diff options
| -rw-r--r-- | services/input/EventHub.cpp | 31 | ||||
| -rw-r--r-- | services/input/EventHub.h | 4 | ||||
| -rw-r--r-- | services/input/InputDispatcher.cpp | 5 | ||||
| -rw-r--r-- | services/input/InputReader.cpp | 21 | ||||
| -rw-r--r-- | services/input/tests/InputReader_test.cpp | 20 |
5 files changed, 76 insertions, 5 deletions
diff --git a/services/input/EventHub.cpp b/services/input/EventHub.cpp index 95b8a5723e2f..ca2540bfad20 100644 --- a/services/input/EventHub.cpp +++ b/services/input/EventHub.cpp @@ -212,8 +212,8 @@ status_t EventHub::getAbsoluteAxisInfo(int32_t deviceId, int axis, 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->identifier.name.string(), device->fd); + LOGW("Error reading absolute controller %d for device %s fd %d, errno=%d", + axis, device->identifier.name.string(), device->fd, errno); return -errno; } @@ -335,6 +335,33 @@ int32_t EventHub::getSwitchStateLocked(Device* device, int32_t sw) const { return AKEY_STATE_UNKNOWN; } +status_t EventHub::getAbsoluteAxisValue(int32_t deviceId, int32_t axis, int32_t* outValue) const { + if (axis >= 0 && axis <= ABS_MAX) { + AutoMutex _l(mLock); + + Device* device = getDeviceLocked(deviceId); + if (device != NULL) { + return getAbsoluteAxisValueLocked(device, axis, outValue); + } + } + *outValue = 0; + return -1; +} + +status_t EventHub::getAbsoluteAxisValueLocked(Device* device, int32_t axis, + int32_t* outValue) const { + struct input_absinfo info; + + if(ioctl(device->fd, EVIOCGABS(axis), &info)) { + LOGW("Error reading absolute controller %d for device %s fd %d, errno=%d", + axis, device->identifier.name.string(), device->fd, errno); + return -errno; + } + + *outValue = info.value; + return OK; +} + bool EventHub::markSupportedKeyCodes(int32_t deviceId, size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) const { AutoMutex _l(mLock); diff --git a/services/input/EventHub.h b/services/input/EventHub.h index 0a34e45a565c..695dfdfb25e6 100644 --- a/services/input/EventHub.h +++ b/services/input/EventHub.h @@ -186,6 +186,8 @@ public: virtual int32_t getScanCodeState(int32_t deviceId, int32_t scanCode) const = 0; virtual int32_t getKeyCodeState(int32_t deviceId, int32_t keyCode) const = 0; virtual int32_t getSwitchState(int32_t deviceId, int32_t sw) const = 0; + virtual status_t getAbsoluteAxisValue(int32_t deviceId, int32_t axis, + int32_t* outValue) const = 0; /* * Examine key input devices for specific framework keycode support @@ -237,6 +239,7 @@ public: virtual int32_t getScanCodeState(int32_t deviceId, int32_t scanCode) const; virtual int32_t getKeyCodeState(int32_t deviceId, int32_t keyCode) const; virtual int32_t getSwitchState(int32_t deviceId, int32_t sw) const; + virtual status_t getAbsoluteAxisValue(int32_t deviceId, int32_t axis, int32_t* outValue) const; virtual bool markSupportedKeyCodes(int32_t deviceId, size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) const; @@ -305,6 +308,7 @@ private: int32_t getScanCodeStateLocked(Device* device, int32_t scanCode) const; int32_t getKeyCodeStateLocked(Device* device, int32_t keyCode) const; int32_t getSwitchStateLocked(Device* device, int32_t sw) const; + int32_t getAbsoluteAxisValueLocked(Device* device, int32_t axis, int32_t* outValue) const; bool markSupportedKeyCodesLocked(Device* device, size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) const; diff --git a/services/input/InputDispatcher.cpp b/services/input/InputDispatcher.cpp index 85ce38ae2020..10b9083549f2 100644 --- a/services/input/InputDispatcher.cpp +++ b/services/input/InputDispatcher.cpp @@ -1239,8 +1239,9 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, const InputWindow* newHoverWindow = NULL; bool isSplit = mTouchState.split; - bool switchedDevice = mTouchState.deviceId != entry->deviceId - || mTouchState.source != entry->source; + bool switchedDevice = mTouchState.deviceId >= 0 + && (mTouchState.deviceId != entry->deviceId + || mTouchState.source != entry->source); bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE || maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER || maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT); diff --git a/services/input/InputReader.cpp b/services/input/InputReader.cpp index 82c3af370ea8..79218a5581ca 100644 --- a/services/input/InputReader.cpp +++ b/services/input/InputReader.cpp @@ -5394,7 +5394,6 @@ void SingleTouchInputMapper::configureRawAxes() { MultiTouchInputMapper::MultiTouchInputMapper(InputDevice* device) : TouchInputMapper(device), mSlotCount(0), mUsingSlotsProtocol(false) { - clearState(); } MultiTouchInputMapper::~MultiTouchInputMapper() { @@ -5404,6 +5403,24 @@ void MultiTouchInputMapper::clearState() { mAccumulator.clearSlots(mSlotCount); mAccumulator.clearButtons(); mButtonState = 0; + + if (mUsingSlotsProtocol) { + // Query the driver for the current slot index and use it as the initial slot + // before we start reading events from the device. It is possible that the + // current slot index will not be the same as it was when the first event was + // written into the evdev buffer, which means the input mapper could start + // out of sync with the initial state of the events in the evdev buffer. + // In the extremely unlikely case that this happens, the data from + // two slots will be confused until the next ABS_MT_SLOT event is received. + // This can cause the touch point to "jump", but at least there will be + // no stuck touches. + status_t status = getEventHub()->getAbsoluteAxisValue(getDeviceId(), ABS_MT_SLOT, + &mAccumulator.currentSlot); + if (status) { + LOGW("Could not retrieve current multitouch slot index. status=%d", status); + mAccumulator.currentSlot = -1; + } + } } void MultiTouchInputMapper::reset() { @@ -5682,6 +5699,8 @@ void MultiTouchInputMapper::configureRawAxes() { } mAccumulator.allocateSlots(mSlotCount); + + clearState(); } diff --git a/services/input/tests/InputReader_test.cpp b/services/input/tests/InputReader_test.cpp index e349248b1c5a..d3c5ece7cbef 100644 --- a/services/input/tests/InputReader_test.cpp +++ b/services/input/tests/InputReader_test.cpp @@ -429,6 +429,7 @@ class FakeEventHub : public EventHubInterface { KeyedVector<int32_t, int32_t> keyCodeStates; KeyedVector<int32_t, int32_t> scanCodeStates; KeyedVector<int32_t, int32_t> switchStates; + KeyedVector<int32_t, int32_t> absoluteAxisValue; KeyedVector<int32_t, KeyInfo> keys; KeyedVector<int32_t, bool> leds; Vector<VirtualKeyDefinition> virtualKeys; @@ -514,6 +515,11 @@ public: device->switchStates.replaceValueFor(switchCode, state); } + void setAbsoluteAxisValue(int32_t deviceId, int32_t axis, int32_t value) { + Device* device = getDevice(deviceId); + device->absoluteAxisValue.replaceValueFor(axis, value); + } + void addKey(int32_t deviceId, int32_t scanCode, int32_t keyCode, uint32_t flags) { Device* device = getDevice(deviceId); KeyInfo info; @@ -677,6 +683,20 @@ private: return AKEY_STATE_UNKNOWN; } + virtual status_t getAbsoluteAxisValue(int32_t deviceId, int32_t axis, + int32_t* outValue) const { + Device* device = getDevice(deviceId); + if (device) { + ssize_t index = device->absoluteAxisValue.indexOfKey(axis); + if (index >= 0) { + *outValue = device->absoluteAxisValue.valueAt(index); + return OK; + } + } + *outValue = 0; + return -1; + } + virtual bool markSupportedKeyCodes(int32_t deviceId, size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) const { bool result = false; |