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

Commit de231db0 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge changes I2a4359de,I08376f69 into main

* changes:
  Revert "Disable stylus integration tests temporarily"
  EventHub: Track the global key and switch states for enabled devices
parents 2fc656d7 39d60aac
Loading
Loading
Loading
Loading
+87 −37
Original line number Diff line number Diff line
@@ -538,7 +538,8 @@ EventHub::Device::Device(int fd, int32_t id, std::string path, InputDeviceIdenti
        associatedDevice(std::move(assocDev)),
        controllerNumber(0),
        enabled(true),
        isVirtual(fd < 0) {}
        isVirtual(fd < 0),
        currentFrameDropped(false) {}

EventHub::Device::~Device() {
    close();
@@ -612,6 +613,18 @@ void EventHub::Device::configureFd() {
    }
    bool usingClockIoctl = !ioctl(fd, EVIOCSCLOCKID, &clockId);
    ALOGI("usingClockIoctl=%s", toString(usingClockIoctl));

    // Query the initial state of keys and switches, which is tracked by EventHub.
    readDeviceState();
}

void EventHub::Device::readDeviceState() {
    if (readDeviceBitMask(EVIOCGKEY(0), keyState) < 0) {
        ALOGD("Unable to query the global key state for %s: %s", path.c_str(), strerror(errno));
    }
    if (readDeviceBitMask(EVIOCGSW(0), swState) < 0) {
        ALOGD("Unable to query the global switch state for %s: %s", path.c_str(), strerror(errno));
    }
}

bool EventHub::Device::hasKeycodeLocked(int keycode) const {
@@ -729,6 +742,48 @@ status_t EventHub::Device::mapLed(int32_t led, int32_t* outScanCode) const {
    return NAME_NOT_FOUND;
}

void EventHub::Device::trackInputEvent(const struct input_event& event) {
    switch (event.type) {
        case EV_KEY: {
            LOG_ALWAYS_FATAL_IF(!currentFrameDropped &&
                                        !keyState.set(static_cast<size_t>(event.code),
                                                      event.value != 0),
                                "%s: received invalid EV_KEY event code: %s", __func__,
                                InputEventLookup::getLinuxEvdevLabel(EV_KEY, event.code, 1)
                                        .code.c_str());
            break;
        }
        case EV_SW: {
            LOG_ALWAYS_FATAL_IF(!currentFrameDropped &&
                                        !swState.set(static_cast<size_t>(event.code),
                                                     event.value != 0),
                                "%s: received invalid EV_SW event code: %s", __func__,
                                InputEventLookup::getLinuxEvdevLabel(EV_SW, event.code, 1)
                                        .code.c_str());
            break;
        }
        case EV_SYN: {
            switch (event.code) {
                case SYN_REPORT:
                    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.
                    currentFrameDropped = true;
                    readDeviceState();
                    break;
                default:
                    break;
            }
            break;
        }
        default:
            break;
    }
}

/**
 * Get the capabilities for the current process.
 * Crashes the system if unable to create / check / destroy the capabilities object.
@@ -962,39 +1017,35 @@ bool EventHub::hasMscEvent(int32_t deviceId, int mscEvent) const {
}

int32_t EventHub::getScanCodeState(int32_t deviceId, int32_t scanCode) const {
    if (scanCode >= 0 && scanCode <= KEY_MAX) {
        std::scoped_lock _l(mLock);

        Device* device = getDeviceLocked(deviceId);
        if (device != nullptr && device->hasValidFd() && device->keyBitmask.test(scanCode)) {
            if (device->readDeviceBitMask(EVIOCGKEY(0), device->keyState) >= 0) {
                return device->keyState.test(scanCode) ? AKEY_STATE_DOWN : AKEY_STATE_UP;
            }
        }
    if (scanCode < 0 || scanCode > KEY_MAX) {
        return AKEY_STATE_UNKNOWN;
    }
    std::scoped_lock _l(mLock);
    const Device* device = getDeviceLocked(deviceId);
    if (device == nullptr || !device->hasValidFd() || !device->keyBitmask.test(scanCode)) {
        return AKEY_STATE_UNKNOWN;
    }
    return device->keyState.test(scanCode) ? AKEY_STATE_DOWN : AKEY_STATE_UP;
}

int32_t EventHub::getKeyCodeState(int32_t deviceId, int32_t keyCode) const {
    std::scoped_lock _l(mLock);

    Device* device = getDeviceLocked(deviceId);
    if (device != nullptr && device->hasValidFd() && device->keyMap.haveKeyLayout()) {
        std::vector<int32_t> scanCodes = device->keyMap.keyLayoutMap->findScanCodesForKey(keyCode);
        if (scanCodes.size() != 0) {
            if (device->readDeviceBitMask(EVIOCGKEY(0), device->keyState) >= 0) {
                for (size_t i = 0; i < scanCodes.size(); i++) {
                    int32_t sc = scanCodes[i];
                    if (sc >= 0 && sc <= KEY_MAX && device->keyState.test(sc)) {
                        return AKEY_STATE_DOWN;
                    }
                }
                return AKEY_STATE_UP;
            }
        }
    const Device* device = getDeviceLocked(deviceId);
    if (device == nullptr || !device->hasValidFd() || !device->keyMap.haveKeyLayout()) {
        return AKEY_STATE_UNKNOWN;
    }
    const std::vector<int32_t> scanCodes =
            device->keyMap.keyLayoutMap->findScanCodesForKey(keyCode);
    if (scanCodes.empty()) {
        return AKEY_STATE_UNKNOWN;
    }
    return std::any_of(scanCodes.begin(), scanCodes.end(),
                       [&device](const int32_t sc) {
                           return sc >= 0 && sc <= KEY_MAX && device->keyState.test(sc);
                       })
            ? AKEY_STATE_DOWN
            : AKEY_STATE_UP;
}

int32_t EventHub::getKeyCodeForKeyLocation(int32_t deviceId, int32_t locationKeyCode) const {
    std::scoped_lock _l(mLock);
@@ -1037,18 +1088,16 @@ int32_t EventHub::getKeyCodeForKeyLocation(int32_t deviceId, int32_t locationKey
}

int32_t EventHub::getSwitchState(int32_t deviceId, int32_t sw) const {
    if (sw >= 0 && sw <= SW_MAX) {
        std::scoped_lock _l(mLock);

        Device* device = getDeviceLocked(deviceId);
        if (device != nullptr && device->hasValidFd() && device->swBitmask.test(sw)) {
            if (device->readDeviceBitMask(EVIOCGSW(0), device->swState) >= 0) {
                return device->swState.test(sw) ? AKEY_STATE_DOWN : AKEY_STATE_UP;
            }
        }
    if (sw < 0 || sw > SW_MAX) {
        return AKEY_STATE_UNKNOWN;
    }
    std::scoped_lock _l(mLock);
    const Device* device = getDeviceLocked(deviceId);
    if (device == nullptr || !device->hasValidFd() || !device->swBitmask.test(sw)) {
        return AKEY_STATE_UNKNOWN;
    }
    return device->swState.test(sw) ? AKEY_STATE_DOWN : AKEY_STATE_UP;
}

status_t EventHub::getAbsoluteAxisValue(int32_t deviceId, int32_t axis, int32_t* outValue) const {
    *outValue = 0;
@@ -1922,6 +1971,7 @@ std::vector<RawEvent> EventHub::getEvents(int timeoutMillis) {
                    const size_t count = size_t(readSize) / sizeof(struct input_event);
                    for (size_t i = 0; i < count; i++) {
                        struct input_event& iev = readBuffer[i];
                        device->trackInputEvent(iev);
                        events.push_back({
                                .when = processEventTimestamp(iev),
                                .readTime = systemTime(SYSTEM_TIME_MONOTONIC),
+15 −1
Original line number Diff line number Diff line
@@ -411,7 +411,17 @@ public:
     * Note the parameter "bit" is an index to the bit, 0 <= bit < BITS.
     */
    inline bool test(size_t bit) const {
        return (bit < BITS) ? mData[bit / WIDTH].test(bit % WIDTH) : false;
        return (bit < BITS) && mData[bit / WIDTH].test(bit % WIDTH);
    }
    /* Sets the given bit in the bit array to given value.
     * Returns true if the given bit is a valid index and thus was set successfully.
     */
    inline bool set(size_t bit, bool value) {
        if (bit >= BITS) {
            return false;
        }
        mData[bit / WIDTH].set(bit % WIDTH, value);
        return true;
    }
    /* Returns total number of bytes needed for the array */
    inline size_t bytes() { return (BITS + CHAR_BIT - 1) / CHAR_BIT; }
@@ -653,6 +663,10 @@ private:
        void setLedForControllerLocked();
        status_t mapLed(int32_t led, int32_t* outScanCode) const;
        void setLedStateLocked(int32_t led, bool on);

        bool currentFrameDropped;
        void trackInputEvent(const struct input_event& event);
        void readDeviceState();
    };

    /**
+8 −8
Original line number Diff line number Diff line
@@ -1886,7 +1886,7 @@ using StylusButtonIntegrationTestTypes =
        ::testing::Types<UinputTouchScreen, UinputExternalStylus, UinputExternalStylusWithPressure>;
TYPED_TEST_SUITE(StylusButtonIntegrationTest, StylusButtonIntegrationTestTypes);
TYPED_TEST(StylusButtonIntegrationTest, DISABLED_StylusButtonsGenerateKeyEvents) {
TYPED_TEST(StylusButtonIntegrationTest, StylusButtonsGenerateKeyEvents) {
    const auto stylusId = TestFixture::mStylusInfo.getId();
    TestFixture::mStylus->pressKey(BTN_STYLUS);
@@ -1900,7 +1900,7 @@ TYPED_TEST(StylusButtonIntegrationTest, DISABLED_StylusButtonsGenerateKeyEvents)
                  WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY), WithDeviceId(stylusId))));
}
TYPED_TEST(StylusButtonIntegrationTest, DISABLED_StylusButtonsSurroundingTouchGesture) {
TYPED_TEST(StylusButtonIntegrationTest, StylusButtonsSurroundingTouchGesture) {
    const Point centerPoint = TestFixture::mTouchscreen->getCenterPoint();
    const auto touchscreenId = TestFixture::mTouchscreenInfo.getId();
    const auto stylusId = TestFixture::mStylusInfo.getId();
@@ -1946,7 +1946,7 @@ TYPED_TEST(StylusButtonIntegrationTest, DISABLED_StylusButtonsSurroundingTouchGe
                  WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY), WithDeviceId(stylusId))));
}
TYPED_TEST(StylusButtonIntegrationTest, DISABLED_StylusButtonsSurroundingHoveringTouchGesture) {
TYPED_TEST(StylusButtonIntegrationTest, StylusButtonsSurroundingHoveringTouchGesture) {
    const Point centerPoint = TestFixture::mTouchscreen->getCenterPoint();
    const auto touchscreenId = TestFixture::mTouchscreenInfo.getId();
    const auto stylusId = TestFixture::mStylusInfo.getId();
@@ -2022,7 +2022,7 @@ TYPED_TEST(StylusButtonIntegrationTest, DISABLED_StylusButtonsSurroundingHoverin
                  WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY), WithDeviceId(stylusId))));
}
TYPED_TEST(StylusButtonIntegrationTest, DISABLED_StylusButtonsWithinTouchGesture) {
TYPED_TEST(StylusButtonIntegrationTest, StylusButtonsWithinTouchGesture) {
    const Point centerPoint = TestFixture::mTouchscreen->getCenterPoint();
    const auto touchscreenId = TestFixture::mTouchscreenInfo.getId();
    const auto stylusId = TestFixture::mStylusInfo.getId();
@@ -2076,7 +2076,7 @@ TYPED_TEST(StylusButtonIntegrationTest, DISABLED_StylusButtonsWithinTouchGesture
                  WithDeviceId(touchscreenId))));
}
TYPED_TEST(StylusButtonIntegrationTest, DISABLED_StylusButtonMotionEventsDisabled) {
TYPED_TEST(StylusButtonIntegrationTest, StylusButtonMotionEventsDisabled) {
    TestFixture::mFakePolicy->setStylusButtonMotionEventsEnabled(false);
    TestFixture::mReader->requestRefreshConfiguration(
            InputReaderConfiguration::Change::STYLUS_BUTTON_REPORTING);
@@ -2133,7 +2133,7 @@ TYPED_TEST(StylusButtonIntegrationTest, DISABLED_StylusButtonMotionEventsDisable
// ongoing stylus gesture that is being emitted by the touchscreen.
using ExternalStylusIntegrationTest = TouchIntegrationTest;
TEST_F(ExternalStylusIntegrationTest, DISABLED_FusedExternalStylusPressureReported) {
TEST_F(ExternalStylusIntegrationTest, FusedExternalStylusPressureReported) {
    const Point centerPoint = mDevice->getCenterPoint();
    // Create an external stylus capable of reporting pressure data that
@@ -2179,7 +2179,7 @@ TEST_F(ExternalStylusIntegrationTest, DISABLED_FusedExternalStylusPressureReport
    ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasNotCalled());
}
TEST_F(ExternalStylusIntegrationTest, DISABLED_FusedExternalStylusPressureNotReported) {
TEST_F(ExternalStylusIntegrationTest, FusedExternalStylusPressureNotReported) {
    const Point centerPoint = mDevice->getCenterPoint();
    // Create an external stylus capable of reporting pressure data that
@@ -2247,7 +2247,7 @@ TEST_F(ExternalStylusIntegrationTest, DISABLED_FusedExternalStylusPressureNotRep
    ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasNotCalled());
}
TEST_F(ExternalStylusIntegrationTest, DISABLED_UnfusedExternalStylus) {
TEST_F(ExternalStylusIntegrationTest, UnfusedExternalStylus) {
    const Point centerPoint = mDevice->getCenterPoint();
    // Create an external stylus device that does not support pressure. It should not affect any