diff options
author | 2023-11-02 10:28:23 +0000 | |
---|---|---|
committer | 2023-11-02 10:28:23 +0000 | |
commit | d5a57a5d892cfb78cf9add6d18e70b26b53365d3 (patch) | |
tree | ed81671e925996c1d8afbc63f7517e7ab6680bfa | |
parent | fa9ff870a152cf77404ee0dfcb1768162556f7b8 (diff) | |
parent | 483104c2d58194074bf020a6797b96dcf06a802b (diff) |
Merge changes I53f65dae,I4bbfe4c5 into main
* changes:
Count active touches in MultiTouchMotionAccumulator
Record last keypress timestamp on physical keyboard while typing
15 files changed, 155 insertions, 5 deletions
diff --git a/services/inputflinger/reader/InputReader.cpp b/services/inputflinger/reader/InputReader.cpp index 5766b14231..0582649d38 100644 --- a/services/inputflinger/reader/InputReader.cpp +++ b/services/inputflinger/reader/InputReader.cpp @@ -1046,6 +1046,14 @@ bool InputReader::ContextImpl::isPreventingTouchpadTaps() { return mReader->mPreventingTouchpadTaps; } +void InputReader::ContextImpl::setLastKeyDownTimestamp(nsecs_t when) { + mReader->mLastKeyDownTimestamp = when; +} + +nsecs_t InputReader::ContextImpl::getLastKeyDownTimestamp() { + return mReader->mLastKeyDownTimestamp; +} + void InputReader::ContextImpl::disableVirtualKeysUntil(nsecs_t time) { // lock is already held by the input loop mReader->disableVirtualKeysUntilLocked(time); diff --git a/services/inputflinger/reader/include/InputReader.h b/services/inputflinger/reader/include/InputReader.h index 9a297c9ace..4c78db38cc 100644 --- a/services/inputflinger/reader/include/InputReader.h +++ b/services/inputflinger/reader/include/InputReader.h @@ -158,6 +158,9 @@ protected: void setPreventingTouchpadTaps(bool prevent) REQUIRES(mReader->mLock) REQUIRES(mLock) override; bool isPreventingTouchpadTaps() REQUIRES(mReader->mLock) REQUIRES(mLock) override; + void setLastKeyDownTimestamp(nsecs_t when) REQUIRES(mReader->mLock) + REQUIRES(mLock) override; + nsecs_t getLastKeyDownTimestamp() REQUIRES(mReader->mLock) REQUIRES(mLock) override; } mContext; friend class ContextImpl; @@ -198,6 +201,9 @@ private: // true if tap-to-click on touchpad currently disabled bool mPreventingTouchpadTaps GUARDED_BY(mLock){false}; + // records timestamp of the last key press on the physical keyboard + nsecs_t mLastKeyDownTimestamp GUARDED_BY(mLock){0}; + // low-level input event decoding and device management [[nodiscard]] std::list<NotifyArgs> processEventsLocked(const RawEvent* rawEvents, size_t count) REQUIRES(mLock); diff --git a/services/inputflinger/reader/include/InputReaderContext.h b/services/inputflinger/reader/include/InputReaderContext.h index aed75636f7..69b2315a6c 100644 --- a/services/inputflinger/reader/include/InputReaderContext.h +++ b/services/inputflinger/reader/include/InputReaderContext.h @@ -65,6 +65,9 @@ public: virtual void setPreventingTouchpadTaps(bool prevent) = 0; virtual bool isPreventingTouchpadTaps() = 0; + + virtual void setLastKeyDownTimestamp(nsecs_t when) = 0; + virtual nsecs_t getLastKeyDownTimestamp() = 0; }; } // namespace android diff --git a/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp b/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp index 531fc6766d..f068cc8aa4 100644 --- a/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp +++ b/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp @@ -270,7 +270,7 @@ std::list<NotifyArgs> KeyboardInputMapper::processKey(nsecs_t when, nsecs_t read keyDown.flags = flags; mKeyDowns.push_back(keyDown); } - onKeyDownProcessed(); + onKeyDownProcessed(downTime); } else { // Remove key down. if (keyDownIndex) { @@ -448,8 +448,9 @@ std::list<NotifyArgs> KeyboardInputMapper::cancelAllDownKeys(nsecs_t when) { return out; } -void KeyboardInputMapper::onKeyDownProcessed() { +void KeyboardInputMapper::onKeyDownProcessed(nsecs_t downTime) { InputReaderContext& context = *getContext(); + context.setLastKeyDownTimestamp(downTime); if (context.isPreventingTouchpadTaps()) { // avoid pinging java service unnecessarily, just fade pointer again if it became visible context.fadePointer(); diff --git a/services/inputflinger/reader/mapper/KeyboardInputMapper.h b/services/inputflinger/reader/mapper/KeyboardInputMapper.h index 09808df18c..500256b21f 100644 --- a/services/inputflinger/reader/mapper/KeyboardInputMapper.h +++ b/services/inputflinger/reader/mapper/KeyboardInputMapper.h @@ -107,7 +107,7 @@ private: void updateLedStateForModifier(LedState& ledState, int32_t led, int32_t modifier, bool reset); std::optional<DisplayViewport> findViewport(const InputReaderConfiguration& readerConfig); [[nodiscard]] std::list<NotifyArgs> cancelAllDownKeys(nsecs_t when); - void onKeyDownProcessed(); + void onKeyDownProcessed(nsecs_t downTime); }; } // namespace android diff --git a/services/inputflinger/reader/mapper/accumulator/MultiTouchMotionAccumulator.cpp b/services/inputflinger/reader/mapper/accumulator/MultiTouchMotionAccumulator.cpp index f70be72741..b0fc9035f2 100644 --- a/services/inputflinger/reader/mapper/accumulator/MultiTouchMotionAccumulator.cpp +++ b/services/inputflinger/reader/mapper/accumulator/MultiTouchMotionAccumulator.cpp @@ -152,6 +152,14 @@ void MultiTouchMotionAccumulator::warnIfNotInUse(const RawEvent& event, const Sl } } +size_t MultiTouchMotionAccumulator::getActiveSlotsCount() const { + if (!mUsingSlotsProtocol) { + return mCurrentSlot < 0 ? 0 : mCurrentSlot; + } + return std::count_if(mSlots.begin(), mSlots.end(), + [](const Slot& slot) { return slot.mInUse; }); +} + // --- MultiTouchMotionAccumulator::Slot --- ToolType MultiTouchMotionAccumulator::Slot::getToolType() const { diff --git a/services/inputflinger/reader/mapper/accumulator/MultiTouchMotionAccumulator.h b/services/inputflinger/reader/mapper/accumulator/MultiTouchMotionAccumulator.h index 943dde5ca2..0e3e2bb365 100644 --- a/services/inputflinger/reader/mapper/accumulator/MultiTouchMotionAccumulator.h +++ b/services/inputflinger/reader/mapper/accumulator/MultiTouchMotionAccumulator.h @@ -77,6 +77,7 @@ public: void process(const RawEvent* rawEvent); void finishSync(); + size_t getActiveSlotsCount() const; inline size_t getSlotCount() const { return mSlots.size(); } inline const Slot& getSlot(size_t index) const { LOG_ALWAYS_FATAL_IF(index < 0 || index >= mSlots.size(), "Invalid index: %zu", index); diff --git a/services/inputflinger/tests/Android.bp b/services/inputflinger/tests/Android.bp index 64e8825f34..db31dede2f 100644 --- a/services/inputflinger/tests/Android.bp +++ b/services/inputflinger/tests/Android.bp @@ -58,6 +58,7 @@ cc_test { "InputReader_test.cpp", "InstrumentedInputReader.cpp", "LatencyTracker_test.cpp", + "MultiTouchMotionAccumulator_test.cpp", "NotifyArgs_test.cpp", "PointerChoreographer_test.cpp", "PreferStylusOverTouch_test.cpp", diff --git a/services/inputflinger/tests/InputMapperTest.cpp b/services/inputflinger/tests/InputMapperTest.cpp index dac4ea02c4..787444c9e6 100644 --- a/services/inputflinger/tests/InputMapperTest.cpp +++ b/services/inputflinger/tests/InputMapperTest.cpp @@ -80,9 +80,15 @@ void InputMapperUnitTest::setKeyCodeState(KeyState state, std::set<int> keyCodes } std::list<NotifyArgs> InputMapperUnitTest::process(int32_t type, int32_t code, int32_t value) { + nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC); + return process(when, type, code, value); +} + +std::list<NotifyArgs> InputMapperUnitTest::process(nsecs_t when, int32_t type, int32_t code, + int32_t value) { RawEvent event; - event.when = systemTime(SYSTEM_TIME_MONOTONIC); - event.readTime = event.when; + event.when = when; + event.readTime = when; event.deviceId = mMapper->getDeviceContext().getEventHubId(); event.type = type; event.code = code; diff --git a/services/inputflinger/tests/InputMapperTest.h b/services/inputflinger/tests/InputMapperTest.h index c2ac258765..3f9061fc6a 100644 --- a/services/inputflinger/tests/InputMapperTest.h +++ b/services/inputflinger/tests/InputMapperTest.h @@ -52,6 +52,7 @@ protected: void setKeyCodeState(KeyState state, std::set<int> keyCodes); std::list<NotifyArgs> process(int32_t type, int32_t code, int32_t value); + std::list<NotifyArgs> process(nsecs_t when, int32_t type, int32_t code, int32_t value); MockEventHubInterface mMockEventHub; std::shared_ptr<FakePointerController> mFakePointerController; diff --git a/services/inputflinger/tests/InstrumentedInputReader.h b/services/inputflinger/tests/InstrumentedInputReader.h index ca85558a0c..e9c7bb44e8 100644 --- a/services/inputflinger/tests/InstrumentedInputReader.h +++ b/services/inputflinger/tests/InstrumentedInputReader.h @@ -106,6 +106,9 @@ protected: void setPreventingTouchpadTaps(bool prevent) override { mPreventingTouchpadTaps = prevent; } bool isPreventingTouchpadTaps() override { return mPreventingTouchpadTaps; } + void setLastKeyDownTimestamp(nsecs_t when) override { mLastKeyDownTimestamp = when; }; + nsecs_t getLastKeyDownTimestamp() override { return mLastKeyDownTimestamp; }; + private: int32_t mGlobalMetaState; bool mUpdateGlobalMetaStateWasCalled; @@ -113,6 +116,7 @@ protected: std::optional<nsecs_t> mRequestedTimeout; std::vector<InputDeviceInfo> mExternalStylusDevices; bool mPreventingTouchpadTaps{false}; + nsecs_t mLastKeyDownTimestamp; } mFakeContext; friend class InputReaderTest; diff --git a/services/inputflinger/tests/InterfaceMocks.h b/services/inputflinger/tests/InterfaceMocks.h index 05823cd9de..73949136f4 100644 --- a/services/inputflinger/tests/InterfaceMocks.h +++ b/services/inputflinger/tests/InterfaceMocks.h @@ -77,6 +77,9 @@ public: MOCK_METHOD(void, setPreventingTouchpadTaps, (bool prevent), (override)); MOCK_METHOD(bool, isPreventingTouchpadTaps, (), (override)); + MOCK_METHOD(void, setLastKeyDownTimestamp, (nsecs_t when)); + MOCK_METHOD(nsecs_t, getLastKeyDownTimestamp, ()); + private: int32_t mGeneration = 0; }; diff --git a/services/inputflinger/tests/KeyboardInputMapper_test.cpp b/services/inputflinger/tests/KeyboardInputMapper_test.cpp index 48f5673c51..2ef79999a2 100644 --- a/services/inputflinger/tests/KeyboardInputMapper_test.cpp +++ b/services/inputflinger/tests/KeyboardInputMapper_test.cpp @@ -26,6 +26,7 @@ namespace android { using testing::_; +using testing::Args; using testing::DoAll; using testing::Return; using testing::SetArgPointee; @@ -158,4 +159,18 @@ TEST_F(KeyboardInputMapperUnitTest, MetaKeystrokesWithIMeConnectionDontDisableTo testTouchpadTapStateForKeys(metaKeys, /* expectPrevent= */ false); } +TEST_F(KeyboardInputMapperUnitTest, KeyPressTimestampRecorded) { + nsecs_t when = ARBITRARY_TIME; + std::vector<int32_t> keyCodes{KEY_0, KEY_A, KEY_LEFTCTRL, KEY_RIGHTALT, KEY_LEFTSHIFT}; + EXPECT_CALL(mMockInputReaderContext, setLastKeyDownTimestamp) + .With(Args<0>(when)) + .Times(keyCodes.size()); + for (int32_t keyCode : keyCodes) { + process(when, EV_KEY, keyCode, 1); + process(when, EV_SYN, SYN_REPORT, 0); + process(when, EV_KEY, keyCode, 0); + process(when, EV_SYN, SYN_REPORT, 0); + } +} + } // namespace android diff --git a/services/inputflinger/tests/MultiTouchMotionAccumulator_test.cpp b/services/inputflinger/tests/MultiTouchMotionAccumulator_test.cpp new file mode 100644 index 0000000000..9fa6cdd298 --- /dev/null +++ b/services/inputflinger/tests/MultiTouchMotionAccumulator_test.cpp @@ -0,0 +1,87 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "MultiTouchMotionAccumulator.h" +#include "InputMapperTest.h" + +namespace android { + +class MultiTouchMotionAccumulatorTest : public InputMapperUnitTest { +protected: + static constexpr size_t SLOT_COUNT = 8; + + MultiTouchMotionAccumulator mMotionAccumulator; + + void processMotionEvent(int32_t type, int32_t code, int32_t value) { + RawEvent event; + event.when = ARBITRARY_TIME; + event.readTime = READ_TIME; + event.deviceId = EVENTHUB_ID; + event.type = type; + event.code = code; + event.value = value; + mMotionAccumulator.process(&event); + } +}; + +TEST_F(MultiTouchMotionAccumulatorTest, ActiveSlotCountUsingSlotsProtocol) { + mMotionAccumulator.configure(*mDeviceContext, SLOT_COUNT, /*usingSlotsProtocol=*/true); + // We expect active slot count to match the touches being tracked + // first touch + processMotionEvent(EV_ABS, ABS_MT_SLOT, 0); + processMotionEvent(EV_ABS, ABS_MT_TRACKING_ID, 123); + processMotionEvent(EV_SYN, SYN_REPORT, 0); + ASSERT_EQ(1u, mMotionAccumulator.getActiveSlotsCount()); + + // second touch + processMotionEvent(EV_ABS, ABS_MT_SLOT, 1); + processMotionEvent(EV_ABS, ABS_MT_TRACKING_ID, 456); + processMotionEvent(EV_SYN, SYN_REPORT, 0); + ASSERT_EQ(2u, mMotionAccumulator.getActiveSlotsCount()); + + // second lifted + processMotionEvent(EV_ABS, ABS_MT_TRACKING_ID, -1); + processMotionEvent(EV_SYN, SYN_REPORT, 0); + ASSERT_EQ(1u, mMotionAccumulator.getActiveSlotsCount()); + + // first lifted + processMotionEvent(EV_ABS, ABS_MT_SLOT, 0); + processMotionEvent(EV_ABS, ABS_MT_TRACKING_ID, -1); + processMotionEvent(EV_SYN, SYN_REPORT, 0); + ASSERT_EQ(0u, mMotionAccumulator.getActiveSlotsCount()); +} + +TEST_F(MultiTouchMotionAccumulatorTest, ActiveSlotCountNotUsingSlotsProtocol) { + mMotionAccumulator.configure(*mDeviceContext, SLOT_COUNT, /*usingSlotsProtocol=*/false); + + // first touch + processMotionEvent(EV_ABS, ABS_MT_POSITION_X, 0); + processMotionEvent(EV_ABS, ABS_MT_POSITION_Y, 0); + processMotionEvent(EV_SYN, SYN_MT_REPORT, 0); + ASSERT_EQ(1u, mMotionAccumulator.getActiveSlotsCount()); + + // second touch + processMotionEvent(EV_ABS, ABS_MT_POSITION_X, 50); + processMotionEvent(EV_ABS, ABS_MT_POSITION_Y, 50); + processMotionEvent(EV_SYN, SYN_MT_REPORT, 0); + ASSERT_EQ(2u, mMotionAccumulator.getActiveSlotsCount()); + + // reset + mMotionAccumulator.finishSync(); + ASSERT_EQ(0u, mMotionAccumulator.getActiveSlotsCount()); +} + +} // namespace android diff --git a/services/inputflinger/tests/fuzzers/MapperHelpers.h b/services/inputflinger/tests/fuzzers/MapperHelpers.h index bdedfdfa0c..e1c0fe28d9 100644 --- a/services/inputflinger/tests/fuzzers/MapperHelpers.h +++ b/services/inputflinger/tests/fuzzers/MapperHelpers.h @@ -360,6 +360,12 @@ public: void setPreventingTouchpadTaps(bool prevent) {} bool isPreventingTouchpadTaps() { return mFdp->ConsumeBool(); }; + + void setLastKeyDownTimestamp(nsecs_t when) { mLastKeyDownTimestamp = when; }; + nsecs_t getLastKeyDownTimestamp() { return mLastKeyDownTimestamp; }; + +private: + nsecs_t mLastKeyDownTimestamp; }; template <class Fdp> |