diff options
| -rw-r--r-- | services/inputflinger/reader/EventHub.cpp | 68 | ||||
| -rw-r--r-- | services/inputflinger/reader/InputReader.cpp | 6 | ||||
| -rw-r--r-- | services/inputflinger/reader/include/EventHub.h | 4 | ||||
| -rw-r--r-- | services/inputflinger/reader/include/InputReader.h | 4 | ||||
| -rw-r--r-- | services/inputflinger/tests/EventHub_test.cpp | 10 | ||||
| -rw-r--r-- | services/inputflinger/tests/InputReader_test.cpp | 9 | ||||
| -rw-r--r-- | services/inputflinger/tests/fuzzers/InputReaderFuzzer.cpp | 1 | ||||
| -rw-r--r-- | services/inputflinger/tests/fuzzers/MapperHelpers.h | 40 |
8 files changed, 68 insertions, 74 deletions
diff --git a/services/inputflinger/reader/EventHub.cpp b/services/inputflinger/reader/EventHub.cpp index 5351a51016..5c24244dfd 100644 --- a/services/inputflinger/reader/EventHub.cpp +++ b/services/inputflinger/reader/EventHub.cpp @@ -76,6 +76,8 @@ static constexpr size_t OBFUSCATED_LENGTH = 8; static constexpr int32_t FF_STRONG_MAGNITUDE_CHANNEL_IDX = 0; static constexpr int32_t FF_WEAK_MAGNITUDE_CHANNEL_IDX = 1; +static constexpr size_t EVENT_BUFFER_SIZE = 256; + // Mapping for input battery class node IDs lookup. // https://www.kernel.org/doc/Documentation/power/power_supply_class.txt static const std::unordered_map<std::string, InputBatteryClass> BATTERY_CLASSES = @@ -1633,14 +1635,13 @@ std::optional<int32_t> EventHub::getBatteryStatus(int32_t deviceId, int32_t batt return std::nullopt; } -size_t EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSize) { - ALOG_ASSERT(bufferSize >= 1); - +std::vector<RawEvent> EventHub::getEvents(int timeoutMillis) { std::scoped_lock _l(mLock); + constexpr size_t bufferSize = EVENT_BUFFER_SIZE; struct input_event readBuffer[bufferSize]; - RawEvent* event = buffer; + std::vector<RawEvent> events; size_t capacity = bufferSize; bool awoken = false; for (;;) { @@ -1661,15 +1662,17 @@ size_t EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSiz for (auto it = mClosingDevices.begin(); it != mClosingDevices.end();) { std::unique_ptr<Device> device = std::move(*it); ALOGV("Reporting device closed: id=%d, name=%s\n", device->id, device->path.c_str()); - event->when = now; - event->deviceId = (device->id == mBuiltInKeyboardId) + const int32_t deviceId = (device->id == mBuiltInKeyboardId) ? ReservedInputDeviceId::BUILT_IN_KEYBOARD_ID : device->id; - event->type = DEVICE_REMOVED; - event += 1; + events.push_back({ + .when = now, + .deviceId = deviceId, + .type = DEVICE_REMOVED, + }); it = mClosingDevices.erase(it); mNeedToSendFinishedDeviceScan = true; - if (--capacity == 0) { + if (events.size() == capacity) { break; } } @@ -1684,10 +1687,12 @@ size_t EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSiz std::unique_ptr<Device> device = std::move(*mOpeningDevices.rbegin()); mOpeningDevices.pop_back(); ALOGV("Reporting device opened: id=%d, name=%s\n", device->id, device->path.c_str()); - event->when = now; - event->deviceId = device->id == mBuiltInKeyboardId ? 0 : device->id; - event->type = DEVICE_ADDED; - event += 1; + const int32_t deviceId = device->id == mBuiltInKeyboardId ? 0 : device->id; + events.push_back({ + .when = now, + .deviceId = deviceId, + .type = DEVICE_ADDED, + }); // Try to find a matching video device by comparing device names for (auto it = mUnattachedVideoDevices.begin(); it != mUnattachedVideoDevices.end(); @@ -1705,17 +1710,18 @@ size_t EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSiz ALOGW("Device id %d exists, replaced.", device->id); } mNeedToSendFinishedDeviceScan = true; - if (--capacity == 0) { + if (events.size() == capacity) { break; } } if (mNeedToSendFinishedDeviceScan) { mNeedToSendFinishedDeviceScan = false; - event->when = now; - event->type = FINISHED_DEVICE_SCAN; - event += 1; - if (--capacity == 0) { + events.push_back({ + .when = now, + .type = FINISHED_DEVICE_SCAN, + }); + if (events.size() == capacity) { break; } } @@ -1794,21 +1800,21 @@ size_t EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSiz } else if ((readSize % sizeof(struct input_event)) != 0) { ALOGE("could not get event (wrong size: %d)", readSize); } else { - int32_t deviceId = device->id == mBuiltInKeyboardId ? 0 : device->id; + const int32_t deviceId = device->id == mBuiltInKeyboardId ? 0 : device->id; - size_t count = size_t(readSize) / sizeof(struct input_event); + 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]; - event->when = processEventTimestamp(iev); - event->readTime = systemTime(SYSTEM_TIME_MONOTONIC); - event->deviceId = deviceId; - event->type = iev.type; - event->code = iev.code; - event->value = iev.value; - event += 1; - capacity -= 1; + events.push_back({ + .when = processEventTimestamp(iev), + .readTime = systemTime(SYSTEM_TIME_MONOTONIC), + .deviceId = deviceId, + .type = iev.type, + .code = iev.code, + .value = iev.value, + }); } - if (capacity == 0) { + if (events.size() >= capacity) { // The result buffer is full. Reset the pending event index // so we will try to read the device again on the next iteration. mPendingEventIndex -= 1; @@ -1844,7 +1850,7 @@ size_t EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSiz } // Return now if we have collected any events or if we were explicitly awoken. - if (event != buffer || awoken) { + if (!events.empty() || awoken) { break; } @@ -1890,7 +1896,7 @@ size_t EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSiz } // All done, return the number of events we read. - return event - buffer; + return events; } std::vector<TouchVideoFrame> EventHub::getVideoFrames(int32_t deviceId) { diff --git a/services/inputflinger/reader/InputReader.cpp b/services/inputflinger/reader/InputReader.cpp index 4c38ce81b6..86508766f5 100644 --- a/services/inputflinger/reader/InputReader.cpp +++ b/services/inputflinger/reader/InputReader.cpp @@ -120,14 +120,14 @@ void InputReader::loopOnce() { } } // release lock - size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE); + std::vector<RawEvent> events = mEventHub->getEvents(timeoutMillis); { // acquire lock std::scoped_lock _l(mLock); mReaderIsAliveCondition.notify_all(); - if (count) { - processEventsLocked(mEventBuffer, count); + if (!events.empty()) { + processEventsLocked(events.data(), events.size()); } if (mNextTimeout != LLONG_MAX) { diff --git a/services/inputflinger/reader/include/EventHub.h b/services/inputflinger/reader/include/EventHub.h index 6b8cc257e9..2eeb3f46e5 100644 --- a/services/inputflinger/reader/include/EventHub.h +++ b/services/inputflinger/reader/include/EventHub.h @@ -282,7 +282,7 @@ public: * * Returns the number of events obtained, or 0 if the timeout expired. */ - virtual size_t getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSize) = 0; + virtual std::vector<RawEvent> getEvents(int timeoutMillis) = 0; virtual std::vector<TouchVideoFrame> getVideoFrames(int32_t deviceId) = 0; virtual base::Result<std::pair<InputDeviceSensorType, int32_t>> mapSensor( int32_t deviceId, int32_t absCode) const = 0; @@ -500,7 +500,7 @@ public: bool markSupportedKeyCodes(int32_t deviceId, const std::vector<int32_t>& keyCodes, uint8_t* outFlags) const override final; - size_t getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSize) override final; + std::vector<RawEvent> getEvents(int timeoutMillis) override final; std::vector<TouchVideoFrame> getVideoFrames(int32_t deviceId) override final; bool hasScanCode(int32_t deviceId, int32_t scanCode) const override final; diff --git a/services/inputflinger/reader/include/InputReader.h b/services/inputflinger/reader/include/InputReader.h index fbce87f9a7..012d43fc3a 100644 --- a/services/inputflinger/reader/include/InputReader.h +++ b/services/inputflinger/reader/include/InputReader.h @@ -170,10 +170,6 @@ private: InputReaderConfiguration mConfig GUARDED_BY(mLock); - // The event queue. - static const int EVENT_BUFFER_SIZE = 256; - RawEvent mEventBuffer[EVENT_BUFFER_SIZE] GUARDED_BY(mLock); - // An input device can represent a collection of EventHub devices. This map provides a way // to lookup the input device instance from the EventHub device id. std::unordered_map<int32_t /*eventHubId*/, std::shared_ptr<InputDevice>> mDevices diff --git a/services/inputflinger/tests/EventHub_test.cpp b/services/inputflinger/tests/EventHub_test.cpp index 6ef6e4498c..9380c7142f 100644 --- a/services/inputflinger/tests/EventHub_test.cpp +++ b/services/inputflinger/tests/EventHub_test.cpp @@ -99,8 +99,6 @@ protected: }; 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) { @@ -108,12 +106,12 @@ std::vector<RawEvent> EventHubTest::getEvents(std::optional<size_t> expectedEven if (expectedEvents) { timeout = 2s; } - const size_t count = - mEventHub->getEvents(timeout.count(), eventBuffer.data(), eventBuffer.size()); - if (count == 0) { + + std::vector<RawEvent> newEvents = mEventHub->getEvents(timeout.count()); + if (newEvents.empty()) { break; } - events.insert(events.end(), eventBuffer.begin(), eventBuffer.begin() + count); + events.insert(events.end(), newEvents.begin(), newEvents.end()); if (expectedEvents && events.size() >= *expectedEvents) { break; } diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp index f1f1abd8b0..b36b49812d 100644 --- a/services/inputflinger/tests/InputReader_test.cpp +++ b/services/inputflinger/tests/InputReader_test.cpp @@ -826,15 +826,14 @@ private: mExcludedDevices = devices; } - size_t getEvents(int, RawEvent* buffer, size_t bufferSize) override { + std::vector<RawEvent> getEvents(int) override { std::scoped_lock lock(mLock); - const size_t filledSize = std::min(mEvents.size(), bufferSize); - std::copy(mEvents.begin(), mEvents.begin() + filledSize, buffer); + std::vector<RawEvent> buffer; + std::swap(buffer, mEvents); - mEvents.erase(mEvents.begin(), mEvents.begin() + filledSize); mEventsCondition.notify_all(); - return filledSize; + return buffer; } std::vector<TouchVideoFrame> getVideoFrames(int32_t deviceId) override { diff --git a/services/inputflinger/tests/fuzzers/InputReaderFuzzer.cpp b/services/inputflinger/tests/fuzzers/InputReaderFuzzer.cpp index f5bd29763e..a9f5a3ac86 100644 --- a/services/inputflinger/tests/fuzzers/InputReaderFuzzer.cpp +++ b/services/inputflinger/tests/fuzzers/InputReaderFuzzer.cpp @@ -169,7 +169,6 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t* data, size_t size) { std::shared_ptr<FuzzEventHub> fuzzEventHub = std::make_shared<FuzzEventHub>(fdp); std::unique_ptr<FuzzInputReader> reader = std::make_unique<FuzzInputReader>(fuzzEventHub, fuzzPolicy, fuzzListener); - fuzzEventHub->addEvents(fdp); size_t patternCount = fdp->ConsumeIntegralInRange<size_t>(1, 260); VibrationSequence pattern(patternCount); for (size_t i = 0; i < patternCount; ++i) { diff --git a/services/inputflinger/tests/fuzzers/MapperHelpers.h b/services/inputflinger/tests/fuzzers/MapperHelpers.h index 53a7b169e4..03c226600e 100644 --- a/services/inputflinger/tests/fuzzers/MapperHelpers.h +++ b/services/inputflinger/tests/fuzzers/MapperHelpers.h @@ -114,30 +114,12 @@ class FuzzEventHub : public EventHubInterface { InputDeviceIdentifier mIdentifier; std::vector<TouchVideoFrame> mVideoFrames; PropertyMap mFuzzConfig; - size_t mCount = 0; - std::array<RawEvent, kMaxSize> mBuf; std::shared_ptr<FuzzedDataProvider> mFdp; public: FuzzEventHub(std::shared_ptr<FuzzedDataProvider> fdp) : mFdp(std::move(fdp)) {} ~FuzzEventHub() {} void addProperty(std::string key, std::string value) { mFuzzConfig.addProperty(key, value); } - void addEvents(std::shared_ptr<FuzzedDataProvider> fdp) { - mCount = fdp->ConsumeIntegralInRange<size_t>(0, kMaxSize); - - for (size_t i = 0; i < mCount; ++i) { - int32_t type = fdp->ConsumeBool() ? fdp->PickValueInArray(kValidTypes) - : fdp->ConsumeIntegral<int32_t>(); - int32_t code = fdp->ConsumeBool() ? fdp->PickValueInArray(kValidCodes) - : fdp->ConsumeIntegral<int32_t>(); - mBuf[i] = {fdp->ConsumeIntegral<nsecs_t>(), - fdp->ConsumeIntegral<nsecs_t>(), - fdp->ConsumeIntegral<int32_t>(), - type, - code, - fdp->ConsumeIntegral<int32_t>()}; - } - } ftl::Flags<InputDeviceClass> getDeviceClasses(int32_t deviceId) const override { return ftl::Flags<InputDeviceClass>(mFdp->ConsumeIntegral<uint32_t>()); @@ -168,10 +150,24 @@ public: return mFdp->ConsumeIntegral<status_t>(); } void setExcludedDevices(const std::vector<std::string>& devices) override {} - size_t getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSize) override { - for (size_t i = 0; i < mCount; ++i) buffer[i] = mBuf[i]; - - return mCount; + std::vector<RawEvent> getEvents(int timeoutMillis) override { + std::vector<RawEvent> events; + const size_t count = mFdp->ConsumeIntegralInRange<size_t>(0, kMaxSize); + for (size_t i = 0; i < count; ++i) { + int32_t type = mFdp->ConsumeBool() ? mFdp->PickValueInArray(kValidTypes) + : mFdp->ConsumeIntegral<int32_t>(); + int32_t code = mFdp->ConsumeBool() ? mFdp->PickValueInArray(kValidCodes) + : mFdp->ConsumeIntegral<int32_t>(); + events.push_back({ + .when = mFdp->ConsumeIntegral<nsecs_t>(), + .readTime = mFdp->ConsumeIntegral<nsecs_t>(), + .deviceId = mFdp->ConsumeIntegral<int32_t>(), + .type = type, + .code = code, + .value = mFdp->ConsumeIntegral<int32_t>(), + }); + } + return events; } std::vector<TouchVideoFrame> getVideoFrames(int32_t deviceId) override { return mVideoFrames; } |