summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/input/EventHub.cpp31
-rw-r--r--services/input/EventHub.h4
-rw-r--r--services/input/InputDispatcher.cpp5
-rw-r--r--services/input/InputReader.cpp21
-rw-r--r--services/input/tests/InputReader_test.cpp20
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;