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

Commit d4fdc888 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Wait longer for expected input events" into rvc-dev am: cd5ecdbe am:...

Merge "Wait longer for expected input events" into rvc-dev am: cd5ecdbe am: 01612b5c am: a06baa0f am: 82293757

Change-Id: I70085494832d3c878fc786dbf25666f1c94afa0b
parents 08255685 82293757
Loading
Loading
Loading
Loading
+36 −9
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ using android::RawEvent;
using android::sp;
using android::UinputHomeKey;
using std::chrono_literals::operator""ms;
using std::chrono_literals::operator""s;

static constexpr bool DEBUG = false;

@@ -70,11 +71,12 @@ protected:
        mEventHub = std::make_unique<EventHub>();
        consumeInitialDeviceAddedEvents();
        mKeyboard = createUinputDevice<UinputHomeKey>();
        mDeviceId = waitForDeviceCreation();
        ASSERT_NO_FATAL_FAILURE(mDeviceId = waitForDeviceCreation());
    }
    virtual void TearDown() override {
        mKeyboard.reset();
        waitForDeviceClose(mDeviceId);
        assertNoMoreEvents();
    }

    /**
@@ -83,21 +85,38 @@ protected:
    int32_t waitForDeviceCreation();
    void waitForDeviceClose(int32_t deviceId);
    void consumeInitialDeviceAddedEvents();
    std::vector<RawEvent> getEvents(std::chrono::milliseconds timeout = 5ms);
    void assertNoMoreEvents();
    /**
     * Read events from the EventHub.
     *
     * If expectedEvents is set, wait for a significant period of time to try and ensure that
     * the expected number of events has been read. The number of returned events
     * may be smaller (if timeout has been reached) or larger than expectedEvents.
     *
     * If expectedEvents is not set, return all of the immediately available events.
     */
    std::vector<RawEvent> getEvents(std::optional<size_t> expectedEvents = std::nullopt);
};

