diff options
author | 2010-10-20 15:33:38 -0700 | |
---|---|---|
committer | 2010-10-23 03:52:57 -0700 | |
commit | c3db858de9fa152480b9cf53c8c0cb793a280722 (patch) | |
tree | ba337dd2df79d211a940727c5c93c112cf0de77d /libs/ui/InputReader.cpp | |
parent | b6a2256e5461160a89d077b761d3253d95ce869f (diff) |
Add unit tests for native input and fix bugs identified.
Fixed a bug where we would lose the first touch point when swiping out of
the virtual key area.
Fixed a bug where we would not send an ACTION_MOVE event in cases where
individual pointers went down/up and the remaining pointers actually moved.
This is important since many applications do not handle pointer movements
during ACTION_POINTER_DOWN or ACTION_POINTER_UP. In the case of
ACTION_POINTER_UP the movement was completely lost since all pointers were
dispatched using their old location rather than the new location.
Improved motion event validation to check for duplicate pointer ids.
Added an input source constant that was missing from the NDK api but
defined in the framework api.
Added a timestamp when reporting added/removed devices in EventHub.
Bug: 3070082
Change-Id: I3206a030f43b7616e2f48006e5a9d522c4d92e56
Diffstat (limited to 'libs/ui/InputReader.cpp')
-rw-r--r-- | libs/ui/InputReader.cpp | 71 |
1 files changed, 55 insertions, 16 deletions
diff --git a/libs/ui/InputReader.cpp b/libs/ui/InputReader.cpp index ce0d88023845..d1674390efd6 100644 --- a/libs/ui/InputReader.cpp +++ b/libs/ui/InputReader.cpp @@ -234,7 +234,7 @@ void InputReader::process(const RawEvent* rawEvent) { break; case EventHubInterface::FINISHED_DEVICE_SCAN: - handleConfigurationChanged(); + handleConfigurationChanged(rawEvent->when); break; default: @@ -372,7 +372,7 @@ void InputReader::consumeEvent(const RawEvent* rawEvent) { } // release device registry reader lock } -void InputReader::handleConfigurationChanged() { +void InputReader::handleConfigurationChanged(nsecs_t when) { // Reset global meta state because it depends on the list of all configured devices. updateGlobalMetaState(); @@ -380,7 +380,6 @@ void InputReader::handleConfigurationChanged() { updateInputConfiguration(); // Enqueue configuration changed. - nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC); mDispatcher->notifyConfigurationChanged(when); } @@ -2094,7 +2093,7 @@ TouchInputMapper::TouchResult TouchInputMapper::consumeOffScreenTouches( mLocked.currentVirtualKey.down = false; #if DEBUG_VIRTUAL_KEYS LOGD("VirtualKeys: Generating key up: keyCode=%d, scanCode=%d", - mCurrentVirtualKey.keyCode, mCurrentVirtualKey.scanCode); + mLocked.currentVirtualKey.keyCode, mLocked.currentVirtualKey.scanCode); #endif keyEventAction = AKEY_EVENT_ACTION_UP; keyEventFlags = AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY; @@ -2119,13 +2118,22 @@ TouchInputMapper::TouchResult TouchInputMapper::consumeOffScreenTouches( mLocked.currentVirtualKey.down = false; #if DEBUG_VIRTUAL_KEYS LOGD("VirtualKeys: Canceling key: keyCode=%d, scanCode=%d", - mCurrentVirtualKey.keyCode, mCurrentVirtualKey.scanCode); + mLocked.currentVirtualKey.keyCode, mLocked.currentVirtualKey.scanCode); #endif keyEventAction = AKEY_EVENT_ACTION_UP; keyEventFlags = AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY | AKEY_EVENT_FLAG_CANCELED; - touchResult = DROP_STROKE; - goto DispatchVirtualKey; + + // Check whether the pointer moved inside the display area where we should + // start a new stroke. + int32_t x = mCurrentTouch.pointers[0].x; + int32_t y = mCurrentTouch.pointers[0].y; + if (isPointInsideSurfaceLocked(x, y)) { + mLastTouch.clear(); + touchResult = DISPATCH_TOUCH; + } else { + touchResult = DROP_STROKE; + } } else { if (mCurrentTouch.pointerCount >= 1 && mLastTouch.pointerCount == 0) { // Pointer just went down. Handle off-screen touches, if needed. @@ -2143,7 +2151,8 @@ TouchInputMapper::TouchResult TouchInputMapper::consumeOffScreenTouches( mLocked.currentVirtualKey.scanCode = virtualKey->scanCode; #if DEBUG_VIRTUAL_KEYS LOGD("VirtualKeys: Generating key down: keyCode=%d, scanCode=%d", - mCurrentVirtualKey.keyCode, mCurrentVirtualKey.scanCode); + mLocked.currentVirtualKey.keyCode, + mLocked.currentVirtualKey.scanCode); #endif keyEventAction = AKEY_EVENT_ACTION_DOWN; keyEventFlags = AKEY_EVENT_FLAG_FROM_SYSTEM @@ -2190,14 +2199,35 @@ void TouchInputMapper::dispatchTouches(nsecs_t when, uint32_t policyFlags) { dispatchTouch(when, policyFlags, & mCurrentTouch, currentIdBits, -1, currentPointerCount, motionEventAction); } else { - // There may be pointers going up and pointers going down at the same time when pointer - // ids are reported by the device driver. + // There may be pointers going up and pointers going down and pointers moving + // all at the same time. BitSet32 upIdBits(lastIdBits.value & ~ currentIdBits.value); BitSet32 downIdBits(currentIdBits.value & ~ lastIdBits.value); BitSet32 activeIdBits(lastIdBits.value); uint32_t pointerCount = lastPointerCount; - while (! upIdBits.isEmpty()) { + // Produce an intermediate representation of the touch data that consists of the + // old location of pointers that have just gone up and the new location of pointers that + // have just moved but omits the location of pointers that have just gone down. + TouchData interimTouch; + interimTouch.copyFrom(mLastTouch); + + BitSet32 moveIdBits(lastIdBits.value & currentIdBits.value); + bool moveNeeded = false; + while (!moveIdBits.isEmpty()) { + uint32_t moveId = moveIdBits.firstMarkedBit(); + moveIdBits.clearBit(moveId); + + int32_t oldIndex = mLastTouch.idToIndex[moveId]; + int32_t newIndex = mCurrentTouch.idToIndex[moveId]; + if (mLastTouch.pointers[oldIndex] != mCurrentTouch.pointers[newIndex]) { + interimTouch.pointers[oldIndex] = mCurrentTouch.pointers[newIndex]; + moveNeeded = true; + } + } + + // Dispatch pointer up events using the interim pointer locations. + while (!upIdBits.isEmpty()) { uint32_t upId = upIdBits.firstMarkedBit(); upIdBits.clearBit(upId); BitSet32 oldActiveIdBits = activeIdBits; @@ -2210,12 +2240,21 @@ void TouchInputMapper::dispatchTouches(nsecs_t when, uint32_t policyFlags) { motionEventAction = AMOTION_EVENT_ACTION_POINTER_UP; } - dispatchTouch(when, policyFlags, & mLastTouch, + dispatchTouch(when, policyFlags, &interimTouch, oldActiveIdBits, upId, pointerCount, motionEventAction); pointerCount -= 1; } - while (! downIdBits.isEmpty()) { + // Dispatch move events if any of the remaining pointers moved from their old locations. + // Although applications receive new locations as part of individual pointer up + // events, they do not generally handle them except when presented in a move event. + if (moveNeeded) { + dispatchTouch(when, policyFlags, &mCurrentTouch, + activeIdBits, -1, pointerCount, AMOTION_EVENT_ACTION_MOVE); + } + + // Dispatch pointer down events using the new pointer locations. + while (!downIdBits.isEmpty()) { uint32_t downId = downIdBits.firstMarkedBit(); downIdBits.clearBit(downId); BitSet32 oldActiveIdBits = activeIdBits; @@ -2230,7 +2269,7 @@ void TouchInputMapper::dispatchTouches(nsecs_t when, uint32_t policyFlags) { } pointerCount += 1; - dispatchTouch(when, policyFlags, & mCurrentTouch, + dispatchTouch(when, policyFlags, &mCurrentTouch, activeIdBits, downId, pointerCount, motionEventAction); } } @@ -3339,8 +3378,8 @@ void MultiTouchInputMapper::sync(nsecs_t when) { if (fields & Accumulator::FIELD_ABS_MT_PRESSURE) { if (inPointer.absMTPressure <= 0) { - // Some devices send sync packets with X / Y but with a 0 presure to indicate - // a pointer up. Drop this finger. + // Some devices send sync packets with X / Y but with a 0 pressure to indicate + // a pointer going up. Drop this finger. continue; } outPointer.pressure = inPointer.absMTPressure; |