diff options
| author | 2022-11-01 19:57:52 +0000 | |
|---|---|---|
| committer | 2022-11-01 19:57:52 +0000 | |
| commit | aee7eb92c4bdf36000eea10165c377b3a9b03c0e (patch) | |
| tree | e62a8b23d33b9cce5dc2f8da56a3a5f3fbcd0282 | |
| parent | d500ef2e8a803528652fd1c002944cc001f52783 (diff) | |
| parent | d6ccedb2282b6653f60de94d8924ecd6f2cd72e7 (diff) | |
Merge changes I0b34480e,I9889e7f8,I5e008d03
* changes:
TouchInputMapper: Rely on default c'tor and copy c'tors for structs
Use the last cooked touch state for generating button release events
Use std::array and default copy assignment for PointerCoords
| -rw-r--r-- | include/input/Input.h | 5 | ||||
| -rw-r--r-- | libs/input/Input.cpp | 8 | ||||
| -rw-r--r-- | services/inputflinger/InputCommonConverter.cpp | 4 | ||||
| -rw-r--r-- | services/inputflinger/reader/include/EventHub.h | 25 | ||||
| -rw-r--r-- | services/inputflinger/reader/mapper/TouchInputMapper.cpp | 160 | ||||
| -rw-r--r-- | services/inputflinger/reader/mapper/TouchInputMapper.h | 181 | ||||
| -rw-r--r-- | services/inputflinger/tests/InputReader_test.cpp | 38 |
7 files changed, 166 insertions, 255 deletions
diff --git a/include/input/Input.h b/include/input/Input.h index 172e5b46d8..dd74a51e5e 100644 --- a/include/input/Input.h +++ b/include/input/Input.h @@ -366,7 +366,7 @@ struct PointerCoords { // Values of axes that are stored in this structure packed in order by axis id // for each axis that is present in the structure according to 'bits'. - float values[MAX_AXES]; + std::array<float, MAX_AXES> values; inline void clear() { BitSet64::clear(bits); @@ -406,7 +406,8 @@ struct PointerCoords { return !(*this == other); } - void copyFrom(const PointerCoords& other); + inline void copyFrom(const PointerCoords& other) { *this = other; } + PointerCoords& operator=(const PointerCoords&) = default; private: void tooManyAxes(int axis); diff --git a/libs/input/Input.cpp b/libs/input/Input.cpp index c1eb8e2a12..cf5a7e7b05 100644 --- a/libs/input/Input.cpp +++ b/libs/input/Input.cpp @@ -438,14 +438,6 @@ bool PointerCoords::operator==(const PointerCoords& other) const { return true; } -void PointerCoords::copyFrom(const PointerCoords& other) { - bits = other.bits; - uint32_t count = BitSet64::count(bits); - for (uint32_t i = 0; i < count; i++) { - values[i] = other.values[i]; - } -} - void PointerCoords::transform(const ui::Transform& transform) { const vec2 xy = transform.transform(getXYValue()); setAxisValue(AMOTION_EVENT_AXIS_X, xy.x); diff --git a/services/inputflinger/InputCommonConverter.cpp b/services/inputflinger/InputCommonConverter.cpp index 6db89d4759..628ce6fc9a 100644 --- a/services/inputflinger/InputCommonConverter.cpp +++ b/services/inputflinger/InputCommonConverter.cpp @@ -304,8 +304,8 @@ static void getHalPropertiesAndCoords(const NotifyMotionArgs& args, common::PointerCoords coords; // OK to copy bits because we have static_assert for pointerCoords axes coords.bits = args.pointerCoords[i].bits; - coords.values = std::vector<float>(args.pointerCoords[i].values, - args.pointerCoords[i].values + + coords.values = std::vector<float>(args.pointerCoords[i].values.cbegin(), + args.pointerCoords[i].values.cbegin() + BitSet64::count(args.pointerCoords[i].bits)); outPointerCoords.push_back(coords); } diff --git a/services/inputflinger/reader/include/EventHub.h b/services/inputflinger/reader/include/EventHub.h index 6933ec7399..8e5f15f338 100644 --- a/services/inputflinger/reader/include/EventHub.h +++ b/services/inputflinger/reader/include/EventHub.h @@ -67,22 +67,15 @@ struct RawEvent { /* Describes an absolute axis. */ struct RawAbsoluteAxisInfo { - bool valid; // true if the information is valid, false otherwise - - int32_t minValue; // minimum value - int32_t maxValue; // maximum value - int32_t flat; // center flat position, eg. flat == 8 means center is between -8 and 8 - int32_t fuzz; // error tolerance, eg. fuzz == 4 means value is +/- 4 due to noise - int32_t resolution; // resolution in units per mm or radians per mm - - inline void clear() { - valid = false; - minValue = 0; - maxValue = 0; - flat = 0; - fuzz = 0; - resolution = 0; - } + bool valid{false}; // true if the information is valid, false otherwise + + int32_t minValue{}; // minimum value + int32_t maxValue{}; // maximum value + int32_t flat{}; // center flat position, eg. flat == 8 means center is between -8 and 8 + int32_t fuzz{}; // error tolerance, eg. fuzz == 4 means value is +/- 4 due to noise + int32_t resolution{}; // resolution in units per mm or radians per mm + + inline void clear() { *this = RawAbsoluteAxisInfo(); } }; /* diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.cpp b/services/inputflinger/reader/mapper/TouchInputMapper.cpp index d17cdf5559..ba3d9802a1 100644 --- a/services/inputflinger/reader/mapper/TouchInputMapper.cpp +++ b/services/inputflinger/reader/mapper/TouchInputMapper.cpp @@ -73,53 +73,8 @@ inline static int32_t signExtendNybble(int32_t value) { return value >= 8 ? value - 16 : value; } -// --- RawPointerAxes --- - -RawPointerAxes::RawPointerAxes() { - clear(); -} - -void RawPointerAxes::clear() { - x.clear(); - y.clear(); - pressure.clear(); - touchMajor.clear(); - touchMinor.clear(); - toolMajor.clear(); - toolMinor.clear(); - orientation.clear(); - distance.clear(); - tiltX.clear(); - tiltY.clear(); - trackingId.clear(); - slot.clear(); -} - // --- RawPointerData --- -RawPointerData::RawPointerData() { - clear(); -} - -void RawPointerData::clear() { - pointerCount = 0; - clearIdBits(); -} - -void RawPointerData::copyFrom(const RawPointerData& other) { - pointerCount = other.pointerCount; - hoveringIdBits = other.hoveringIdBits; - touchingIdBits = other.touchingIdBits; - canceledIdBits = other.canceledIdBits; - - for (uint32_t i = 0; i < pointerCount; i++) { - pointers[i] = other.pointers[i]; - - int id = pointers[i].id; - idToIndex[id] = other.idToIndex[id]; - } -} - void RawPointerData::getCentroidOfTouchingPointers(float* outX, float* outY) const { float x = 0, y = 0; uint32_t count = touchingIdBits.count(); @@ -137,35 +92,6 @@ void RawPointerData::getCentroidOfTouchingPointers(float* outX, float* outY) con *outY = y; } -// --- CookedPointerData --- - -CookedPointerData::CookedPointerData() { - clear(); -} - -void CookedPointerData::clear() { - pointerCount = 0; - hoveringIdBits.clear(); - touchingIdBits.clear(); - canceledIdBits.clear(); - validIdBits.clear(); -} - -void CookedPointerData::copyFrom(const CookedPointerData& other) { - pointerCount = other.pointerCount; - hoveringIdBits = other.hoveringIdBits; - touchingIdBits = other.touchingIdBits; - validIdBits = other.validIdBits; - - for (uint32_t i = 0; i < pointerCount; i++) { - pointerProperties[i].copyFrom(other.pointerProperties[i]); - pointerCoords[i].copyFrom(other.pointerCoords[i]); - - int id = pointerProperties[i].id; - idToIndex[id] = other.idToIndex[id]; - } -} - // --- TouchInputMapper --- TouchInputMapper::TouchInputMapper(InputDeviceContext& deviceContext) @@ -1583,7 +1509,7 @@ std::list<NotifyArgs> TouchInputMapper::processRawTouches(bool timeout) { // All ready to go. clearStylusDataPendingFlags(); - mCurrentRawState.copyFrom(next); + mCurrentRawState = next; if (mCurrentRawState.when < mLastRawState.when) { mCurrentRawState.when = mLastRawState.when; mCurrentRawState.readTime = mLastRawState.readTime; @@ -1598,7 +1524,7 @@ std::list<NotifyArgs> TouchInputMapper::processRawTouches(bool timeout) { if (timeout) { nsecs_t when = mExternalStylusFusionTimeout - STYLUS_DATA_LATENCY; clearStylusDataPendingFlags(); - mCurrentRawState.copyFrom(mLastRawState); + mCurrentRawState = mLastRawState; ALOGD_IF(DEBUG_STYLUS_FUSION, "Timeout expired, synthesizing event with new stylus data"); const nsecs_t readTime = when; // consider this synthetic event to be zero latency @@ -1723,8 +1649,8 @@ std::list<NotifyArgs> TouchInputMapper::cookAndDispatch(nsecs_t when, nsecs_t re mCurrentRawState.rawHScroll = 0; // Copy current touch to last touch in preparation for the next cycle. - mLastRawState.copyFrom(mCurrentRawState); - mLastCookedState.copyFrom(mCurrentCookedState); + mLastRawState = mCurrentRawState; + mLastCookedState = mCurrentCookedState; return out; } @@ -1744,8 +1670,8 @@ void TouchInputMapper::updateTouchSpots() { mPointerController->fade(PointerControllerInterface::Transition::GRADUAL); mPointerController->setButtonState(mCurrentRawState.buttonState); - mPointerController->setSpots(mCurrentCookedState.cookedPointerData.pointerCoords, - mCurrentCookedState.cookedPointerData.idToIndex, + mPointerController->setSpots(mCurrentCookedState.cookedPointerData.pointerCoords.cbegin(), + mCurrentCookedState.cookedPointerData.idToIndex.cbegin(), mCurrentCookedState.cookedPointerData.touchingIdBits, mViewport.displayId); } @@ -1993,6 +1919,36 @@ std::list<NotifyArgs> TouchInputMapper::abortTouches(nsecs_t when, nsecs_t readT return out; } +// Updates pointer coords and properties for pointers with specified ids that have moved. +// Returns true if any of them changed. +static bool updateMovedPointers(const PropertiesArray& inProperties, CoordsArray& inCoords, + const IdToIndexArray& inIdToIndex, PropertiesArray& outProperties, + CoordsArray& outCoords, IdToIndexArray& outIdToIndex, + BitSet32 idBits) { + bool changed = false; + while (!idBits.isEmpty()) { + uint32_t id = idBits.clearFirstMarkedBit(); + uint32_t inIndex = inIdToIndex[id]; + uint32_t outIndex = outIdToIndex[id]; + + const PointerProperties& curInProperties = inProperties[inIndex]; + const PointerCoords& curInCoords = inCoords[inIndex]; + PointerProperties& curOutProperties = outProperties[outIndex]; + PointerCoords& curOutCoords = outCoords[outIndex]; + + if (curInProperties != curOutProperties) { + curOutProperties.copyFrom(curInProperties); + changed = true; + } + + if (curInCoords != curOutCoords) { + curOutCoords.copyFrom(curInCoords); + changed = true; + } + } + return changed; +} + std::list<NotifyArgs> TouchInputMapper::dispatchTouches(nsecs_t when, nsecs_t readTime, uint32_t policyFlags) { std::list<NotifyArgs> out; @@ -2160,9 +2116,9 @@ std::list<NotifyArgs> TouchInputMapper::dispatchButtonRelease(nsecs_t when, nsec out.push_back(dispatchMotion(when, readTime, policyFlags, mSource, AMOTION_EVENT_ACTION_BUTTON_RELEASE, actionButton, 0, metaState, buttonState, 0, - mCurrentCookedState.cookedPointerData.pointerProperties, - mCurrentCookedState.cookedPointerData.pointerCoords, - mCurrentCookedState.cookedPointerData.idToIndex, idBits, -1, + mLastCookedState.cookedPointerData.pointerProperties, + mLastCookedState.cookedPointerData.pointerCoords, + mLastCookedState.cookedPointerData.idToIndex, idBits, -1, mOrientedXPrecision, mOrientedYPrecision, mDownTime, MotionClassification::NONE)); } @@ -2539,8 +2495,8 @@ std::list<NotifyArgs> TouchInputMapper::dispatchPointerGestures(nsecs_t when, ns } if (mPointerGesture.currentGestureMode == PointerGesture::Mode::FREEFORM) { - mPointerController->setSpots(mPointerGesture.currentGestureCoords, - mPointerGesture.currentGestureIdToIndex, + mPointerController->setSpots(mPointerGesture.currentGestureCoords.cbegin(), + mPointerGesture.currentGestureIdToIndex.cbegin(), mPointerGesture.currentGestureIdBits, mPointerController->getDisplayId()); } @@ -3743,8 +3699,8 @@ std::list<NotifyArgs> TouchInputMapper::abortPointerSimple(nsecs_t when, nsecs_t NotifyMotionArgs TouchInputMapper::dispatchMotion( nsecs_t when, nsecs_t readTime, uint32_t policyFlags, uint32_t source, int32_t action, int32_t actionButton, int32_t flags, int32_t metaState, int32_t buttonState, - int32_t edgeFlags, const PointerProperties* properties, const PointerCoords* coords, - const uint32_t* idToIndex, BitSet32 idBits, int32_t changedId, float xPrecision, + int32_t edgeFlags, const PropertiesArray& properties, const CoordsArray& coords, + const IdToIndexArray& idToIndex, BitSet32 idBits, int32_t changedId, float xPrecision, float yPrecision, nsecs_t downTime, MotionClassification classification) { PointerCoords pointerCoords[MAX_POINTERS]; PointerProperties pointerProperties[MAX_POINTERS]; @@ -3798,36 +3754,6 @@ NotifyMotionArgs TouchInputMapper::dispatchMotion( downTime, std::move(frames)); } -bool TouchInputMapper::updateMovedPointers(const PointerProperties* inProperties, - const PointerCoords* inCoords, - const uint32_t* inIdToIndex, - PointerProperties* outProperties, - PointerCoords* outCoords, const uint32_t* outIdToIndex, - BitSet32 idBits) const { - bool changed = false; - while (!idBits.isEmpty()) { - uint32_t id = idBits.clearFirstMarkedBit(); - uint32_t inIndex = inIdToIndex[id]; - uint32_t outIndex = outIdToIndex[id]; - - const PointerProperties& curInProperties = inProperties[inIndex]; - const PointerCoords& curInCoords = inCoords[inIndex]; - PointerProperties& curOutProperties = outProperties[outIndex]; - PointerCoords& curOutCoords = outCoords[outIndex]; - - if (curInProperties != curOutProperties) { - curOutProperties.copyFrom(curInProperties); - changed = true; - } - - if (curInCoords != curOutCoords) { - curOutCoords.copyFrom(curInCoords); - changed = true; - } - } - return changed; -} - std::list<NotifyArgs> TouchInputMapper::cancelTouch(nsecs_t when, nsecs_t readTime) { std::list<NotifyArgs> out; out += abortPointerUsage(when, readTime, 0 /*policyFlags*/); diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.h b/services/inputflinger/reader/mapper/TouchInputMapper.h index 7680090188..2bb9ecebe4 100644 --- a/services/inputflinger/reader/mapper/TouchInputMapper.h +++ b/services/inputflinger/reader/mapper/TouchInputMapper.h @@ -29,53 +29,56 @@ namespace android { /* Raw axis information from the driver. */ struct RawPointerAxes { - RawAbsoluteAxisInfo x; - RawAbsoluteAxisInfo y; - RawAbsoluteAxisInfo pressure; - RawAbsoluteAxisInfo touchMajor; - RawAbsoluteAxisInfo touchMinor; - RawAbsoluteAxisInfo toolMajor; - RawAbsoluteAxisInfo toolMinor; - RawAbsoluteAxisInfo orientation; - RawAbsoluteAxisInfo distance; - RawAbsoluteAxisInfo tiltX; - RawAbsoluteAxisInfo tiltY; - RawAbsoluteAxisInfo trackingId; - RawAbsoluteAxisInfo slot; - - RawPointerAxes(); + RawAbsoluteAxisInfo x{}; + RawAbsoluteAxisInfo y{}; + RawAbsoluteAxisInfo pressure{}; + RawAbsoluteAxisInfo touchMajor{}; + RawAbsoluteAxisInfo touchMinor{}; + RawAbsoluteAxisInfo toolMajor{}; + RawAbsoluteAxisInfo toolMinor{}; + RawAbsoluteAxisInfo orientation{}; + RawAbsoluteAxisInfo distance{}; + RawAbsoluteAxisInfo tiltX{}; + RawAbsoluteAxisInfo tiltY{}; + RawAbsoluteAxisInfo trackingId{}; + RawAbsoluteAxisInfo slot{}; + inline int32_t getRawWidth() const { return x.maxValue - x.minValue + 1; } inline int32_t getRawHeight() const { return y.maxValue - y.minValue + 1; } - void clear(); + inline void clear() { *this = RawPointerAxes(); } }; +using PropertiesArray = std::array<PointerProperties, MAX_POINTERS>; +using CoordsArray = std::array<PointerCoords, MAX_POINTERS>; +using IdToIndexArray = std::array<uint32_t, MAX_POINTER_ID + 1>; + /* Raw data for a collection of pointers including a pointer id mapping table. */ struct RawPointerData { struct Pointer { - uint32_t id; - int32_t x; - int32_t y; - int32_t pressure; - int32_t touchMajor; - int32_t touchMinor; - int32_t toolMajor; - int32_t toolMinor; - int32_t orientation; - int32_t distance; - int32_t tiltX; - int32_t tiltY; - int32_t toolType; // a fully decoded AMOTION_EVENT_TOOL_TYPE constant - bool isHovering; + uint32_t id{0xFFFFFFFF}; + int32_t x{}; + int32_t y{}; + int32_t pressure{}; + int32_t touchMajor{}; + int32_t touchMinor{}; + int32_t toolMajor{}; + int32_t toolMinor{}; + int32_t orientation{}; + int32_t distance{}; + int32_t tiltX{}; + int32_t tiltY{}; + // A fully decoded AMOTION_EVENT_TOOL_TYPE constant. + int32_t toolType{AMOTION_EVENT_TOOL_TYPE_UNKNOWN}; + bool isHovering{false}; }; - uint32_t pointerCount; - Pointer pointers[MAX_POINTERS]; - BitSet32 hoveringIdBits, touchingIdBits, canceledIdBits; - uint32_t idToIndex[MAX_POINTER_ID + 1]; + uint32_t pointerCount{}; + std::array<Pointer, MAX_POINTERS> pointers{}; + BitSet32 hoveringIdBits{}, touchingIdBits{}, canceledIdBits{}; + IdToIndexArray idToIndex{}; + + inline void clear() { *this = RawPointerData(); } - RawPointerData(); - void clear(); - void copyFrom(const RawPointerData& other); void getCentroidOfTouchingPointers(float* outX, float* outY) const; inline void markIdBit(uint32_t id, bool isHovering) { @@ -99,15 +102,13 @@ struct RawPointerData { /* Cooked data for a collection of pointers including a pointer id mapping table. */ struct CookedPointerData { - uint32_t pointerCount; - PointerProperties pointerProperties[MAX_POINTERS]; - PointerCoords pointerCoords[MAX_POINTERS]; - BitSet32 hoveringIdBits, touchingIdBits, canceledIdBits, validIdBits; - uint32_t idToIndex[MAX_POINTER_ID + 1]; + uint32_t pointerCount{}; + PropertiesArray pointerProperties{}; + CoordsArray pointerCoords{}; + BitSet32 hoveringIdBits{}, touchingIdBits{}, canceledIdBits{}, validIdBits{}; + IdToIndexArray idToIndex{}; - CookedPointerData(); - void clear(); - void copyFrom(const CookedPointerData& other); + inline void clear() { *this = CookedPointerData(); } inline const PointerCoords& pointerCoordsForId(uint32_t id) const { return pointerCoords[idToIndex[id]]; @@ -314,65 +315,33 @@ protected: RawPointerAxes mRawPointerAxes; struct RawState { - nsecs_t when; - nsecs_t readTime; + nsecs_t when{}; + nsecs_t readTime{}; // Raw pointer sample data. - RawPointerData rawPointerData; + RawPointerData rawPointerData{}; - int32_t buttonState; + int32_t buttonState{}; // Scroll state. - int32_t rawVScroll; - int32_t rawHScroll; - - explicit inline RawState() { clear(); } - - void copyFrom(const RawState& other) { - when = other.when; - readTime = other.readTime; - rawPointerData.copyFrom(other.rawPointerData); - buttonState = other.buttonState; - rawVScroll = other.rawVScroll; - rawHScroll = other.rawHScroll; - } + int32_t rawVScroll{}; + int32_t rawHScroll{}; - void clear() { - when = 0; - readTime = 0; - rawPointerData.clear(); - buttonState = 0; - rawVScroll = 0; - rawHScroll = 0; - } + inline void clear() { *this = RawState(); } }; struct CookedState { // Cooked pointer sample data. - CookedPointerData cookedPointerData; + CookedPointerData cookedPointerData{}; // Id bits used to differentiate fingers, stylus and mouse tools. - BitSet32 fingerIdBits; - BitSet32 stylusIdBits; - BitSet32 mouseIdBits; - - int32_t buttonState; - - void copyFrom(const CookedState& other) { - cookedPointerData.copyFrom(other.cookedPointerData); - fingerIdBits = other.fingerIdBits; - stylusIdBits = other.stylusIdBits; - mouseIdBits = other.mouseIdBits; - buttonState = other.buttonState; - } + BitSet32 fingerIdBits{}; + BitSet32 stylusIdBits{}; + BitSet32 mouseIdBits{}; - void clear() { - cookedPointerData.clear(); - fingerIdBits.clear(); - stylusIdBits.clear(); - mouseIdBits.clear(); - buttonState = 0; - } + int32_t buttonState{}; + + inline void clear() { *this = CookedState(); } }; std::vector<RawState> mRawStatesPending; @@ -528,9 +497,9 @@ private: float mPointerGestureMaxSwipeWidth; struct PointerDistanceHeapElement { - uint32_t currentPointerIndex : 8; - uint32_t lastPointerIndex : 8; - uint64_t distance : 48; // squared distance + uint32_t currentPointerIndex : 8 {}; + uint32_t lastPointerIndex : 8 {}; + uint64_t distance : 48 {}; // squared distance }; enum class PointerUsage { @@ -627,15 +596,15 @@ private: // Pointer coords and ids for the current and previous pointer gesture. Mode currentGestureMode; BitSet32 currentGestureIdBits; - uint32_t currentGestureIdToIndex[MAX_POINTER_ID + 1]; - PointerProperties currentGestureProperties[MAX_POINTERS]; - PointerCoords currentGestureCoords[MAX_POINTERS]; + IdToIndexArray currentGestureIdToIndex{}; + PropertiesArray currentGestureProperties{}; + CoordsArray currentGestureCoords{}; Mode lastGestureMode; BitSet32 lastGestureIdBits; - uint32_t lastGestureIdToIndex[MAX_POINTER_ID + 1]; - PointerProperties lastGestureProperties[MAX_POINTERS]; - PointerCoords lastGestureCoords[MAX_POINTERS]; + IdToIndexArray lastGestureIdToIndex{}; + PropertiesArray lastGestureProperties{}; + CoordsArray lastGestureCoords{}; // Time the pointer gesture last went down. nsecs_t downTime; @@ -812,17 +781,10 @@ private: [[nodiscard]] NotifyMotionArgs dispatchMotion( nsecs_t when, nsecs_t readTime, uint32_t policyFlags, uint32_t source, int32_t action, int32_t actionButton, int32_t flags, int32_t metaState, int32_t buttonState, - int32_t edgeFlags, const PointerProperties* properties, const PointerCoords* coords, - const uint32_t* idToIndex, BitSet32 idBits, int32_t changedId, float xPrecision, + int32_t edgeFlags, const PropertiesArray& properties, const CoordsArray& coords, + const IdToIndexArray& idToIndex, BitSet32 idBits, int32_t changedId, float xPrecision, float yPrecision, nsecs_t downTime, MotionClassification classification); - // Updates pointer coords and properties for pointers with specified ids that have moved. - // Returns true if any of them changed. - bool updateMovedPointers(const PointerProperties* inProperties, const PointerCoords* inCoords, - const uint32_t* inIdToIndex, PointerProperties* outProperties, - PointerCoords* outCoords, const uint32_t* outIdToIndex, - BitSet32 idBits) const; - // Returns if this touch device is a touch screen with an associated display. bool isTouchScreen(); // Updates touch spots if they are enabled. Should only be used when this device is a @@ -834,7 +796,6 @@ private: static void assignPointerIds(const RawState& last, RawState& current); - const char* modeToString(DeviceMode deviceMode); void rotateAndScale(float& x, float& y) const; }; diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp index 2142070a09..8553a7211f 100644 --- a/services/inputflinger/tests/InputReader_test.cpp +++ b/services/inputflinger/tests/InputReader_test.cpp @@ -7154,6 +7154,44 @@ TEST_F(SingleTouchInputMapperTest, ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasNotCalled()); } +TEST_F(SingleTouchInputMapperTest, ButtonIsReleasedOnTouchUp) { + addConfigurationProperty("touch.deviceType", "touchScreen"); + prepareDisplay(DISPLAY_ORIENTATION_0); + prepareButtons(); + prepareAxes(POSITION); + SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>(); + ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled()); + + // Press a stylus button. + processKey(mapper, BTN_STYLUS, 1); + processSync(mapper); + + // Start a touch gesture and ensure the BUTTON_PRESS event is generated. + processDown(mapper, 100, 200); + processSync(mapper); + ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled( + AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), + WithCoords(toDisplayX(100), toDisplayY(200)), + WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY)))); + ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled( + AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS), + WithCoords(toDisplayX(100), toDisplayY(200)), + WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY)))); + + // Release the touch gesture. Ensure that the BUTTON_RELEASE event is generated even though + // the button has not actually been released, since there will be no pointers through which the + // button state can be reported. The event is generated at the location of the pointer before + // it went up. + processUp(mapper); + processSync(mapper); + ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled( + AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE), + WithCoords(toDisplayX(100), toDisplayY(200)), WithButtonState(0)))); + ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled( + AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), + WithCoords(toDisplayX(100), toDisplayY(200)), WithButtonState(0)))); +} + // --- TouchDisplayProjectionTest --- class TouchDisplayProjectionTest : public SingleTouchInputMapperTest { |