Loading services/inputflinger/reader/mapper/CursorInputMapper.cpp +7 −2 Original line number Diff line number Diff line Loading @@ -67,7 +67,7 @@ void CursorMotionAccumulator::finishSync() { // --- CursorInputMapper --- CursorInputMapper::CursorInputMapper(InputDeviceContext& deviceContext) : InputMapper(deviceContext) {} : InputMapper(deviceContext), mLastEventTime(std::numeric_limits<nsecs_t>::min()) {} CursorInputMapper::~CursorInputMapper() { if (mPointerController != nullptr) { Loading Loading @@ -276,6 +276,7 @@ void CursorInputMapper::dumpParameters(std::string& dump) { std::list<NotifyArgs> CursorInputMapper::reset(nsecs_t when) { mButtonState = 0; mDownTime = 0; mLastEventTime = std::numeric_limits<nsecs_t>::min(); mPointerVelocityControl.reset(); mWheelXVelocityControl.reset(); Loading @@ -295,7 +296,11 @@ std::list<NotifyArgs> CursorInputMapper::process(const RawEvent* rawEvent) { mCursorScrollAccumulator.process(rawEvent); if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) { out += sync(rawEvent->when, rawEvent->readTime); const nsecs_t eventTime = applyBluetoothTimestampSmoothening(getDeviceContext().getDeviceIdentifier(), rawEvent->when, mLastEventTime); out += sync(eventTime, rawEvent->readTime); mLastEventTime = eventTime; } return out; } Loading services/inputflinger/reader/mapper/CursorInputMapper.h +1 −0 Original line number Diff line number Diff line Loading @@ -121,6 +121,7 @@ private: int32_t mButtonState; nsecs_t mDownTime; nsecs_t mLastEventTime; void configureParameters(); void dumpParameters(std::string& dump); Loading services/inputflinger/reader/mapper/TouchCursorInputMapperCommon.h +26 −0 Original line number Diff line number Diff line Loading @@ -101,4 +101,30 @@ static bool isPointerDown(int32_t buttonState) { return out; } // For devices connected over Bluetooth, although they may produce events at a consistent rate, // the events might end up reaching Android in a "batched" manner through the Bluetooth // stack, where a few events may be clumped together and processed around the same time. // In this case, if the input device or its driver does not send or process the actual event // generation timestamps, the event time will set to whenever the kernel received the event. // When the timestamp deltas are minuscule for these batched events, any changes in x or y // coordinates result in extremely large instantaneous velocities, which can negatively impact // user experience. To avoid this, we augment the timestamps so that subsequent event timestamps // differ by at least a minimum delta value. static nsecs_t applyBluetoothTimestampSmoothening(const InputDeviceIdentifier& identifier, nsecs_t currentEventTime, nsecs_t lastEventTime) { if (identifier.bus != BUS_BLUETOOTH) { return currentEventTime; } // Assume the fastest rate at which a Bluetooth touch device can report input events is one // every 4 milliseconds, or 250 Hz. Timestamps for successive events from a Bluetooth device // will be separated by at least this amount. constexpr static nsecs_t MIN_BLUETOOTH_TIMESTAMP_DELTA = ms2ns(4); // We define a maximum smoothing time delta so that we don't generate events too far into the // future. constexpr static nsecs_t MAX_BLUETOOTH_SMOOTHING_DELTA = ms2ns(32); return std::min(std::max(currentEventTime, lastEventTime + MIN_BLUETOOTH_TIMESTAMP_DELTA), currentEventTime + MAX_BLUETOOTH_SMOOTHING_DELTA); } } // namespace android services/inputflinger/reader/mapper/TouchInputMapper.cpp +3 −0 Original line number Diff line number Diff line Loading @@ -1469,6 +1469,9 @@ std::list<NotifyArgs> TouchInputMapper::sync(nsecs_t when, nsecs_t readTime) { const RawState& last = mRawStatesPending.size() == 1 ? mCurrentRawState : mRawStatesPending.rbegin()[1]; next.when = applyBluetoothTimestampSmoothening(getDeviceContext().getDeviceIdentifier(), when, last.when); // Assign pointer ids. if (!mHavePointerIds) { assignPointerIds(last, next); Loading services/inputflinger/reader/mapper/TouchInputMapper.h +1 −1 Original line number Diff line number Diff line Loading @@ -318,7 +318,7 @@ protected: RawPointerAxes mRawPointerAxes; struct RawState { nsecs_t when{}; nsecs_t when{std::numeric_limits<nsecs_t>::min()}; nsecs_t readTime{}; // Raw pointer sample data. Loading Loading
services/inputflinger/reader/mapper/CursorInputMapper.cpp +7 −2 Original line number Diff line number Diff line Loading @@ -67,7 +67,7 @@ void CursorMotionAccumulator::finishSync() { // --- CursorInputMapper --- CursorInputMapper::CursorInputMapper(InputDeviceContext& deviceContext) : InputMapper(deviceContext) {} : InputMapper(deviceContext), mLastEventTime(std::numeric_limits<nsecs_t>::min()) {} CursorInputMapper::~CursorInputMapper() { if (mPointerController != nullptr) { Loading Loading @@ -276,6 +276,7 @@ void CursorInputMapper::dumpParameters(std::string& dump) { std::list<NotifyArgs> CursorInputMapper::reset(nsecs_t when) { mButtonState = 0; mDownTime = 0; mLastEventTime = std::numeric_limits<nsecs_t>::min(); mPointerVelocityControl.reset(); mWheelXVelocityControl.reset(); Loading @@ -295,7 +296,11 @@ std::list<NotifyArgs> CursorInputMapper::process(const RawEvent* rawEvent) { mCursorScrollAccumulator.process(rawEvent); if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) { out += sync(rawEvent->when, rawEvent->readTime); const nsecs_t eventTime = applyBluetoothTimestampSmoothening(getDeviceContext().getDeviceIdentifier(), rawEvent->when, mLastEventTime); out += sync(eventTime, rawEvent->readTime); mLastEventTime = eventTime; } return out; } Loading
services/inputflinger/reader/mapper/CursorInputMapper.h +1 −0 Original line number Diff line number Diff line Loading @@ -121,6 +121,7 @@ private: int32_t mButtonState; nsecs_t mDownTime; nsecs_t mLastEventTime; void configureParameters(); void dumpParameters(std::string& dump); Loading
services/inputflinger/reader/mapper/TouchCursorInputMapperCommon.h +26 −0 Original line number Diff line number Diff line Loading @@ -101,4 +101,30 @@ static bool isPointerDown(int32_t buttonState) { return out; } // For devices connected over Bluetooth, although they may produce events at a consistent rate, // the events might end up reaching Android in a "batched" manner through the Bluetooth // stack, where a few events may be clumped together and processed around the same time. // In this case, if the input device or its driver does not send or process the actual event // generation timestamps, the event time will set to whenever the kernel received the event. // When the timestamp deltas are minuscule for these batched events, any changes in x or y // coordinates result in extremely large instantaneous velocities, which can negatively impact // user experience. To avoid this, we augment the timestamps so that subsequent event timestamps // differ by at least a minimum delta value. static nsecs_t applyBluetoothTimestampSmoothening(const InputDeviceIdentifier& identifier, nsecs_t currentEventTime, nsecs_t lastEventTime) { if (identifier.bus != BUS_BLUETOOTH) { return currentEventTime; } // Assume the fastest rate at which a Bluetooth touch device can report input events is one // every 4 milliseconds, or 250 Hz. Timestamps for successive events from a Bluetooth device // will be separated by at least this amount. constexpr static nsecs_t MIN_BLUETOOTH_TIMESTAMP_DELTA = ms2ns(4); // We define a maximum smoothing time delta so that we don't generate events too far into the // future. constexpr static nsecs_t MAX_BLUETOOTH_SMOOTHING_DELTA = ms2ns(32); return std::min(std::max(currentEventTime, lastEventTime + MIN_BLUETOOTH_TIMESTAMP_DELTA), currentEventTime + MAX_BLUETOOTH_SMOOTHING_DELTA); } } // namespace android
services/inputflinger/reader/mapper/TouchInputMapper.cpp +3 −0 Original line number Diff line number Diff line Loading @@ -1469,6 +1469,9 @@ std::list<NotifyArgs> TouchInputMapper::sync(nsecs_t when, nsecs_t readTime) { const RawState& last = mRawStatesPending.size() == 1 ? mCurrentRawState : mRawStatesPending.rbegin()[1]; next.when = applyBluetoothTimestampSmoothening(getDeviceContext().getDeviceIdentifier(), when, last.when); // Assign pointer ids. if (!mHavePointerIds) { assignPointerIds(last, next); Loading
services/inputflinger/reader/mapper/TouchInputMapper.h +1 −1 Original line number Diff line number Diff line Loading @@ -318,7 +318,7 @@ protected: RawPointerAxes mRawPointerAxes; struct RawState { nsecs_t when{}; nsecs_t when{std::numeric_limits<nsecs_t>::min()}; nsecs_t readTime{}; // Raw pointer sample data. Loading