Loading libs/input/InputConsumer.cpp +26 −18 Original line number Diff line number Diff line Loading @@ -181,7 +181,8 @@ inline bool isPointerEvent(int32_t source) { } bool shouldResampleTool(ToolType toolType) { return toolType == ToolType::FINGER || toolType == ToolType::UNKNOWN; return toolType == ToolType::FINGER || toolType == ToolType::MOUSE || toolType == ToolType::STYLUS || toolType == ToolType::UNKNOWN; } } // namespace Loading Loading @@ -592,6 +593,11 @@ void InputConsumer::resampleTouchState(nsecs_t sampleTime, MotionEvent* event, ALOGD_IF(debugResampling(), "Not resampled, missing id %d", id); return; } if (!shouldResampleTool(event->getToolType(i))) { ALOGD_IF(debugResampling(), "Not resampled, containing unsupported tool type at pointer %d", id); return; } } // Find the data to use for resampling. Loading Loading @@ -639,10 +645,18 @@ void InputConsumer::resampleTouchState(nsecs_t sampleTime, MotionEvent* event, } if (current->eventTime == sampleTime) { // Prevents having 2 events with identical times and coordinates. ALOGD_IF(debugResampling(), "Not resampled, 2 events with identical times."); return; } for (size_t i = 0; i < pointerCount; i++) { uint32_t id = event->getPointerId(i); if (!other->idBits.hasBit(id)) { ALOGD_IF(debugResampling(), "Not resampled, the other doesn't have pointer id %d.", id); return; } } // Resample touch coordinates. History oldLastResample; oldLastResample.initializeFrom(touchState.lastResample); Loading Loading @@ -670,7 +684,6 @@ void InputConsumer::resampleTouchState(nsecs_t sampleTime, MotionEvent* event, const PointerCoords& currentCoords = current->getPointerById(id); resampledCoords = currentCoords; resampledCoords.isResampled = true; if (other->idBits.hasBit(id) && shouldResampleTool(event->getToolType(i))) { const PointerCoords& otherCoords = other->getPointerById(id); resampledCoords.setAxisValue(AMOTION_EVENT_AXIS_X, lerp(currentCoords.getX(), otherCoords.getX(), alpha)); Loading @@ -681,11 +694,6 @@ void InputConsumer::resampleTouchState(nsecs_t sampleTime, MotionEvent* event, "other (%0.3f, %0.3f), alpha %0.3f", id, resampledCoords.getX(), resampledCoords.getY(), currentCoords.getX(), currentCoords.getY(), otherCoords.getX(), otherCoords.getY(), alpha); } else { ALOGD_IF(debugResampling(), "[%d] - out (%0.3f, %0.3f), cur (%0.3f, %0.3f)", id, resampledCoords.getX(), resampledCoords.getY(), currentCoords.getX(), currentCoords.getY()); } } event->addSample(sampleTime, touchState.lastResample.pointers); Loading libs/input/tests/TouchResampling_test.cpp +80 −5 Original line number Diff line number Diff line Loading @@ -297,10 +297,9 @@ TEST_F(TouchResamplingTest, EventIsResampledWithDifferentId) { } /** * Stylus pointer coordinates are not resampled, but an event is still generated for the batch with * a resampled timestamp and should be marked as such. * Stylus pointer coordinates are resampled. */ TEST_F(TouchResamplingTest, StylusCoordinatesNotResampledFor) { TEST_F(TouchResamplingTest, StylusEventIsResampled) { std::chrono::nanoseconds frameTime; std::vector<InputEventEntry> entries, expectedEntries; Loading Loading @@ -330,14 +329,90 @@ TEST_F(TouchResamplingTest, StylusCoordinatesNotResampledFor) { // id x y {10ms, {{0, 20, 30, .toolType = ToolType::STYLUS}}, AMOTION_EVENT_ACTION_MOVE}, {20ms, {{0, 30, 30, .toolType = ToolType::STYLUS}}, AMOTION_EVENT_ACTION_MOVE}, // A resampled event is generated, but the stylus coordinates are not resampled. {25ms, {{0, 30, 30, .toolType = ToolType::STYLUS, .isResampled = true}}, {{0, 35, 30, .toolType = ToolType::STYLUS, .isResampled = true}}, AMOTION_EVENT_ACTION_MOVE}, }; consumeInputEventEntries(expectedEntries, frameTime); } /** * Mouse pointer coordinates are resampled. */ TEST_F(TouchResamplingTest, MouseEventIsResampled) { std::chrono::nanoseconds frameTime; std::vector<InputEventEntry> entries, expectedEntries; // Initial ACTION_DOWN should be separate, because the first consume event will only return // InputEvent with a single action. entries = { // id x y {0ms, {{0, 10, 20, .toolType = ToolType::MOUSE}}, AMOTION_EVENT_ACTION_DOWN}, }; publishInputEventEntries(entries); frameTime = 5ms; expectedEntries = { // id x y {0ms, {{0, 10, 20, .toolType = ToolType::MOUSE}}, AMOTION_EVENT_ACTION_DOWN}, }; consumeInputEventEntries(expectedEntries, frameTime); // Two ACTION_MOVE events 10 ms apart that move in X direction and stay still in Y entries = { // id x y {10ms, {{0, 20, 30, .toolType = ToolType::MOUSE}}, AMOTION_EVENT_ACTION_MOVE}, {20ms, {{0, 30, 30, .toolType = ToolType::MOUSE}}, AMOTION_EVENT_ACTION_MOVE}, }; publishInputEventEntries(entries); frameTime = 35ms; expectedEntries = { // id x y {10ms, {{0, 20, 30, .toolType = ToolType::MOUSE}}, AMOTION_EVENT_ACTION_MOVE}, {20ms, {{0, 30, 30, .toolType = ToolType::MOUSE}}, AMOTION_EVENT_ACTION_MOVE}, {25ms, {{0, 35, 30, .toolType = ToolType::MOUSE, .isResampled = true}}, AMOTION_EVENT_ACTION_MOVE}, }; consumeInputEventEntries(expectedEntries, frameTime); } /** * Motion events with palm tool type are not resampled. */ TEST_F(TouchResamplingTest, PalmEventIsNotResampled) { std::chrono::nanoseconds frameTime; std::vector<InputEventEntry> entries, expectedEntries; // Initial ACTION_DOWN should be separate, because the first consume event will only return // InputEvent with a single action. entries = { // id x y {0ms, {{0, 10, 20, .toolType = ToolType::PALM}}, AMOTION_EVENT_ACTION_DOWN}, }; publishInputEventEntries(entries); frameTime = 5ms; expectedEntries = { // id x y {0ms, {{0, 10, 20, .toolType = ToolType::PALM}}, AMOTION_EVENT_ACTION_DOWN}, }; consumeInputEventEntries(expectedEntries, frameTime); // Two ACTION_MOVE events 10 ms apart that move in X direction and stay still in Y entries = { // id x y {10ms, {{0, 20, 30, .toolType = ToolType::PALM}}, AMOTION_EVENT_ACTION_MOVE}, {20ms, {{0, 30, 30, .toolType = ToolType::PALM}}, AMOTION_EVENT_ACTION_MOVE}, }; publishInputEventEntries(entries); frameTime = 35ms; expectedEntries = { // id x y {10ms, {{0, 20, 30, .toolType = ToolType::PALM}}, AMOTION_EVENT_ACTION_MOVE}, {20ms, {{0, 30, 30, .toolType = ToolType::PALM}}, AMOTION_EVENT_ACTION_MOVE}, }; consumeInputEventEntries(expectedEntries, frameTime); } /** * Event should not be resampled when sample time is equal to event time. */ Loading Loading
libs/input/InputConsumer.cpp +26 −18 Original line number Diff line number Diff line Loading @@ -181,7 +181,8 @@ inline bool isPointerEvent(int32_t source) { } bool shouldResampleTool(ToolType toolType) { return toolType == ToolType::FINGER || toolType == ToolType::UNKNOWN; return toolType == ToolType::FINGER || toolType == ToolType::MOUSE || toolType == ToolType::STYLUS || toolType == ToolType::UNKNOWN; } } // namespace Loading Loading @@ -592,6 +593,11 @@ void InputConsumer::resampleTouchState(nsecs_t sampleTime, MotionEvent* event, ALOGD_IF(debugResampling(), "Not resampled, missing id %d", id); return; } if (!shouldResampleTool(event->getToolType(i))) { ALOGD_IF(debugResampling(), "Not resampled, containing unsupported tool type at pointer %d", id); return; } } // Find the data to use for resampling. Loading Loading @@ -639,10 +645,18 @@ void InputConsumer::resampleTouchState(nsecs_t sampleTime, MotionEvent* event, } if (current->eventTime == sampleTime) { // Prevents having 2 events with identical times and coordinates. ALOGD_IF(debugResampling(), "Not resampled, 2 events with identical times."); return; } for (size_t i = 0; i < pointerCount; i++) { uint32_t id = event->getPointerId(i); if (!other->idBits.hasBit(id)) { ALOGD_IF(debugResampling(), "Not resampled, the other doesn't have pointer id %d.", id); return; } } // Resample touch coordinates. History oldLastResample; oldLastResample.initializeFrom(touchState.lastResample); Loading Loading @@ -670,7 +684,6 @@ void InputConsumer::resampleTouchState(nsecs_t sampleTime, MotionEvent* event, const PointerCoords& currentCoords = current->getPointerById(id); resampledCoords = currentCoords; resampledCoords.isResampled = true; if (other->idBits.hasBit(id) && shouldResampleTool(event->getToolType(i))) { const PointerCoords& otherCoords = other->getPointerById(id); resampledCoords.setAxisValue(AMOTION_EVENT_AXIS_X, lerp(currentCoords.getX(), otherCoords.getX(), alpha)); Loading @@ -681,11 +694,6 @@ void InputConsumer::resampleTouchState(nsecs_t sampleTime, MotionEvent* event, "other (%0.3f, %0.3f), alpha %0.3f", id, resampledCoords.getX(), resampledCoords.getY(), currentCoords.getX(), currentCoords.getY(), otherCoords.getX(), otherCoords.getY(), alpha); } else { ALOGD_IF(debugResampling(), "[%d] - out (%0.3f, %0.3f), cur (%0.3f, %0.3f)", id, resampledCoords.getX(), resampledCoords.getY(), currentCoords.getX(), currentCoords.getY()); } } event->addSample(sampleTime, touchState.lastResample.pointers); Loading
libs/input/tests/TouchResampling_test.cpp +80 −5 Original line number Diff line number Diff line Loading @@ -297,10 +297,9 @@ TEST_F(TouchResamplingTest, EventIsResampledWithDifferentId) { } /** * Stylus pointer coordinates are not resampled, but an event is still generated for the batch with * a resampled timestamp and should be marked as such. * Stylus pointer coordinates are resampled. */ TEST_F(TouchResamplingTest, StylusCoordinatesNotResampledFor) { TEST_F(TouchResamplingTest, StylusEventIsResampled) { std::chrono::nanoseconds frameTime; std::vector<InputEventEntry> entries, expectedEntries; Loading Loading @@ -330,14 +329,90 @@ TEST_F(TouchResamplingTest, StylusCoordinatesNotResampledFor) { // id x y {10ms, {{0, 20, 30, .toolType = ToolType::STYLUS}}, AMOTION_EVENT_ACTION_MOVE}, {20ms, {{0, 30, 30, .toolType = ToolType::STYLUS}}, AMOTION_EVENT_ACTION_MOVE}, // A resampled event is generated, but the stylus coordinates are not resampled. {25ms, {{0, 30, 30, .toolType = ToolType::STYLUS, .isResampled = true}}, {{0, 35, 30, .toolType = ToolType::STYLUS, .isResampled = true}}, AMOTION_EVENT_ACTION_MOVE}, }; consumeInputEventEntries(expectedEntries, frameTime); } /** * Mouse pointer coordinates are resampled. */ TEST_F(TouchResamplingTest, MouseEventIsResampled) { std::chrono::nanoseconds frameTime; std::vector<InputEventEntry> entries, expectedEntries; // Initial ACTION_DOWN should be separate, because the first consume event will only return // InputEvent with a single action. entries = { // id x y {0ms, {{0, 10, 20, .toolType = ToolType::MOUSE}}, AMOTION_EVENT_ACTION_DOWN}, }; publishInputEventEntries(entries); frameTime = 5ms; expectedEntries = { // id x y {0ms, {{0, 10, 20, .toolType = ToolType::MOUSE}}, AMOTION_EVENT_ACTION_DOWN}, }; consumeInputEventEntries(expectedEntries, frameTime); // Two ACTION_MOVE events 10 ms apart that move in X direction and stay still in Y entries = { // id x y {10ms, {{0, 20, 30, .toolType = ToolType::MOUSE}}, AMOTION_EVENT_ACTION_MOVE}, {20ms, {{0, 30, 30, .toolType = ToolType::MOUSE}}, AMOTION_EVENT_ACTION_MOVE}, }; publishInputEventEntries(entries); frameTime = 35ms; expectedEntries = { // id x y {10ms, {{0, 20, 30, .toolType = ToolType::MOUSE}}, AMOTION_EVENT_ACTION_MOVE}, {20ms, {{0, 30, 30, .toolType = ToolType::MOUSE}}, AMOTION_EVENT_ACTION_MOVE}, {25ms, {{0, 35, 30, .toolType = ToolType::MOUSE, .isResampled = true}}, AMOTION_EVENT_ACTION_MOVE}, }; consumeInputEventEntries(expectedEntries, frameTime); } /** * Motion events with palm tool type are not resampled. */ TEST_F(TouchResamplingTest, PalmEventIsNotResampled) { std::chrono::nanoseconds frameTime; std::vector<InputEventEntry> entries, expectedEntries; // Initial ACTION_DOWN should be separate, because the first consume event will only return // InputEvent with a single action. entries = { // id x y {0ms, {{0, 10, 20, .toolType = ToolType::PALM}}, AMOTION_EVENT_ACTION_DOWN}, }; publishInputEventEntries(entries); frameTime = 5ms; expectedEntries = { // id x y {0ms, {{0, 10, 20, .toolType = ToolType::PALM}}, AMOTION_EVENT_ACTION_DOWN}, }; consumeInputEventEntries(expectedEntries, frameTime); // Two ACTION_MOVE events 10 ms apart that move in X direction and stay still in Y entries = { // id x y {10ms, {{0, 20, 30, .toolType = ToolType::PALM}}, AMOTION_EVENT_ACTION_MOVE}, {20ms, {{0, 30, 30, .toolType = ToolType::PALM}}, AMOTION_EVENT_ACTION_MOVE}, }; publishInputEventEntries(entries); frameTime = 35ms; expectedEntries = { // id x y {10ms, {{0, 20, 30, .toolType = ToolType::PALM}}, AMOTION_EVENT_ACTION_MOVE}, {20ms, {{0, 30, 30, .toolType = ToolType::PALM}}, AMOTION_EVENT_ACTION_MOVE}, }; consumeInputEventEntries(expectedEntries, frameTime); } /** * Event should not be resampled when sample time is equal to event time. */ Loading