summaryrefslogtreecommitdiffstats
path: root/services/input/InputReader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'services/input/InputReader.cpp')
-rw-r--r--services/input/InputReader.cpp171
1 files changed, 108 insertions, 63 deletions
diff --git a/services/input/InputReader.cpp b/services/input/InputReader.cpp
index 42512d8..71eba52 100644
--- a/services/input/InputReader.cpp
+++ b/services/input/InputReader.cpp
@@ -237,7 +237,8 @@ InputReader::InputReader(const sp<EventHubInterface>& eventHub,
const sp<InputReaderPolicyInterface>& policy,
const sp<InputListenerInterface>& listener) :
mContext(this), mEventHub(eventHub), mPolicy(policy),
- mGlobalMetaState(0), mDisableVirtualKeysTimeout(LLONG_MIN), mNextTimeout(LLONG_MAX),
+ mGlobalMetaState(0), mGeneration(1),
+ mDisableVirtualKeysTimeout(LLONG_MIN), mNextTimeout(LLONG_MAX),
mConfigurationChangesToRefresh(0) {
mQueuedListener = new QueuedInputListener(listener);
@@ -257,18 +258,24 @@ InputReader::~InputReader() {
}
void InputReader::loopOnce() {
+ int32_t oldGeneration;
int32_t timeoutMillis;
+ bool inputDevicesChanged = false;
+ Vector<InputDeviceInfo> inputDevices;
{ // acquire lock
AutoMutex _l(mLock);
+ oldGeneration = mGeneration;
+ timeoutMillis = -1;
+
uint32_t changes = mConfigurationChangesToRefresh;
if (changes) {
mConfigurationChangesToRefresh = 0;
+ timeoutMillis = 0;
refreshConfigurationLocked(changes);
}
- timeoutMillis = -1;
- if (mNextTimeout != LLONG_MAX) {
+ if (timeoutMillis < 0 && mNextTimeout != LLONG_MAX) {
nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
timeoutMillis = toMillisecondTimeoutDelay(now, mNextTimeout);
}
@@ -283,7 +290,8 @@ void InputReader::loopOnce() {
if (count) {
processEventsLocked(mEventBuffer, count);
}
- if (!count || timeoutMillis == 0) {
+
+ if (mNextTimeout != LLONG_MAX) {
nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
if (now >= mNextTimeout) {
#if DEBUG_RAW_EVENTS
@@ -293,8 +301,18 @@ void InputReader::loopOnce() {
timeoutExpiredLocked(now);
}
}
+
+ if (oldGeneration != mGeneration) {
+ inputDevicesChanged = true;
+ getInputDevicesLocked(inputDevices);
+ }
} // release lock
+ // Send out a message that the describes the changed input devices.
+ if (inputDevicesChanged) {
+ mPolicy->notifyInputDevicesChanged(inputDevices);
+ }
+
// Flush queued events out to the listener.
// This must happen outside of the lock because the listener could potentially call
// back into the InputReader's methods, such as getScanCodeState, or become blocked
@@ -344,6 +362,12 @@ void InputReader::processEventsLocked(const RawEvent* rawEvents, size_t count) {
}
void InputReader::addDeviceLocked(nsecs_t when, int32_t deviceId) {
+ ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
+ if (deviceIndex >= 0) {
+ ALOGW("Ignoring spurious device added event for deviceId %d.", deviceId);
+ return;
+ }
+
InputDeviceIdentifier identifier = mEventHub->getDeviceIdentifier(deviceId);
uint32_t classes = mEventHub->getDeviceClasses(deviceId);
@@ -359,27 +383,22 @@ void InputReader::addDeviceLocked(nsecs_t when, int32_t deviceId) {
identifier.name.string(), device->getSources());
}
- ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
- if (deviceIndex < 0) {
- mDevices.add(deviceId, device);
- } else {
- ALOGW("Ignoring spurious device added event for deviceId %d.", deviceId);
- delete device;
- return;
- }
+ mDevices.add(deviceId, device);
+ bumpGenerationLocked();
}
void InputReader::removeDeviceLocked(nsecs_t when, int32_t deviceId) {
InputDevice* device = NULL;
ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
- if (deviceIndex >= 0) {
- device = mDevices.valueAt(deviceIndex);
- mDevices.removeItemsAt(deviceIndex, 1);
- } else {
+ if (deviceIndex < 0) {
ALOGW("Ignoring spurious device removed event for deviceId %d.", deviceId);
return;
}
+ device = mDevices.valueAt(deviceIndex);
+ mDevices.removeItemsAt(deviceIndex, 1);
+ bumpGenerationLocked();
+
if (device->isIgnored()) {
ALOGI("Device removed: id=%d, name='%s' (ignored non-input device)",
device->getId(), device->getName().string());
@@ -394,7 +413,8 @@ void InputReader::removeDeviceLocked(nsecs_t when, int32_t deviceId) {
InputDevice* InputReader::createDeviceLocked(int32_t deviceId,
const InputDeviceIdentifier& identifier, uint32_t classes) {
- InputDevice* device = new InputDevice(&mContext, deviceId, identifier, classes);
+ InputDevice* device = new InputDevice(&mContext, deviceId, bumpGenerationLocked(),
+ identifier, classes);
// External devices.
if (classes & INPUT_DEVICE_CLASS_EXTERNAL) {
@@ -577,39 +597,30 @@ void InputReader::requestTimeoutAtTimeLocked(nsecs_t when) {
}
}
+int32_t InputReader::bumpGenerationLocked() {
+ return ++mGeneration;
+}
+
void InputReader::getInputConfiguration(InputConfiguration* outConfiguration) {
AutoMutex _l(mLock);
*outConfiguration = mInputConfiguration;
}
-status_t InputReader::getInputDeviceInfo(int32_t deviceId, InputDeviceInfo* outDeviceInfo) {
+void InputReader::getInputDevices(Vector<InputDeviceInfo>& outInputDevices) {
AutoMutex _l(mLock);
-
- ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
- if (deviceIndex < 0) {
- return NAME_NOT_FOUND;
- }
-
- InputDevice* device = mDevices.valueAt(deviceIndex);
- if (device->isIgnored()) {
- return NAME_NOT_FOUND;
- }
-
- device->getDeviceInfo(outDeviceInfo);
- return OK;
+ getInputDevicesLocked(outInputDevices);
}
-void InputReader::getInputDeviceIds(Vector<int32_t>& outDeviceIds) {
- AutoMutex _l(mLock);
-
- outDeviceIds.clear();
+void InputReader::getInputDevicesLocked(Vector<InputDeviceInfo>& outInputDevices) {
+ outInputDevices.clear();
size_t numDevices = mDevices.size();
for (size_t i = 0; i < numDevices; i++) {
InputDevice* device = mDevices.valueAt(i);
if (!device->isIgnored()) {
- outDeviceIds.add(device->getId());
+ outInputDevices.push();
+ device->getDeviceInfo(&outInputDevices.editTop());
}
}
}
@@ -824,6 +835,11 @@ void InputReader::ContextImpl::requestTimeoutAtTime(nsecs_t when) {
mReader->requestTimeoutAtTimeLocked(when);
}
+int32_t InputReader::ContextImpl::bumpGeneration() {
+ // lock is already held by the input loop
+ return mReader->bumpGenerationLocked();
+}
+
InputReaderPolicyInterface* InputReader::ContextImpl::getPolicy() {
return mReader->mPolicy.get();
}
@@ -854,9 +870,10 @@ bool InputReaderThread::threadLoop() {
// --- InputDevice ---
-InputDevice::InputDevice(InputReaderContext* context, int32_t id,
+InputDevice::InputDevice(InputReaderContext* context, int32_t id, int32_t generation,
const InputDeviceIdentifier& identifier, uint32_t classes) :
- mContext(context), mId(id), mIdentifier(identifier), mClasses(classes),
+ mContext(context), mId(id), mGeneration(generation),
+ mIdentifier(identifier), mClasses(classes),
mSources(0), mIsExternal(false), mDropUntilNextSync(false) {
}
@@ -874,6 +891,7 @@ void InputDevice::dump(String8& dump) {
dump.appendFormat(INDENT "Device %d: %s\n", deviceInfo.getId(),
deviceInfo.getName().string());
+ dump.appendFormat(INDENT2 "Generation: %d\n", mGeneration);
dump.appendFormat(INDENT2 "IsExternal: %s\n", toString(mIsExternal));
dump.appendFormat(INDENT2 "Sources: 0x%08x\n", deviceInfo.getSources());
dump.appendFormat(INDENT2 "KeyboardType: %d\n", deviceInfo.getKeyboardType());
@@ -946,14 +964,12 @@ void InputDevice::process(const RawEvent* rawEvents, size_t count) {
size_t numMappers = mMappers.size();
for (const RawEvent* rawEvent = rawEvents; count--; rawEvent++) {
#if DEBUG_RAW_EVENTS
- ALOGD("Input event: device=%d type=0x%04x scancode=0x%04x "
- "keycode=0x%04x value=0x%08x flags=0x%08x",
- rawEvent->deviceId, rawEvent->type, rawEvent->scanCode, rawEvent->keyCode,
- rawEvent->value, rawEvent->flags);
+ ALOGD("Input event: device=%d type=0x%04x code=0x%04x value=0x%08x",
+ rawEvent->deviceId, rawEvent->type, rawEvent->code, rawEvent->value);
#endif
if (mDropUntilNextSync) {
- if (rawEvent->type == EV_SYN && rawEvent->scanCode == SYN_REPORT) {
+ if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
mDropUntilNextSync = false;
#if DEBUG_RAW_EVENTS
ALOGD("Recovered from input event buffer overrun.");
@@ -963,7 +979,7 @@ void InputDevice::process(const RawEvent* rawEvents, size_t count) {
ALOGD("Dropped input event while waiting for next input sync.");
#endif
}
- } else if (rawEvent->type == EV_SYN && rawEvent->scanCode == SYN_DROPPED) {
+ } else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_DROPPED) {
ALOGI("Detected input event buffer overrun for device %s.", getName().string());
mDropUntilNextSync = true;
reset(rawEvent->when);
@@ -985,7 +1001,7 @@ void InputDevice::timeoutExpired(nsecs_t when) {
}
void InputDevice::getDeviceInfo(InputDeviceInfo* outDeviceInfo) {
- outDeviceInfo->initialize(mId, mIdentifier.name, mIdentifier.descriptor);
+ outDeviceInfo->initialize(mId, mGeneration, mIdentifier.name, mIdentifier.descriptor);
size_t numMappers = mMappers.size();
for (size_t i = 0; i < numMappers; i++) {
@@ -1056,6 +1072,10 @@ void InputDevice::fadePointer() {
}
}
+void InputDevice::bumpGeneration() {
+ mGeneration = mContext->bumpGeneration();
+}
+
void InputDevice::notifyReset(nsecs_t when) {
NotifyDeviceResetArgs args(when, mId);
mContext->getListener()->notifyDeviceReset(&args);
@@ -1092,7 +1112,7 @@ void CursorButtonAccumulator::clearButtons() {
void CursorButtonAccumulator::process(const RawEvent* rawEvent) {
if (rawEvent->type == EV_KEY) {
- switch (rawEvent->scanCode) {
+ switch (rawEvent->code) {
case BTN_LEFT:
mBtnLeft = rawEvent->value;
break;
@@ -1159,7 +1179,7 @@ void CursorMotionAccumulator::clearRelativeAxes() {
void CursorMotionAccumulator::process(const RawEvent* rawEvent) {
if (rawEvent->type == EV_REL) {
- switch (rawEvent->scanCode) {
+ switch (rawEvent->code) {
case REL_X:
mRelX = rawEvent->value;
break;
@@ -1198,7 +1218,7 @@ void CursorScrollAccumulator::clearRelativeAxes() {
void CursorScrollAccumulator::process(const RawEvent* rawEvent) {
if (rawEvent->type == EV_REL) {
- switch (rawEvent->scanCode) {
+ switch (rawEvent->code) {
case REL_WHEEL:
mRelWheel = rawEvent->value;
break;
@@ -1261,7 +1281,7 @@ void TouchButtonAccumulator::clearButtons() {
void TouchButtonAccumulator::process(const RawEvent* rawEvent) {
if (rawEvent->type == EV_KEY) {
- switch (rawEvent->scanCode) {
+ switch (rawEvent->code) {
case BTN_TOUCH:
mBtnTouch = rawEvent->value;
break;
@@ -1467,7 +1487,7 @@ void SingleTouchMotionAccumulator::clearAbsoluteAxes() {
void SingleTouchMotionAccumulator::process(const RawEvent* rawEvent) {
if (rawEvent->type == EV_ABS) {
- switch (rawEvent->scanCode) {
+ switch (rawEvent->code) {
case ABS_X:
mAbsX = rawEvent->value;
break;
@@ -1551,7 +1571,7 @@ void MultiTouchMotionAccumulator::process(const RawEvent* rawEvent) {
if (rawEvent->type == EV_ABS) {
bool newSlot = false;
if (mUsingSlotsProtocol) {
- if (rawEvent->scanCode == ABS_MT_SLOT) {
+ if (rawEvent->code == ABS_MT_SLOT) {
mCurrentSlot = rawEvent->value;
newSlot = true;
}
@@ -1570,7 +1590,7 @@ void MultiTouchMotionAccumulator::process(const RawEvent* rawEvent) {
} else {
Slot* slot = &mSlots[mCurrentSlot];
- switch (rawEvent->scanCode) {
+ switch (rawEvent->code) {
case ABS_MT_POSITION_X:
slot->mInUse = true;
slot->mAbsMTPositionX = rawEvent->value;
@@ -1626,7 +1646,7 @@ void MultiTouchMotionAccumulator::process(const RawEvent* rawEvent) {
break;
}
}
- } else if (rawEvent->type == EV_SYN && rawEvent->scanCode == SYN_MT_REPORT) {
+ } else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_MT_REPORT) {
// MultiTouch Sync: The driver has returned all data for *one* of the pointers.
mCurrentSlot += 1;
}
@@ -1730,6 +1750,10 @@ status_t InputMapper::getAbsoluteAxisInfo(int32_t axis, RawAbsoluteAxisInfo* axi
return getEventHub()->getAbsoluteAxisInfo(getDeviceId(), axis, axisInfo);
}
+void InputMapper::bumpGeneration() {
+ mDevice->bumpGeneration();
+}
+
void InputMapper::dumpRawAbsoluteAxisInfo(String8& dump,
const RawAbsoluteAxisInfo& axis, const char* name) {
if (axis.valid) {
@@ -1757,7 +1781,7 @@ uint32_t SwitchInputMapper::getSources() {
void SwitchInputMapper::process(const RawEvent* rawEvent) {
switch (rawEvent->type) {
case EV_SW:
- processSwitch(rawEvent->when, rawEvent->scanCode, rawEvent->value);
+ processSwitch(rawEvent->when, rawEvent->code, rawEvent->value);
break;
}
}
@@ -1849,6 +1873,7 @@ void KeyboardInputMapper::reset(nsecs_t when) {
mMetaState = AMETA_NONE;
mDownTime = 0;
mKeyDowns.clear();
+ mCurrentHidUsage = 0;
resetLedState();
@@ -1858,13 +1883,32 @@ void KeyboardInputMapper::reset(nsecs_t when) {
void KeyboardInputMapper::process(const RawEvent* rawEvent) {
switch (rawEvent->type) {
case EV_KEY: {
- int32_t scanCode = rawEvent->scanCode;
+ int32_t scanCode = rawEvent->code;
+ int32_t usageCode = mCurrentHidUsage;
+ mCurrentHidUsage = 0;
+
if (isKeyboardOrGamepadKey(scanCode)) {
- processKey(rawEvent->when, rawEvent->value != 0, rawEvent->keyCode, scanCode,
- rawEvent->flags);
+ int32_t keyCode;
+ uint32_t flags;
+ if (getEventHub()->mapKey(getDeviceId(), scanCode, usageCode, &keyCode, &flags)) {
+ keyCode = AKEYCODE_UNKNOWN;
+ flags = 0;
+ }
+ processKey(rawEvent->when, rawEvent->value != 0, keyCode, scanCode, flags);
+ }
+ break;
+ }
+ case EV_MSC: {
+ if (rawEvent->code == MSC_SCAN) {
+ mCurrentHidUsage = rawEvent->value;
}
break;
}
+ case EV_SYN: {
+ if (rawEvent->code == SYN_REPORT) {
+ mCurrentHidUsage = 0;
+ }
+ }
}
}
@@ -2119,6 +2163,7 @@ void CursorInputMapper::configure(nsecs_t when,
} else {
mOrientation = DISPLAY_ORIENTATION_0;
}
+ bumpGeneration();
}
}
@@ -2183,7 +2228,7 @@ void CursorInputMapper::process(const RawEvent* rawEvent) {
mCursorMotionAccumulator.process(rawEvent);
mCursorScrollAccumulator.process(rawEvent);
- if (rawEvent->type == EV_SYN && rawEvent->scanCode == SYN_REPORT) {
+ if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
sync(rawEvent->when);
}
}
@@ -2980,6 +3025,7 @@ void TouchInputMapper::configureSurface(nsecs_t when, bool* outResetNeeded) {
// Inform the dispatcher about the changes.
*outResetNeeded = true;
+ bumpGeneration();
}
}
@@ -3016,8 +3062,7 @@ void TouchInputMapper::configureVirtualKeys() {
virtualKey.scanCode = virtualKeyDefinition.scanCode;
int32_t keyCode;
uint32_t flags;
- if (getEventHub()->mapKey(getDeviceId(), virtualKey.scanCode,
- & keyCode, & flags)) {
+ if (getEventHub()->mapKey(getDeviceId(), virtualKey.scanCode, 0, &keyCode, &flags)) {
ALOGW(INDENT "VirtualKey %d: could not obtain key code, ignoring",
virtualKey.scanCode);
mVirtualKeys.pop(); // drop the key
@@ -3311,7 +3356,7 @@ void TouchInputMapper::process(const RawEvent* rawEvent) {
mCursorScrollAccumulator.process(rawEvent);
mTouchButtonAccumulator.process(rawEvent);
- if (rawEvent->type == EV_SYN && rawEvent->scanCode == SYN_REPORT) {
+ if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
sync(rawEvent->when);
}
}
@@ -5920,7 +5965,7 @@ void JoystickInputMapper::reset(nsecs_t when) {
void JoystickInputMapper::process(const RawEvent* rawEvent) {
switch (rawEvent->type) {
case EV_ABS: {
- ssize_t index = mAxes.indexOfKey(rawEvent->scanCode);
+ ssize_t index = mAxes.indexOfKey(rawEvent->code);
if (index >= 0) {
Axis& axis = mAxes.editValueAt(index);
float newValue, highNewValue;
@@ -5956,7 +6001,7 @@ void JoystickInputMapper::process(const RawEvent* rawEvent) {
}
case EV_SYN:
- switch (rawEvent->scanCode) {
+ switch (rawEvent->code) {
case SYN_REPORT:
sync(rawEvent->when, false /*force*/);
break;