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

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

Merge "Wait longer for expected input events" into rvc-dev

parents f1274d45 e5b5e45e
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.