Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dd438e2a authored by Vladimir Komsiyski's avatar Vladimir Komsiyski
Browse files

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
parent 8faf3d40
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -122,4 +122,11 @@ private:
    bool handleStylusUp(uint16_t tool, std::chrono::nanoseconds eventTime);
};

class VirtualRotaryEncoder : public VirtualInputDevice {
public:
    VirtualRotaryEncoder(android::base::unique_fd fd);
    virtual ~VirtualRotaryEncoder() override;
    bool writeScrollEvent(float scrollAmount, std::chrono::nanoseconds eventTime);
};

} // namespace android
+11 −0
Original line number Diff line number Diff line
@@ -509,4 +509,15 @@ bool VirtualStylus::handleStylusUp(uint16_t tool, std::chrono::nanoseconds event
    return true;
}

// --- VirtualRotaryEncoder ---
VirtualRotaryEncoder::VirtualRotaryEncoder(unique_fd fd) : VirtualInputDevice(std::move(fd)) {}

VirtualRotaryEncoder::~VirtualRotaryEncoder() {}

bool VirtualRotaryEncoder::writeScrollEvent(float scrollAmount,
                                            std::chrono::nanoseconds eventTime) {
    return writeInputEvent(EV_REL, REL_WHEEL, static_cast<int32_t>(scrollAmount), eventTime) &&
            writeInputEvent(EV_SYN, SYN_REPORT, 0, eventTime);
}

} // namespace android
+1 −0
Original line number Diff line number Diff line
@@ -78,6 +78,7 @@ cc_defaults {
    name: "libinputreader_defaults",
    srcs: [":libinputreader_sources"],
    shared_libs: [
        "android.companion.virtualdevice.flags-aconfig-cc-host",
        "libbase",
        "libcap",
        "libcrypto",
+10 −0
Original line number Diff line number Diff line
@@ -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 @@ using android::base::StringPrintf;

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 @@ void EventHub::openDeviceLocked(const std::string& devicePath) {
        }
    }

    // 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(),
+12 −8
Original line number Diff line number Diff line
@@ -84,6 +84,11 @@ std::list<NotifyArgs> RotaryEncoderInputMapper::reconfigure(nsecs_t when,
        }
    }
    if (!changes.any() || changes.test(InputReaderConfiguration::Change::DISPLAY_INFO)) {
        if (getDeviceContext().getAssociatedViewport()) {
            mDisplayId = getDeviceContext().getAssociatedViewport()->displayId;
            mOrientation = getDeviceContext().getAssociatedViewport()->orientation;
        } else {
            mDisplayId = ui::LogicalDisplayId::INVALID;
            std::optional<DisplayViewport> internalViewport =
                    config.getDisplayViewportByType(ViewportType::INTERNAL);
            if (internalViewport) {
@@ -92,6 +97,7 @@ std::list<NotifyArgs> RotaryEncoderInputMapper::reconfigure(nsecs_t when,
                mOrientation = ui::ROTATION_0;
            }
        }
    }
    return out;
}

@@ -124,8 +130,6 @@ std::list<NotifyArgs> RotaryEncoderInputMapper::sync(nsecs_t when, nsecs_t readT
    // 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 @@ std::list<NotifyArgs> RotaryEncoderInputMapper::sync(nsecs_t when, nsecs_t readT

        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,
Loading