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

Commit 1411cf8b authored by Arpit Singh's avatar Arpit Singh Committed by Android (Google) Code Review
Browse files

Merge changes Ie02dbcb3,I8195406c into main

* changes:
  Wait till next SYN_REPORT to repopulate device state after SYN_DROPPED
  Sync MT slots on reset and buffer overflow
parents 044d04a9 1c3d855f
Loading
Loading
Loading
Loading
+26 −4
Original line number Diff line number Diff line
@@ -810,14 +810,20 @@ void EventHub::Device::trackInputEvent(const struct input_event& event) {
        case EV_SYN: {
            switch (event.code) {
                case SYN_REPORT:
                    if (currentFrameDropped) {
                        // To recover after a SYN_DROPPED, we need to query the state of the device
                        // to synchronize our device state with the kernel's to account for the
                        // dropped events on receiving the next SYN_REPORT.
                        // Note we don't drop the SYN_REPORT at this point but it is used by the
                        // InputDevice to reset and repopulate mapper state
                        readDeviceState();
                        currentFrameDropped = false;
                    }
                    break;
                case SYN_DROPPED:
                    // When we receive SYN_DROPPED, all events in the current frame should be
                    // dropped. We query the state of the device to synchronize our device state
                    // with the kernel's to account for the dropped events.
                    // dropped up to and including next SYN_REPORT
                    currentFrameDropped = true;
                    readDeviceState();
                    break;
                default:
                    break;
@@ -1141,6 +1147,22 @@ status_t EventHub::getAbsoluteAxisValue(int32_t deviceId, int32_t axis, int32_t*
    return OK;
}

base::Result<std::vector<int32_t>> EventHub::getMtSlotValues(int32_t deviceId, int32_t axis,
                                                             size_t slotCount) const {
    std::scoped_lock _l(mLock);
    const Device* device = getDeviceLocked(deviceId);
    if (device == nullptr || !device->hasValidFd() || !device->absBitmask.test(axis)) {
        return base::ResultError("device problem or axis not supported", NAME_NOT_FOUND);
    }
    std::vector<int32_t> outValues(slotCount + 1);
    outValues[0] = axis;
    const size_t bufferSize = outValues.size() * sizeof(int32_t);
    if (ioctl(device->fd, EVIOCGMTSLOTS(bufferSize), outValues.data()) != OK) {
        return base::ErrnoError();
    }
    return std::move(outValues);
}

bool EventHub::markSupportedKeyCodes(int32_t deviceId, const std::vector<int32_t>& keyCodes,
                                     uint8_t* outFlags) const {
    std::scoped_lock _l(mLock);
+1 −1
Original line number Diff line number Diff line
@@ -350,6 +350,7 @@ std::list<NotifyArgs> InputDevice::process(const RawEvent* rawEvents, size_t cou

        if (mDropUntilNextSync) {
            if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
                out += reset(rawEvent->when);
                mDropUntilNextSync = false;
                ALOGD_IF(debugRawEvents(), "Recovered from input event buffer overrun.");
            } else {
@@ -359,7 +360,6 @@ std::list<NotifyArgs> InputDevice::process(const RawEvent* rawEvents, size_t cou
        } else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_DROPPED) {
            ALOGI("Detected input event buffer overrun for device %s.", getName().c_str());
            mDropUntilNextSync = true;
            out += reset(rawEvent->when);
        } else {
            for_each_mapper_in_subdevice(rawEvent->deviceId, [&](InputMapper& mapper) {
                out += mapper.process(rawEvent);
+6 −0
Original line number Diff line number Diff line
@@ -336,6 +336,10 @@ public:
    virtual int32_t getSwitchState(int32_t deviceId, int32_t sw) const = 0;
    virtual status_t getAbsoluteAxisValue(int32_t deviceId, int32_t axis,
                                          int32_t* outValue) const = 0;
    /* Query Multi-Touch slot values for an axis. Returns error or an 1 indexed array of size
     * (slotCount + 1). The value at the 0 index is set to queried axis. */
    virtual base::Result<std::vector<int32_t>> getMtSlotValues(int32_t deviceId, int32_t axis,
                                                               size_t slotCount) const = 0;
    virtual int32_t getKeyCodeForKeyLocation(int32_t deviceId, int32_t locationKeyCode) const = 0;

    /*
@@ -552,6 +556,8 @@ public:
                                     int32_t locationKeyCode) const override final;
    status_t getAbsoluteAxisValue(int32_t deviceId, int32_t axis,
                                  int32_t* outValue) const override final;
    base::Result<std::vector<int32_t>> getMtSlotValues(int32_t deviceId, int32_t axis,
                                                       size_t slotCount) const override final;

    bool markSupportedKeyCodes(int32_t deviceId, const std::vector<int32_t>& keyCodes,
                               uint8_t* outFlags) const override final;
+4 −0
Original line number Diff line number Diff line
@@ -372,6 +372,10 @@ public:
    inline status_t getAbsoluteAxisValue(int32_t code, int32_t* outValue) const {
        return mEventHub->getAbsoluteAxisValue(mId, code, outValue);
    }
    inline base::Result<std::vector<int32_t>> getMtSlotValues(int32_t axis,
                                                              size_t slotCount) const {
        return mEventHub->getMtSlotValues(mId, axis, slotCount);
    }
    inline bool markSupportedKeyCodes(const std::vector<int32_t>& keyCodes,
                                      uint8_t* outFlags) const {
        return mEventHub->markSupportedKeyCodes(mId, keyCodes, outFlags);
+2 −6
Original line number Diff line number Diff line
@@ -35,12 +35,8 @@ MultiTouchInputMapper::MultiTouchInputMapper(InputDeviceContext& deviceContext,
MultiTouchInputMapper::~MultiTouchInputMapper() {}

std::list<NotifyArgs> MultiTouchInputMapper::reset(nsecs_t when) {
    // The evdev multi-touch protocol does not allow userspace applications to query the initial or
    // current state of the pointers at any time. This means if we clear our accumulated state when
    // resetting the input mapper, there's no way to rebuild the full initial state of the pointers.
    // We can only wait for updates to all the pointers and axes. Rather than clearing the state and
    // rebuilding the state from scratch, we work around this kernel API limitation by never
    // fully clearing any state specific to the multi-touch protocol.
    mPointerIdBits.clear();
    mMultiTouchMotionAccumulator.reset(mDeviceContext);
    return TouchInputMapper::reset(when);
}

Loading