Virtual rotary encoder native support
- detect rotary encoder input devices if they have a single scroll
axis and nothing else
- make the rotary mapper display-aware as the virtual rotary is
constrained to a single virtual display, just like the other
virtual input devices
Fix: 320328752
Test: atest inputflinger_tests
Test: see CTS in topic
Flag: android.companion.virtualdevice.flags.virtual_rotary
Change-Id: I5581013d06708cbcc2c3ac8a622cd259aea8a9b4
diff --git a/services/inputflinger/reader/Android.bp b/services/inputflinger/reader/Android.bp
index e76b648..b2f15b4 100644
--- a/services/inputflinger/reader/Android.bp
+++ b/services/inputflinger/reader/Android.bp
@@ -78,6 +78,7 @@
name: "libinputreader_defaults",
srcs: [":libinputreader_sources"],
shared_libs: [
+ "android.companion.virtualdevice.flags-aconfig-cc-host",
"libbase",
"libcap",
"libcrypto",
diff --git a/services/inputflinger/reader/EventHub.cpp b/services/inputflinger/reader/EventHub.cpp
index fe70a51..540f55d 100644
--- a/services/inputflinger/reader/EventHub.cpp
+++ b/services/inputflinger/reader/EventHub.cpp
@@ -33,6 +33,8 @@
#include <sys/sysmacros.h>
#include <unistd.h>
+#include <android_companion_virtualdevice_flags.h>
+
#define LOG_TAG "EventHub"
// #define LOG_NDEBUG 0
@@ -68,6 +70,8 @@
namespace android {
+namespace vd_flags = android::companion::virtualdevice::flags;
+
using namespace ftl::flag_operators;
static const char* DEVICE_INPUT_PATH = "/dev/input";
@@ -2503,6 +2507,12 @@
}
}
+ // See if the device is a rotary encoder with a single scroll axis and nothing else.
+ if (vd_flags::virtual_rotary() && device->classes == ftl::Flags<InputDeviceClass>(0) &&
+ device->relBitmask.test(REL_WHEEL) && !device->relBitmask.test(REL_HWHEEL)) {
+ device->classes |= InputDeviceClass::ROTARY_ENCODER;
+ }
+
// If the device isn't recognized as something we handle, don't monitor it.
if (device->classes == ftl::Flags<InputDeviceClass>(0)) {
ALOGV("Dropping device: id=%d, path='%s', name='%s'", deviceId, devicePath.c_str(),
diff --git a/services/inputflinger/reader/mapper/RotaryEncoderInputMapper.cpp b/services/inputflinger/reader/mapper/RotaryEncoderInputMapper.cpp
index 27ff52f..20fd359 100644
--- a/services/inputflinger/reader/mapper/RotaryEncoderInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/RotaryEncoderInputMapper.cpp
@@ -84,12 +84,18 @@
}
}
if (!changes.any() || changes.test(InputReaderConfiguration::Change::DISPLAY_INFO)) {
- std::optional<DisplayViewport> internalViewport =
- config.getDisplayViewportByType(ViewportType::INTERNAL);
- if (internalViewport) {
- mOrientation = internalViewport->orientation;
+ if (getDeviceContext().getAssociatedViewport()) {
+ mDisplayId = getDeviceContext().getAssociatedViewport()->displayId;
+ mOrientation = getDeviceContext().getAssociatedViewport()->orientation;
} else {
- mOrientation = ui::ROTATION_0;
+ mDisplayId = ui::LogicalDisplayId::INVALID;
+ std::optional<DisplayViewport> internalViewport =
+ config.getDisplayViewportByType(ViewportType::INTERNAL);
+ if (internalViewport) {
+ mOrientation = internalViewport->orientation;
+ } else {
+ mOrientation = ui::ROTATION_0;
+ }
}
}
return out;
@@ -124,8 +130,6 @@
// Send motion event.
if (scrolled) {
int32_t metaState = getContext()->getGlobalMetaState();
- // This is not a pointer, so it's not associated with a display.
- ui::LogicalDisplayId displayId = ui::LogicalDisplayId::INVALID;
if (mOrientation == ui::ROTATION_180) {
scroll = -scroll;
@@ -147,7 +151,7 @@
out.push_back(
NotifyMotionArgs(getContext()->getNextId(), when, readTime, getDeviceId(), mSource,
- displayId, policyFlags, AMOTION_EVENT_ACTION_SCROLL, 0, 0,
+ mDisplayId, policyFlags, AMOTION_EVENT_ACTION_SCROLL, 0, 0,
metaState, /*buttonState=*/0, MotionClassification::NONE,
AMOTION_EVENT_EDGE_FLAG_NONE, 1, &pointerProperties,
&pointerCoords, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
diff --git a/services/inputflinger/reader/mapper/RotaryEncoderInputMapper.h b/services/inputflinger/reader/mapper/RotaryEncoderInputMapper.h
index 14c540b..7e80415 100644
--- a/services/inputflinger/reader/mapper/RotaryEncoderInputMapper.h
+++ b/services/inputflinger/reader/mapper/RotaryEncoderInputMapper.h
@@ -47,6 +47,7 @@
int32_t mSource;
float mScalingFactor;
ui::Rotation mOrientation;
+ ui::LogicalDisplayId mDisplayId = ui::LogicalDisplayId::INVALID;
std::unique_ptr<SlopController> mSlopController;
explicit RotaryEncoderInputMapper(InputDeviceContext& deviceContext,