diff options
| author | 2022-10-12 14:36:45 +0000 | |
|---|---|---|
| committer | 2022-10-12 14:36:45 +0000 | |
| commit | eb38d4613545b89858df521af7d3a78a8a27abbc (patch) | |
| tree | 875c1dbf88ffff9ed7cd2a961a9bd9526375198f | |
| parent | 87717eafed72e18f4b608d49129078f8c5a2eb96 (diff) | |
| parent | 167c270ea82781d0a003c05292ff623fcb5f8243 (diff) | |
Merge changes from topic "inputdevice-supportsusi"
* changes:
Determine whether an input device supports USI using IDC files
TouchInputMapper: Cancel ongoing gesture when resetting
TouchInputMapper: Use early return in populateDeviceInfo
| -rw-r--r-- | include/input/InputDevice.h | 5 | ||||
| -rw-r--r-- | libs/input/InputDevice.cpp | 2 | ||||
| -rw-r--r-- | services/inputflinger/reader/mapper/TouchInputMapper.cpp | 149 | ||||
| -rw-r--r-- | services/inputflinger/reader/mapper/TouchInputMapper.h | 3 | ||||
| -rw-r--r-- | services/inputflinger/tests/InputReader_test.cpp | 45 | ||||
| -rw-r--r-- | services/inputflinger/tests/TestInputListenerMatchers.h | 14 |
6 files changed, 136 insertions, 82 deletions
diff --git a/include/input/InputDevice.h b/include/input/InputDevice.h index 0026e82caa..f4a15238cf 100644 --- a/include/input/InputDevice.h +++ b/include/input/InputDevice.h @@ -280,6 +280,9 @@ public: std::vector<InputDeviceLightInfo> getLights(); + inline void setSupportsUsi(bool supportsUsi) { mSupportsUsi = supportsUsi; } + inline bool supportsUsi() const { return mSupportsUsi; } + private: int32_t mId; int32_t mGeneration; @@ -292,6 +295,8 @@ private: uint32_t mSources; int32_t mKeyboardType; std::shared_ptr<KeyCharacterMap> mKeyCharacterMap; + // Whether this device supports the Universal Stylus Initiative (USI) protocol for styluses. + bool mSupportsUsi; bool mHasVibrator; bool mHasBattery; diff --git a/libs/input/InputDevice.cpp b/libs/input/InputDevice.cpp index 3fe03c7979..4751a7de8b 100644 --- a/libs/input/InputDevice.cpp +++ b/libs/input/InputDevice.cpp @@ -182,6 +182,7 @@ InputDeviceInfo::InputDeviceInfo(const InputDeviceInfo& other) mSources(other.mSources), mKeyboardType(other.mKeyboardType), mKeyCharacterMap(other.mKeyCharacterMap), + mSupportsUsi(other.mSupportsUsi), mHasVibrator(other.mHasVibrator), mHasBattery(other.mHasBattery), mHasButtonUnderPad(other.mHasButtonUnderPad), @@ -210,6 +211,7 @@ void InputDeviceInfo::initialize(int32_t id, int32_t generation, int32_t control mHasBattery = false; mHasButtonUnderPad = false; mHasSensor = false; + mSupportsUsi = false; mMotionRanges.clear(); mSensors.clear(); mLights.clear(); diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.cpp b/services/inputflinger/reader/mapper/TouchInputMapper.cpp index da58efde31..18a73eadfb 100644 --- a/services/inputflinger/reader/mapper/TouchInputMapper.cpp +++ b/services/inputflinger/reader/mapper/TouchInputMapper.cpp @@ -189,73 +189,74 @@ uint32_t TouchInputMapper::getSources() const { void TouchInputMapper::populateDeviceInfo(InputDeviceInfo* info) { InputMapper::populateDeviceInfo(info); - if (mDeviceMode != DeviceMode::DISABLED) { - info->addMotionRange(mOrientedRanges.x); - info->addMotionRange(mOrientedRanges.y); - info->addMotionRange(mOrientedRanges.pressure); - - if (mDeviceMode == DeviceMode::UNSCALED && mSource == AINPUT_SOURCE_TOUCHPAD) { - // Populate RELATIVE_X and RELATIVE_Y motion ranges for touchpad capture mode. - // - // RELATIVE_X and RELATIVE_Y motion ranges should be the largest possible relative - // motion, i.e. the hardware dimensions, as the finger could move completely across the - // touchpad in one sample cycle. - const InputDeviceInfo::MotionRange& x = mOrientedRanges.x; - const InputDeviceInfo::MotionRange& y = mOrientedRanges.y; - info->addMotionRange(AMOTION_EVENT_AXIS_RELATIVE_X, mSource, -x.max, x.max, x.flat, - x.fuzz, x.resolution); - info->addMotionRange(AMOTION_EVENT_AXIS_RELATIVE_Y, mSource, -y.max, y.max, y.flat, - y.fuzz, y.resolution); - } + if (mDeviceMode == DeviceMode::DISABLED) { + return; + } - if (mOrientedRanges.size) { - info->addMotionRange(*mOrientedRanges.size); - } + info->addMotionRange(mOrientedRanges.x); + info->addMotionRange(mOrientedRanges.y); + info->addMotionRange(mOrientedRanges.pressure); - if (mOrientedRanges.touchMajor) { - info->addMotionRange(*mOrientedRanges.touchMajor); - info->addMotionRange(*mOrientedRanges.touchMinor); - } + if (mDeviceMode == DeviceMode::UNSCALED && mSource == AINPUT_SOURCE_TOUCHPAD) { + // Populate RELATIVE_X and RELATIVE_Y motion ranges for touchpad capture mode. + // + // RELATIVE_X and RELATIVE_Y motion ranges should be the largest possible relative + // motion, i.e. the hardware dimensions, as the finger could move completely across the + // touchpad in one sample cycle. + const InputDeviceInfo::MotionRange& x = mOrientedRanges.x; + const InputDeviceInfo::MotionRange& y = mOrientedRanges.y; + info->addMotionRange(AMOTION_EVENT_AXIS_RELATIVE_X, mSource, -x.max, x.max, x.flat, x.fuzz, + x.resolution); + info->addMotionRange(AMOTION_EVENT_AXIS_RELATIVE_Y, mSource, -y.max, y.max, y.flat, y.fuzz, + y.resolution); + } - if (mOrientedRanges.toolMajor) { - info->addMotionRange(*mOrientedRanges.toolMajor); - info->addMotionRange(*mOrientedRanges.toolMinor); - } + if (mOrientedRanges.size) { + info->addMotionRange(*mOrientedRanges.size); + } - if (mOrientedRanges.orientation) { - info->addMotionRange(*mOrientedRanges.orientation); - } + if (mOrientedRanges.touchMajor) { + info->addMotionRange(*mOrientedRanges.touchMajor); + info->addMotionRange(*mOrientedRanges.touchMinor); + } - if (mOrientedRanges.distance) { - info->addMotionRange(*mOrientedRanges.distance); - } + if (mOrientedRanges.toolMajor) { + info->addMotionRange(*mOrientedRanges.toolMajor); + info->addMotionRange(*mOrientedRanges.toolMinor); + } - if (mOrientedRanges.tilt) { - info->addMotionRange(*mOrientedRanges.tilt); - } + if (mOrientedRanges.orientation) { + info->addMotionRange(*mOrientedRanges.orientation); + } - if (mCursorScrollAccumulator.haveRelativeVWheel()) { - info->addMotionRange(AMOTION_EVENT_AXIS_VSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f, - 0.0f); - } - if (mCursorScrollAccumulator.haveRelativeHWheel()) { - info->addMotionRange(AMOTION_EVENT_AXIS_HSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f, - 0.0f); - } - if (mCalibration.coverageCalibration == Calibration::CoverageCalibration::BOX) { - const InputDeviceInfo::MotionRange& x = mOrientedRanges.x; - const InputDeviceInfo::MotionRange& y = mOrientedRanges.y; - info->addMotionRange(AMOTION_EVENT_AXIS_GENERIC_1, mSource, x.min, x.max, x.flat, - x.fuzz, x.resolution); - info->addMotionRange(AMOTION_EVENT_AXIS_GENERIC_2, mSource, y.min, y.max, y.flat, - y.fuzz, y.resolution); - info->addMotionRange(AMOTION_EVENT_AXIS_GENERIC_3, mSource, x.min, x.max, x.flat, - x.fuzz, x.resolution); - info->addMotionRange(AMOTION_EVENT_AXIS_GENERIC_4, mSource, y.min, y.max, y.flat, - y.fuzz, y.resolution); - } - info->setButtonUnderPad(mParameters.hasButtonUnderPad); + if (mOrientedRanges.distance) { + info->addMotionRange(*mOrientedRanges.distance); + } + + if (mOrientedRanges.tilt) { + info->addMotionRange(*mOrientedRanges.tilt); + } + + if (mCursorScrollAccumulator.haveRelativeVWheel()) { + info->addMotionRange(AMOTION_EVENT_AXIS_VSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f); + } + if (mCursorScrollAccumulator.haveRelativeHWheel()) { + info->addMotionRange(AMOTION_EVENT_AXIS_HSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f); } + if (mCalibration.coverageCalibration == Calibration::CoverageCalibration::BOX) { + const InputDeviceInfo::MotionRange& x = mOrientedRanges.x; + const InputDeviceInfo::MotionRange& y = mOrientedRanges.y; + info->addMotionRange(AMOTION_EVENT_AXIS_GENERIC_1, mSource, x.min, x.max, x.flat, x.fuzz, + x.resolution); + info->addMotionRange(AMOTION_EVENT_AXIS_GENERIC_2, mSource, y.min, y.max, y.flat, y.fuzz, + y.resolution); + info->addMotionRange(AMOTION_EVENT_AXIS_GENERIC_3, mSource, x.min, x.max, x.flat, x.fuzz, + x.resolution); + info->addMotionRange(AMOTION_EVENT_AXIS_GENERIC_4, mSource, y.min, y.max, y.flat, y.fuzz, + y.resolution); + } + info->setButtonUnderPad(mParameters.hasButtonUnderPad); + info->setSupportsUsi(mParameters.supportsUsi); } void TouchInputMapper::dump(std::string& dump) { @@ -395,13 +396,11 @@ std::list<NotifyArgs> TouchInputMapper::configure(nsecs_t when, } if (changes && resetNeeded) { - // If the device needs to be reset, cancel any ongoing gestures and reset the state. - out += cancelTouch(when, when); out += reset(when); // Send reset, unless this is the first time the device has been configured, // in which case the reader will call reset itself after all mappers are ready. - out.push_back(NotifyDeviceResetArgs(getContext()->getNextId(), when, getDeviceId())); + out.emplace_back(NotifyDeviceResetArgs(getContext()->getNextId(), when, getDeviceId())); } return out; } @@ -507,6 +506,10 @@ void TouchInputMapper::configureParameters() { // up in your pocket but you can enable it using the input device configuration. mParameters.wake = getDeviceContext().isExternal(); getDeviceContext().getConfiguration().tryGetProperty("touch.wake", mParameters.wake); + + mParameters.supportsUsi = false; + getDeviceContext().getConfiguration().tryGetProperty("touch.supportsUsi", + mParameters.supportsUsi); } void TouchInputMapper::dumpParameters(std::string& dump) { @@ -523,6 +526,7 @@ void TouchInputMapper::dumpParameters(std::string& dump) { mParameters.uniqueDisplayId.c_str()); dump += StringPrintf(INDENT4 "OrientationAware: %s\n", toString(mParameters.orientationAware)); dump += INDENT4 "Orientation: " + ftl::enum_string(mParameters.orientation) + "\n"; + dump += StringPrintf(INDENT4 "SupportsUsi: %s\n", toString(mParameters.supportsUsi)); } void TouchInputMapper::configureRawPointerAxes() { @@ -1440,6 +1444,9 @@ void TouchInputMapper::updateAffineTransformation() { } std::list<NotifyArgs> TouchInputMapper::reset(nsecs_t when) { + std::list<NotifyArgs> out = cancelTouch(when, when); + updateTouchSpots(); + mCursorButtonAccumulator.reset(getDeviceContext()); mCursorScrollAccumulator.reset(getDeviceContext()); mTouchButtonAccumulator.reset(getDeviceContext()); @@ -1470,7 +1477,7 @@ std::list<NotifyArgs> TouchInputMapper::reset(nsecs_t when) { mPointerController->clearSpots(); } - return InputMapper::reset(when); + return out += InputMapper::reset(when); } void TouchInputMapper::resetExternalStylus() { @@ -1554,10 +1561,7 @@ std::list<NotifyArgs> TouchInputMapper::sync(nsecs_t when, nsecs_t readTime) { std::list<NotifyArgs> TouchInputMapper::processRawTouches(bool timeout) { std::list<NotifyArgs> out; if (mDeviceMode == DeviceMode::DISABLED) { - // Drop all input if the device is disabled. - out += cancelTouch(mCurrentRawState.when, mCurrentRawState.readTime); - mCurrentCookedState.clear(); - updateTouchSpots(); + // Do not process raw event while the device is disabled. return out; } @@ -1976,8 +1980,8 @@ std::list<NotifyArgs> TouchInputMapper::abortTouches(nsecs_t when, nsecs_t readT int32_t metaState = getContext()->getGlobalMetaState(); int32_t buttonState = mCurrentCookedState.buttonState; out.push_back(dispatchMotion(when, readTime, policyFlags, mSource, - AMOTION_EVENT_ACTION_CANCEL, 0, 0, metaState, buttonState, - AMOTION_EVENT_EDGE_FLAG_NONE, + AMOTION_EVENT_ACTION_CANCEL, 0, AMOTION_EVENT_FLAG_CANCELED, + metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE, mCurrentCookedState.cookedPointerData.pointerProperties, mCurrentCookedState.cookedPointerData.pointerCoords, mCurrentCookedState.cookedPointerData.idToIndex, currentIdBits, @@ -2617,8 +2621,9 @@ std::list<NotifyArgs> TouchInputMapper::dispatchPointerGestures(nsecs_t when, ns BitSet32 dispatchedGestureIdBits(mPointerGesture.lastGestureIdBits); if (!dispatchedGestureIdBits.isEmpty()) { if (cancelPreviousGesture) { + const uint32_t cancelFlags = flags | AMOTION_EVENT_FLAG_CANCELED; out.push_back(dispatchMotion(when, readTime, policyFlags, mSource, - AMOTION_EVENT_ACTION_CANCEL, 0, flags, metaState, + AMOTION_EVENT_ACTION_CANCEL, 0, cancelFlags, metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE, mPointerGesture.lastGestureProperties, mPointerGesture.lastGestureCoords, @@ -2754,8 +2759,8 @@ std::list<NotifyArgs> TouchInputMapper::abortPointerGestures(nsecs_t when, nsecs int32_t metaState = getContext()->getGlobalMetaState(); int32_t buttonState = mCurrentRawState.buttonState; out.push_back(dispatchMotion(when, readTime, policyFlags, mSource, - AMOTION_EVENT_ACTION_CANCEL, 0, 0, metaState, buttonState, - AMOTION_EVENT_EDGE_FLAG_NONE, + AMOTION_EVENT_ACTION_CANCEL, 0, AMOTION_EVENT_FLAG_CANCELED, + metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE, mPointerGesture.lastGestureProperties, mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex, diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.h b/services/inputflinger/reader/mapper/TouchInputMapper.h index 50f30c824e..7b0327e913 100644 --- a/services/inputflinger/reader/mapper/TouchInputMapper.h +++ b/services/inputflinger/reader/mapper/TouchInputMapper.h @@ -232,6 +232,9 @@ protected: GestureMode gestureMode; bool wake; + + // Whether the device supports the Universal Stylus Initiative (USI) protocol for styluses. + bool supportsUsi; } mParameters; // Immutable calibration parameters in parsed form. diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp index dded6a13e0..8ac8dfc3ac 100644 --- a/services/inputflinger/tests/InputReader_test.cpp +++ b/services/inputflinger/tests/InputReader_test.cpp @@ -3112,6 +3112,15 @@ protected: return processArgList; } + void resetMapper(InputMapper& mapper, nsecs_t when) { + const auto resetArgs = mapper.reset(when); + for (const auto args : resetArgs) { + mFakeListener->notify(args); + } + // Loop the reader to flush the input listener queue. + mReader->loopOnce(); + } + static void assertMotionRange(const InputDeviceInfo& info, int32_t axis, uint32_t source, float min, float max, float flat, float fuzz) { const InputDeviceInfo::MotionRange* range = info.getMotionRange(axis, source); @@ -6864,6 +6873,28 @@ TEST_F(SingleTouchInputMapperTest, Process_WhenAbsPressureIsPresent_HoversIfItsV toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0)); } +TEST_F(SingleTouchInputMapperTest, Reset_CancelsOngoingGesture) { + addConfigurationProperty("touch.deviceType", "touchScreen"); + prepareDisplay(DISPLAY_ORIENTATION_0); + prepareButtons(); + prepareAxes(POSITION | PRESSURE); + SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>(); + + // Touch down. + processDown(mapper, 100, 200); + processPressure(mapper, 1); + processSync(mapper); + ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled( + WithMotionAction(AMOTION_EVENT_ACTION_DOWN))); + + // Reset the mapper. This should cancel the ongoing gesture. + resetMapper(mapper, ARBITRARY_TIME); + ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled( + WithMotionAction(AMOTION_EVENT_ACTION_CANCEL))); + + ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled()); +} + TEST_F(SingleTouchInputMapperTest, Reset_RecreatesTouchState) { addConfigurationProperty("touch.deviceType", "touchScreen"); prepareDisplay(DISPLAY_ORIENTATION_0); @@ -6878,8 +6909,9 @@ TEST_F(SingleTouchInputMapperTest, Reset_RecreatesTouchState) { mFakeEventHub->setScanCodeState(EVENTHUB_ID, BTN_TOUCH, 1); // Reset the mapper. When the mapper is reset, we expect it to attempt to recreate the touch - // state by reading the current axis values. - std::list<NotifyArgs> unused = mapper.reset(ARBITRARY_TIME); + // state by reading the current axis values. Since there was no ongoing gesture, calling reset + // does not generate any events. + resetMapper(mapper, ARBITRARY_TIME); // Send a sync to simulate an empty touch frame where nothing changes. The mapper should use // the recreated touch state to generate a down event. @@ -9530,9 +9562,10 @@ TEST_F(MultiTouchInputMapperTest, Reset_PreservesLastTouchState) { mFakeListener->assertNotifyMotionWasCalled(WithMotionAction(ACTION_POINTER_1_DOWN))); // Reset the mapper. When the mapper is reset, we expect the current multi-touch state to be - // preserved. Resetting should not generate any events. - std::list<NotifyArgs> unused = mapper.reset(ARBITRARY_TIME); - ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled()); + // preserved. Resetting should cancel the ongoing gesture. + resetMapper(mapper, ARBITRARY_TIME); + ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled( + WithMotionAction(AMOTION_EVENT_ACTION_CANCEL))); // Send a sync to simulate an empty touch frame where nothing changes. The mapper should use // the existing touch state to generate a down event. @@ -9566,7 +9599,7 @@ TEST_F(MultiTouchInputMapperTest, Reset_PreservesLastTouchState_NoPointersDown) // Reset the mapper. When the mapper is reset, we expect it to restore the latest // raw state where no pointers are down. - std::list<NotifyArgs> unused = mapper.reset(ARBITRARY_TIME); + resetMapper(mapper, ARBITRARY_TIME); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled()); // Send an empty sync frame. Since there are no pointers, no events are generated. diff --git a/services/inputflinger/tests/TestInputListenerMatchers.h b/services/inputflinger/tests/TestInputListenerMatchers.h index 2580405c02..ff7455b452 100644 --- a/services/inputflinger/tests/TestInputListenerMatchers.h +++ b/services/inputflinger/tests/TestInputListenerMatchers.h @@ -23,13 +23,19 @@ namespace android { MATCHER_P(WithMotionAction, action, "InputEvent with specified action") { + bool matches = action == arg.action; + if (!matches) { + *result_listener << "expected action " << MotionEvent::actionToString(action) + << ", but got " << MotionEvent::actionToString(arg.action); + } if (action == AMOTION_EVENT_ACTION_CANCEL) { + if (!matches) { + *result_listener << "; "; + } *result_listener << "expected FLAG_CANCELED to be set with ACTION_CANCEL, but was not set"; - return (arg.flags & AMOTION_EVENT_FLAG_CANCELED) != 0; + matches &= (arg.flags & AMOTION_EVENT_FLAG_CANCELED) != 0; } - *result_listener << "expected action " << MotionEvent::actionToString(action) << ", but got " - << MotionEvent::actionToString(arg.action); - return action == arg.action; + return matches; } MATCHER_P(WithSource, source, "InputEvent with specified source") { |