std::vector<RawEvent> EventHubTest::getEvents(std::chrono::milliseconds timeout) {
std::vector<RawEvent> EventHubTest::getEvents(std::optional<size_t> expectedEvents) {
    static constexpr size_t EVENT_BUFFER_SIZE = 256;
    std::array<RawEvent, EVENT_BUFFER_SIZE> eventBuffer;
    std::vector<RawEvent> events;

    while (true) {
        size_t count =
        std::chrono::milliseconds timeout = 0s;
        if (expectedEvents) {
            timeout = 2s;
        }
        const size_t count =
                mEventHub->getEvents(timeout.count(), eventBuffer.data(), eventBuffer.size());
        if (count == 0) {
            break;
        }
        events.insert(events.end(), eventBuffer.begin(), eventBuffer.begin() + count);
        if (expectedEvents && events.size() >= *expectedEvents) {
            break;
        }
    }
    if (DEBUG) {
        dumpEvents(events);
@@ -111,7 +130,7 @@ std::vector<RawEvent> EventHubTest::getEvents(std::chrono::milliseconds timeout)
 * it will return a lot of "device added" type of events.
 */
void EventHubTest::consumeInitialDeviceAddedEvents() {
    std::vector<RawEvent> events = getEvents(0ms);
    std::vector<RawEvent> events = getEvents();
    std::set<int32_t /*deviceId*/> existingDevices;
    // All of the events should be DEVICE_ADDED type, except the last one.
    for (size_t i = 0; i < events.size() - 1; i++) {
@@ -128,8 +147,11 @@ void EventHubTest::consumeInitialDeviceAddedEvents() {

int32_t EventHubTest::waitForDeviceCreation() {
    // Wait a little longer than usual, to ensure input device has time to be created
    std::vector<RawEvent> events = getEvents(20ms);
    EXPECT_EQ(2U, events.size()); // Using "expect" because the function is non-void.
    std::vector<RawEvent> events = getEvents(2);
    if (events.size() != 2) {
        ADD_FAILURE() << "Instead of 2 events, received " << events.size();
        return 0; // this value is unused
    }
    const RawEvent& deviceAddedEvent = events[0];
    EXPECT_EQ(static_cast<int32_t>(EventHubInterface::DEVICE_ADDED), deviceAddedEvent.type);
    InputDeviceIdentifier identifier = mEventHub->getDeviceIdentifier(deviceAddedEvent.deviceId);
@@ -142,7 +164,7 @@ int32_t EventHubTest::waitForDeviceCreation() {
}

void EventHubTest::waitForDeviceClose(int32_t deviceId) {
    std::vector<RawEvent> events = getEvents(20ms);
    std::vector<RawEvent> events = getEvents(2);
    ASSERT_EQ(2U, events.size());
    const RawEvent& deviceRemovedEvent = events[0];
    EXPECT_EQ(static_cast<int32_t>(EventHubInterface::DEVICE_REMOVED), deviceRemovedEvent.type);
@@ -152,6 +174,11 @@ void EventHubTest::waitForDeviceClose(int32_t deviceId) {
              finishedDeviceScanEvent.type);
}

void EventHubTest::assertNoMoreEvents() {
    std::vector<RawEvent> events = getEvents();
    ASSERT_TRUE(events.empty());
}

/**
 * Ensure that input_events are generated with monotonic clock.
 * That means input_event should receive a timestamp that is in the future of the time
@@ -162,7 +189,7 @@ TEST_F(EventHubTest, InputEvent_TimestampIsMonotonic) {
    nsecs_t lastEventTime = systemTime(SYSTEM_TIME_MONOTONIC);
    ASSERT_NO_FATAL_FAILURE(mKeyboard->pressAndReleaseHomeKey());

    std::vector<RawEvent> events = getEvents();
    std::vector<RawEvent> events = getEvents(4);
    ASSERT_EQ(4U, events.size()) << "Expected to receive 2 keys and 2 syncs, total of 4 events";
    for (const RawEvent& event : events) {
        // Cannot use strict comparison because the events may happen too quickly
+27 −29
Original line number Diff line number Diff line
@@ -44,9 +44,7 @@ void UinputDevice::init() {
    device.id.product = 0x01;
    device.id.version = 1;

    // Using EXPECT instead of ASSERT to allow the device creation to continue even when
    // some failures are reported when configuring the device.
    EXPECT_NO_FATAL_FAILURE(configureDevice(mDeviceFd, &device));
    ASSERT_NO_FATAL_FAILURE(configureDevice(mDeviceFd, &device));

    if (write(mDeviceFd, &device, sizeof(device)) < 0) {
        FAIL() << "Could not write uinput_user_dev struct into uinput file descriptor: "
@@ -70,7 +68,7 @@ void UinputDevice::injectEvent(uint16_t type, uint16_t code, int32_t value) {
                                             " with value %" PRId32 " : %s",
                                             type, code, value, strerror(errno));
        ALOGE("%s", msg.c_str());
        ADD_FAILURE() << msg.c_str();
        FAIL() << msg.c_str();
    }
}

@@ -82,41 +80,41 @@ UinputKeyboard::UinputKeyboard(std::initializer_list<int> keys)
void UinputKeyboard::configureDevice(int fd, uinput_user_dev* device) {
    // enable key press/release event
    if (ioctl(fd, UI_SET_EVBIT, EV_KEY)) {
        ADD_FAILURE() << "Error in ioctl : UI_SET_EVBIT : EV_KEY: " << strerror(errno);
        FAIL() << "Error in ioctl : UI_SET_EVBIT : EV_KEY: " << strerror(errno);
    }

    // enable set of KEY events
    std::for_each(mKeys.begin(), mKeys.end(), [fd](int key) {
        if (ioctl(fd, UI_SET_KEYBIT, key)) {
            ADD_FAILURE() << "Error in ioctl : UI_SET_KEYBIT : " << key << " : " << strerror(errno);
            FAIL() << "Error in ioctl : UI_SET_KEYBIT : " << key << " : " << strerror(errno);
        }
    });

    // enable synchronization event
    if (ioctl(fd, UI_SET_EVBIT, EV_SYN)) {
        ADD_FAILURE() << "Error in ioctl : UI_SET_EVBIT : EV_SYN: " << strerror(errno);
        FAIL() << "Error in ioctl : UI_SET_EVBIT : EV_SYN: " << strerror(errno);
    }
}

void UinputKeyboard::pressKey(int key) {
    if (mKeys.find(key) == mKeys.end()) {
        ADD_FAILURE() << mName << ": Cannot inject key press: Key not found: " << key;
        FAIL() << mName << ": Cannot inject key press: Key not found: " << key;
    }
    EXPECT_NO_FATAL_FAILURE(injectEvent(EV_KEY, key, 1));
    EXPECT_NO_FATAL_FAILURE(injectEvent(EV_SYN, SYN_REPORT, 0));
    injectEvent(EV_KEY, key, 1);
    injectEvent(EV_SYN, SYN_REPORT, 0);
}

void UinputKeyboard::releaseKey(int key) {
    if (mKeys.find(key) == mKeys.end()) {
        ADD_FAILURE() << mName << ": Cannot inject key release: Key not found: " << key;
        FAIL() << mName << ": Cannot inject key release: Key not found: " << key;
    }
    EXPECT_NO_FATAL_FAILURE(injectEvent(EV_KEY, key, 0));
    EXPECT_NO_FATAL_FAILURE(injectEvent(EV_SYN, SYN_REPORT, 0));
    injectEvent(EV_KEY, key, 0);
    injectEvent(EV_SYN, SYN_REPORT, 0);
}

void UinputKeyboard::pressAndReleaseKey(int key) {
    EXPECT_NO_FATAL_FAILURE(pressKey(key));
    EXPECT_NO_FATAL_FAILURE(releaseKey(key));
    pressKey(key);
    releaseKey(key);
}

// --- UinputHomeKey ---
@@ -124,7 +122,7 @@ void UinputKeyboard::pressAndReleaseKey(int key) {
UinputHomeKey::UinputHomeKey() : UinputKeyboard({KEY_HOME}) {}

void UinputHomeKey::pressAndReleaseHomeKey() {
    EXPECT_NO_FATAL_FAILURE(pressAndReleaseKey(KEY_HOME));
    pressAndReleaseKey(KEY_HOME);
}

// --- UinputTouchScreen ---
@@ -158,35 +156,35 @@ void UinputTouchScreen::configureDevice(int fd, uinput_user_dev* device) {
}

void UinputTouchScreen::sendSlot(int32_t slot) {
    EXPECT_NO_FATAL_FAILURE(injectEvent(EV_ABS, ABS_MT_SLOT, slot));
    injectEvent(EV_ABS, ABS_MT_SLOT, slot);
}

void UinputTouchScreen::sendTrackingId(int32_t trackingId) {
    EXPECT_NO_FATAL_FAILURE(injectEvent(EV_ABS, ABS_MT_TRACKING_ID, trackingId));
    injectEvent(EV_ABS, ABS_MT_TRACKING_ID, trackingId);
}

void UinputTouchScreen::sendDown(const Point& point) {
    EXPECT_NO_FATAL_FAILURE(injectEvent(EV_KEY, BTN_TOUCH, 1));
    EXPECT_NO_FATAL_FAILURE(injectEvent(EV_ABS, ABS_MT_POSITION_X, point.x));
    EXPECT_NO_FATAL_FAILURE(injectEvent(EV_ABS, ABS_MT_POSITION_Y, point.y));
    EXPECT_NO_FATAL_FAILURE(injectEvent(EV_SYN, SYN_REPORT, 0));
    injectEvent(EV_KEY, BTN_TOUCH, 1);
    injectEvent(EV_ABS, ABS_MT_POSITION_X, point.x);
    injectEvent(EV_ABS, ABS_MT_POSITION_Y, point.y);
    injectEvent(EV_SYN, SYN_REPORT, 0);
}

void UinputTouchScreen::sendMove(const Point& point) {
    EXPECT_NO_FATAL_FAILURE(injectEvent(EV_ABS, ABS_MT_POSITION_X, point.x));
    EXPECT_NO_FATAL_FAILURE(injectEvent(EV_ABS, ABS_MT_POSITION_Y, point.y));
    EXPECT_NO_FATAL_FAILURE(injectEvent(EV_SYN, SYN_REPORT, 0));
    injectEvent(EV_ABS, ABS_MT_POSITION_X, point.x);
    injectEvent(EV_ABS, ABS_MT_POSITION_Y, point.y);
    injectEvent(EV_SYN, SYN_REPORT, 0);
}

void UinputTouchScreen::sendUp() {
    sendTrackingId(0xffffffff);
    EXPECT_NO_FATAL_FAILURE(injectEvent(EV_KEY, BTN_TOUCH, 0));
    EXPECT_NO_FATAL_FAILURE(injectEvent(EV_SYN, SYN_REPORT, 0));
    injectEvent(EV_KEY, BTN_TOUCH, 0);
    injectEvent(EV_SYN, SYN_REPORT, 0);
}

void UinputTouchScreen::sendToolType(int32_t toolType) {
    EXPECT_NO_FATAL_FAILURE(injectEvent(EV_ABS, ABS_MT_TOOL_TYPE, toolType));
    EXPECT_NO_FATAL_FAILURE(injectEvent(EV_SYN, SYN_REPORT, 0));
    injectEvent(EV_ABS, ABS_MT_TOOL_TYPE, toolType);
    injectEvent(EV_SYN, SYN_REPORT, 0);
}

// Get the center x, y base on the range definition.