Support high-resolution scroll
VirtualMouse currently supports -1f to 1f float scroll values,
but it worked for integer values only as input framework supported
only REL_HWHEEL and REL_WHEEL events. With the introduction of
high-res scroll event support (REL_HWHEEL_HI_RES and REL_WHEEL_HI_RES),
granular mouse scrolling can be done, and VirtualMouse scroll API
would work for all float values.
Flag: android.companion.virtualdevice.flags.high_resolution_scroll
Test: atest VirtualMouseTest
Bug: 335160780
Change-Id: I7b13ac1722b6fd31736fe1c0117d4de6e838261a
diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.h b/services/inputflinger/reader/mapper/TouchInputMapper.h
index beab6e7..87b72af 100644
--- a/services/inputflinger/reader/mapper/TouchInputMapper.h
+++ b/services/inputflinger/reader/mapper/TouchInputMapper.h
@@ -339,8 +339,8 @@
int32_t buttonState{};
// Scroll state.
- int32_t rawVScroll{};
- int32_t rawHScroll{};
+ float rawVScroll{};
+ float rawHScroll{};
inline void clear() { *this = RawState(); }
};
diff --git a/services/inputflinger/reader/mapper/accumulator/CursorScrollAccumulator.cpp b/services/inputflinger/reader/mapper/accumulator/CursorScrollAccumulator.cpp
index f85cab2..06315e2 100644
--- a/services/inputflinger/reader/mapper/accumulator/CursorScrollAccumulator.cpp
+++ b/services/inputflinger/reader/mapper/accumulator/CursorScrollAccumulator.cpp
@@ -16,18 +16,29 @@
#include "CursorScrollAccumulator.h"
+#include <android_companion_virtualdevice_flags.h>
#include "EventHub.h"
#include "InputDevice.h"
namespace android {
-CursorScrollAccumulator::CursorScrollAccumulator() : mHaveRelWheel(false), mHaveRelHWheel(false) {
+namespace vd_flags = android::companion::virtualdevice::flags;
+
+CursorScrollAccumulator::CursorScrollAccumulator()
+ : mHaveRelWheel(false),
+ mHaveRelHWheel(false),
+ mHaveRelWheelHighRes(false),
+ mHaveRelHWheelHighRes(false) {
clearRelativeAxes();
}
void CursorScrollAccumulator::configure(InputDeviceContext& deviceContext) {
mHaveRelWheel = deviceContext.hasRelativeAxis(REL_WHEEL);
mHaveRelHWheel = deviceContext.hasRelativeAxis(REL_HWHEEL);
+ if (vd_flags::high_resolution_scroll()) {
+ mHaveRelWheelHighRes = deviceContext.hasRelativeAxis(REL_WHEEL_HI_RES);
+ mHaveRelHWheelHighRes = deviceContext.hasRelativeAxis(REL_HWHEEL_HI_RES);
+ }
}
void CursorScrollAccumulator::reset(InputDeviceContext& deviceContext) {
@@ -42,11 +53,31 @@
void CursorScrollAccumulator::process(const RawEvent& rawEvent) {
if (rawEvent.type == EV_REL) {
switch (rawEvent.code) {
+ case REL_WHEEL_HI_RES:
+ if (mHaveRelWheelHighRes) {
+ mRelWheel = rawEvent.value /
+ static_cast<float>(kEvdevMouseHighResScrollUnitsPerDetent);
+ }
+ break;
+ case REL_HWHEEL_HI_RES:
+ if (mHaveRelHWheelHighRes) {
+ mRelHWheel = rawEvent.value /
+ static_cast<float>(kEvdevMouseHighResScrollUnitsPerDetent);
+ }
+ break;
case REL_WHEEL:
- mRelWheel = rawEvent.value;
+ // We should ignore regular scroll events, if we have already have high-res scroll
+ // enabled.
+ if (!mHaveRelWheelHighRes) {
+ mRelWheel = rawEvent.value;
+ }
break;
case REL_HWHEEL:
- mRelHWheel = rawEvent.value;
+ // We should ignore regular scroll events, if we have already have high-res scroll
+ // enabled.
+ if (!mHaveRelHWheelHighRes) {
+ mRelHWheel = rawEvent.value;
+ }
break;
}
}
diff --git a/services/inputflinger/reader/mapper/accumulator/CursorScrollAccumulator.h b/services/inputflinger/reader/mapper/accumulator/CursorScrollAccumulator.h
index e563620..6990d20 100644
--- a/services/inputflinger/reader/mapper/accumulator/CursorScrollAccumulator.h
+++ b/services/inputflinger/reader/mapper/accumulator/CursorScrollAccumulator.h
@@ -24,7 +24,6 @@
struct RawEvent;
/* Keeps track of cursor scrolling motions. */
-
class CursorScrollAccumulator {
public:
CursorScrollAccumulator();
@@ -39,17 +38,19 @@
inline int32_t getRelativeX() const { return mRelX; }
inline int32_t getRelativeY() const { return mRelY; }
- inline int32_t getRelativeVWheel() const { return mRelWheel; }
- inline int32_t getRelativeHWheel() const { return mRelHWheel; }
+ inline float getRelativeVWheel() const { return mRelWheel; }
+ inline float getRelativeHWheel() const { return mRelHWheel; }
private:
bool mHaveRelWheel;
bool mHaveRelHWheel;
+ bool mHaveRelWheelHighRes;
+ bool mHaveRelHWheelHighRes;
int32_t mRelX;
int32_t mRelY;
- int32_t mRelWheel;
- int32_t mRelHWheel;
+ float mRelWheel;
+ float mRelHWheel;
void clearRelativeAxes();
};