diff options
author | 2024-03-15 13:29:57 -0700 | |
---|---|---|
committer | 2024-03-15 20:57:50 +0000 | |
commit | 3891ec978149a896a453b4a675c4134639b9a152 (patch) | |
tree | 4eac466df97b9f5d79997037ea898e9ac4d65e0f | |
parent | acb53f928fc2d1838873114cbff66fdbdb97d28a (diff) |
Send events wrapped in unique_ptr to InputConsumerCallbacks
This will allow the upper layers to release the ownership and hand the
object over to the ndk client. The client will then assume the
ownership. This is not possible with the current implementation of
rvalue, because the ndk interface is only using pointers.
Unfortunately, this makes things more clunky for tests (unless we modify
BlockingQueue).
Bug: 324271765
Test: TEST=libinput_tests; m $TEST && $ANDROID_HOST_OUT/nativetest64/$TEST/$TEST --gtest_repeat=100 --gtest_break_on_failure
Change-Id: I0cf326a22f840be6f8aa00d1e69f818815788487
-rw-r--r-- | include/input/InputConsumerNoResampling.h | 12 | ||||
-rw-r--r-- | libs/input/InputConsumerNoResampling.cpp | 96 | ||||
-rw-r--r-- | libs/input/tests/InputPublisherAndConsumerNoResampling_test.cpp | 66 |
3 files changed, 93 insertions, 81 deletions
diff --git a/include/input/InputConsumerNoResampling.h b/include/input/InputConsumerNoResampling.h index 7e6ae9b107..9e48b0872d 100644 --- a/include/input/InputConsumerNoResampling.h +++ b/include/input/InputConsumerNoResampling.h @@ -29,8 +29,8 @@ namespace android { class InputConsumerCallbacks { public: virtual ~InputConsumerCallbacks(){}; - virtual void onKeyEvent(KeyEvent&& event, uint32_t seq) = 0; - virtual void onMotionEvent(MotionEvent&& event, uint32_t seq) = 0; + virtual void onKeyEvent(std::unique_ptr<KeyEvent> event, uint32_t seq) = 0; + virtual void onMotionEvent(std::unique_ptr<MotionEvent> event, uint32_t seq) = 0; /** * When you receive this callback, you must (eventually) call "consumeBatchedInputEvents". * If you don't want batching, then call "consumeBatchedInputEvents" immediately with @@ -38,10 +38,10 @@ public: * @param pendingBatchSource the source of the pending batch. */ virtual void onBatchedInputEventPending(int32_t pendingBatchSource) = 0; - virtual void onFocusEvent(FocusEvent&& event, uint32_t seq) = 0; - virtual void onCaptureEvent(CaptureEvent&& event, uint32_t seq) = 0; - virtual void onDragEvent(DragEvent&& event, uint32_t seq) = 0; - virtual void onTouchModeEvent(TouchModeEvent&& event, uint32_t seq) = 0; + virtual void onFocusEvent(std::unique_ptr<FocusEvent> event, uint32_t seq) = 0; + virtual void onCaptureEvent(std::unique_ptr<CaptureEvent> event, uint32_t seq) = 0; + virtual void onDragEvent(std::unique_ptr<DragEvent> event, uint32_t seq) = 0; + virtual void onTouchModeEvent(std::unique_ptr<TouchModeEvent> event, uint32_t seq) = 0; }; /** diff --git a/libs/input/InputConsumerNoResampling.cpp b/libs/input/InputConsumerNoResampling.cpp index 1462c9059a..52acb51910 100644 --- a/libs/input/InputConsumerNoResampling.cpp +++ b/libs/input/InputConsumerNoResampling.cpp @@ -44,28 +44,37 @@ namespace { const bool DEBUG_TRANSPORT_CONSUMER = __android_log_is_loggable(ANDROID_LOG_DEBUG, LOG_TAG "Consumer", ANDROID_LOG_INFO); -void initializeKeyEvent(KeyEvent& event, const InputMessage& msg) { - event.initialize(msg.body.key.eventId, msg.body.key.deviceId, msg.body.key.source, - msg.body.key.displayId, msg.body.key.hmac, msg.body.key.action, - msg.body.key.flags, msg.body.key.keyCode, msg.body.key.scanCode, - msg.body.key.metaState, msg.body.key.repeatCount, msg.body.key.downTime, - msg.body.key.eventTime); +std::unique_ptr<KeyEvent> createKeyEvent(const InputMessage& msg) { + std::unique_ptr<KeyEvent> event = std::make_unique<KeyEvent>(); + event->initialize(msg.body.key.eventId, msg.body.key.deviceId, msg.body.key.source, + msg.body.key.displayId, msg.body.key.hmac, msg.body.key.action, + msg.body.key.flags, msg.body.key.keyCode, msg.body.key.scanCode, + msg.body.key.metaState, msg.body.key.repeatCount, msg.body.key.downTime, + msg.body.key.eventTime); + return event; } -void initializeFocusEvent(FocusEvent& event, const InputMessage& msg) { - event.initialize(msg.body.focus.eventId, msg.body.focus.hasFocus); +std::unique_ptr<FocusEvent> createFocusEvent(const InputMessage& msg) { + std::unique_ptr<FocusEvent> event = std::make_unique<FocusEvent>(); + event->initialize(msg.body.focus.eventId, msg.body.focus.hasFocus); + return event; } -void initializeCaptureEvent(CaptureEvent& event, const InputMessage& msg) { - event.initialize(msg.body.capture.eventId, msg.body.capture.pointerCaptureEnabled); +std::unique_ptr<CaptureEvent> createCaptureEvent(const InputMessage& msg) { + std::unique_ptr<CaptureEvent> event = std::make_unique<CaptureEvent>(); + event->initialize(msg.body.capture.eventId, msg.body.capture.pointerCaptureEnabled); + return event; } -void initializeDragEvent(DragEvent& event, const InputMessage& msg) { - event.initialize(msg.body.drag.eventId, msg.body.drag.x, msg.body.drag.y, - msg.body.drag.isExiting); +std::unique_ptr<DragEvent> createDragEvent(const InputMessage& msg) { + std::unique_ptr<DragEvent> event = std::make_unique<DragEvent>(); + event->initialize(msg.body.drag.eventId, msg.body.drag.x, msg.body.drag.y, + msg.body.drag.isExiting); + return event; } -void initializeMotionEvent(MotionEvent& event, const InputMessage& msg) { +std::unique_ptr<MotionEvent> createMotionEvent(const InputMessage& msg) { + std::unique_ptr<MotionEvent> event = std::make_unique<MotionEvent>(); const uint32_t pointerCount = msg.body.motion.pointerCount; std::vector<PointerProperties> pointerProperties; pointerProperties.reserve(pointerCount); @@ -83,15 +92,16 @@ void initializeMotionEvent(MotionEvent& event, const InputMessage& msg) { displayTransform.set({msg.body.motion.dsdxRaw, msg.body.motion.dtdxRaw, msg.body.motion.txRaw, msg.body.motion.dtdyRaw, msg.body.motion.dsdyRaw, msg.body.motion.tyRaw, 0, 0, 1}); - event.initialize(msg.body.motion.eventId, msg.body.motion.deviceId, msg.body.motion.source, - msg.body.motion.displayId, msg.body.motion.hmac, msg.body.motion.action, - msg.body.motion.actionButton, msg.body.motion.flags, msg.body.motion.edgeFlags, - msg.body.motion.metaState, msg.body.motion.buttonState, - msg.body.motion.classification, transform, msg.body.motion.xPrecision, - msg.body.motion.yPrecision, msg.body.motion.xCursorPosition, - msg.body.motion.yCursorPosition, displayTransform, msg.body.motion.downTime, - msg.body.motion.eventTime, pointerCount, pointerProperties.data(), - pointerCoords.data()); + event->initialize(msg.body.motion.eventId, msg.body.motion.deviceId, msg.body.motion.source, + msg.body.motion.displayId, msg.body.motion.hmac, msg.body.motion.action, + msg.body.motion.actionButton, msg.body.motion.flags, + msg.body.motion.edgeFlags, msg.body.motion.metaState, + msg.body.motion.buttonState, msg.body.motion.classification, transform, + msg.body.motion.xPrecision, msg.body.motion.yPrecision, + msg.body.motion.xCursorPosition, msg.body.motion.yCursorPosition, + displayTransform, msg.body.motion.downTime, msg.body.motion.eventTime, + pointerCount, pointerProperties.data(), pointerCoords.data()); + return event; } void addSample(MotionEvent& event, const InputMessage& msg) { @@ -107,8 +117,10 @@ void addSample(MotionEvent& event, const InputMessage& msg) { event.addSample(msg.body.motion.eventTime, pointerCoords.data()); } -void initializeTouchModeEvent(TouchModeEvent& event, const InputMessage& msg) { - event.initialize(msg.body.touchMode.eventId, msg.body.touchMode.isInTouchMode); +std::unique_ptr<TouchModeEvent> createTouchModeEvent(const InputMessage& msg) { + std::unique_ptr<TouchModeEvent> event = std::make_unique<TouchModeEvent>(); + event->initialize(msg.body.touchMode.eventId, msg.body.touchMode.isInTouchMode); + return event; } std::string outboundMessageToString(const InputMessage& outboundMsg) { @@ -388,15 +400,13 @@ std::vector<InputMessage> InputConsumerNoResampling::readAllMessages() { void InputConsumerNoResampling::handleMessage(const InputMessage& msg) const { switch (msg.header.type) { case InputMessage::Type::KEY: { - KeyEvent keyEvent; - initializeKeyEvent(keyEvent, msg); + std::unique_ptr<KeyEvent> keyEvent = createKeyEvent(msg); mCallbacks.onKeyEvent(std::move(keyEvent), msg.header.seq); break; } case InputMessage::Type::MOTION: { - MotionEvent motionEvent; - initializeMotionEvent(motionEvent, msg); + std::unique_ptr<MotionEvent> motionEvent = createMotionEvent(msg); mCallbacks.onMotionEvent(std::move(motionEvent), msg.header.seq); break; } @@ -411,29 +421,25 @@ void InputConsumerNoResampling::handleMessage(const InputMessage& msg) const { } case InputMessage::Type::FOCUS: { - FocusEvent focusEvent; - initializeFocusEvent(focusEvent, msg); + std::unique_ptr<FocusEvent> focusEvent = createFocusEvent(msg); mCallbacks.onFocusEvent(std::move(focusEvent), msg.header.seq); break; } case InputMessage::Type::CAPTURE: { - CaptureEvent captureEvent; - initializeCaptureEvent(captureEvent, msg); + std::unique_ptr<CaptureEvent> captureEvent = createCaptureEvent(msg); mCallbacks.onCaptureEvent(std::move(captureEvent), msg.header.seq); break; } case InputMessage::Type::DRAG: { - DragEvent dragEvent; - initializeDragEvent(dragEvent, msg); + std::unique_ptr<DragEvent> dragEvent = createDragEvent(msg); mCallbacks.onDragEvent(std::move(dragEvent), msg.header.seq); break; } case InputMessage::Type::TOUCH_MODE: { - TouchModeEvent touchModeEvent; - initializeTouchModeEvent(touchModeEvent, msg); + std::unique_ptr<TouchModeEvent> touchModeEvent = createTouchModeEvent(msg); mCallbacks.onTouchModeEvent(std::move(touchModeEvent), msg.header.seq); break; } @@ -448,7 +454,7 @@ bool InputConsumerNoResampling::consumeBatchedInputEvents( const nsecs_t frameTime = requestedFrameTime.value_or(std::numeric_limits<nsecs_t>::max()); bool producedEvents = false; for (auto& [deviceId, messages] : mBatches) { - MotionEvent motion; + std::unique_ptr<MotionEvent> motion; std::optional<uint32_t> firstSeqForBatch; std::vector<uint32_t> sequences; while (!messages.empty()) { @@ -456,20 +462,21 @@ bool InputConsumerNoResampling::consumeBatchedInputEvents( if (msg.body.motion.eventTime > frameTime) { break; } - if (!firstSeqForBatch.has_value()) { - initializeMotionEvent(motion, msg); + if (motion == nullptr) { + motion = createMotionEvent(msg); firstSeqForBatch = msg.header.seq; const auto [_, inserted] = mBatchedSequenceNumbers.insert({*firstSeqForBatch, {}}); if (!inserted) { LOG(FATAL) << "The sequence " << msg.header.seq << " was already present!"; } } else { - addSample(motion, msg); + addSample(*motion, msg); mBatchedSequenceNumbers[*firstSeqForBatch].push_back(msg.header.seq); } messages.pop(); } - if (firstSeqForBatch.has_value()) { + if (motion != nullptr) { + LOG_ALWAYS_FATAL_IF(!firstSeqForBatch.has_value()); mCallbacks.onMotionEvent(std::move(motion), *firstSeqForBatch); producedEvents = true; } else { @@ -520,9 +527,8 @@ std::string InputConsumerNoResampling::dump() const { std::queue<InputMessage> tmpQueue = messages; while (!tmpQueue.empty()) { LOG_ALWAYS_FATAL_IF(tmpQueue.front().header.type != InputMessage::Type::MOTION); - MotionEvent motion; - initializeMotionEvent(motion, tmpQueue.front()); - out += std::string(" ") + streamableToString(motion) + "\n"; + std::unique_ptr<MotionEvent> motion = createMotionEvent(tmpQueue.front()); + out += std::string(" ") + streamableToString(*motion) + "\n"; tmpQueue.pop(); } } diff --git a/libs/input/tests/InputPublisherAndConsumerNoResampling_test.cpp b/libs/input/tests/InputPublisherAndConsumerNoResampling_test.cpp index e24ae49c09..6593497763 100644 --- a/libs/input/tests/InputPublisherAndConsumerNoResampling_test.cpp +++ b/libs/input/tests/InputPublisherAndConsumerNoResampling_test.cpp @@ -341,19 +341,19 @@ private: // The sequence number to use when publishing the next event uint32_t mSeq = 1; - BlockingQueue<KeyEvent> mKeyEvents; - BlockingQueue<MotionEvent> mMotionEvents; - BlockingQueue<FocusEvent> mFocusEvents; - BlockingQueue<CaptureEvent> mCaptureEvents; - BlockingQueue<DragEvent> mDragEvents; - BlockingQueue<TouchModeEvent> mTouchModeEvents; + BlockingQueue<std::unique_ptr<KeyEvent>> mKeyEvents; + BlockingQueue<std::unique_ptr<MotionEvent>> mMotionEvents; + BlockingQueue<std::unique_ptr<FocusEvent>> mFocusEvents; + BlockingQueue<std::unique_ptr<CaptureEvent>> mCaptureEvents; + BlockingQueue<std::unique_ptr<DragEvent>> mDragEvents; + BlockingQueue<std::unique_ptr<TouchModeEvent>> mTouchModeEvents; // InputConsumerCallbacks interface - void onKeyEvent(KeyEvent&& event, uint32_t seq) override { + void onKeyEvent(std::unique_ptr<KeyEvent> event, uint32_t seq) override { mKeyEvents.push(std::move(event)); mConsumer->finishInputEvent(seq, true); } - void onMotionEvent(MotionEvent&& event, uint32_t seq) override { + void onMotionEvent(std::unique_ptr<MotionEvent> event, uint32_t seq) override { mMotionEvents.push(std::move(event)); mConsumer->finishInputEvent(seq, true); } @@ -363,19 +363,19 @@ private: } mConsumer->consumeBatchedInputEvents(std::nullopt); }; - void onFocusEvent(FocusEvent&& event, uint32_t seq) override { + void onFocusEvent(std::unique_ptr<FocusEvent> event, uint32_t seq) override { mFocusEvents.push(std::move(event)); mConsumer->finishInputEvent(seq, true); }; - void onCaptureEvent(CaptureEvent&& event, uint32_t seq) override { + void onCaptureEvent(std::unique_ptr<CaptureEvent> event, uint32_t seq) override { mCaptureEvents.push(std::move(event)); mConsumer->finishInputEvent(seq, true); }; - void onDragEvent(DragEvent&& event, uint32_t seq) override { + void onDragEvent(std::unique_ptr<DragEvent> event, uint32_t seq) override { mDragEvents.push(std::move(event)); mConsumer->finishInputEvent(seq, true); } - void onTouchModeEvent(TouchModeEvent&& event, uint32_t seq) override { + void onTouchModeEvent(std::unique_ptr<TouchModeEvent> event, uint32_t seq) override { mTouchModeEvents.push(std::move(event)); mConsumer->finishInputEvent(seq, true); }; @@ -465,15 +465,15 @@ void InputPublisherAndConsumerNoResamplingTest::publishAndConsumeKeyEvent() { eventTime); ASSERT_EQ(OK, status) << "publisher publishKeyEvent should return OK"; - std::optional<KeyEvent> keyEvent = mKeyEvents.popWithTimeout(TIMEOUT); + std::optional<std::unique_ptr<KeyEvent>> optKeyEvent = mKeyEvents.popWithTimeout(TIMEOUT); + ASSERT_TRUE(optKeyEvent.has_value()) << "consumer should have returned non-NULL event"; + std::unique_ptr<KeyEvent> keyEvent = std::move(*optKeyEvent); sendMessage(LooperMessage::CALL_PROBABLY_HAS_INPUT); std::optional<bool> probablyHasInput = mProbablyHasInputResponses.popWithTimeout(TIMEOUT); ASSERT_TRUE(probablyHasInput.has_value()); ASSERT_FALSE(probablyHasInput.value()) << "no events should be waiting after being consumed"; - ASSERT_TRUE(keyEvent.has_value()) << "consumer should have returned non-NULL event"; - EXPECT_EQ(eventId, keyEvent->getId()); EXPECT_EQ(deviceId, keyEvent->getDeviceId()); EXPECT_EQ(source, keyEvent->getSource()); @@ -540,7 +540,8 @@ void InputPublisherAndConsumerNoResamplingTest::publishAndConsumeBatchedMotionMo publishMotionEvent(*mPublisher, args); // Ensure no event arrives because the UI thread is blocked - std::optional<MotionEvent> noEvent = mMotionEvents.popWithTimeout(NO_EVENT_TIMEOUT); + std::optional<std::unique_ptr<MotionEvent>> noEvent = + mMotionEvents.popWithTimeout(NO_EVENT_TIMEOUT); ASSERT_FALSE(noEvent.has_value()) << "Got unexpected event: " << *noEvent; Result<InputPublisher::ConsumerResponse> result = mPublisher->receiveConsumerResponse(); @@ -559,8 +560,9 @@ void InputPublisherAndConsumerNoResamplingTest::publishAndConsumeBatchedMotionMo } mNotifyLooperMayProceed.notify_all(); - std::optional<MotionEvent> motion = mMotionEvents.popWithTimeout(TIMEOUT); - ASSERT_TRUE(motion.has_value()); + std::optional<std::unique_ptr<MotionEvent>> optMotion = mMotionEvents.popWithTimeout(TIMEOUT); + ASSERT_TRUE(optMotion.has_value()); + std::unique_ptr<MotionEvent> motion = std::move(*optMotion); ASSERT_EQ(ACTION_MOVE, motion->getAction()); verifyFinishedSignal(*mPublisher, seq, publishTime); @@ -573,8 +575,9 @@ void InputPublisherAndConsumerNoResamplingTest::publishAndConsumeMotionEvent( nsecs_t publishTime = systemTime(SYSTEM_TIME_MONOTONIC); publishMotionEvent(*mPublisher, args); - std::optional<MotionEvent> event = mMotionEvents.popWithTimeout(TIMEOUT); - ASSERT_TRUE(event.has_value()) << "consumer should have returned non-NULL event"; + std::optional<std::unique_ptr<MotionEvent>> optMotion = mMotionEvents.popWithTimeout(TIMEOUT); + ASSERT_TRUE(optMotion.has_value()); + std::unique_ptr<MotionEvent> event = std::move(*optMotion); verifyArgsEqualToEvent(args, *event); @@ -592,8 +595,9 @@ void InputPublisherAndConsumerNoResamplingTest::publishAndConsumeFocusEvent() { status = mPublisher->publishFocusEvent(seq, eventId, hasFocus); ASSERT_EQ(OK, status) << "publisher publishFocusEvent should return OK"; - std::optional<FocusEvent> focusEvent = mFocusEvents.popWithTimeout(TIMEOUT); - ASSERT_TRUE(focusEvent.has_value()) << "consumer should have returned non-NULL event"; + std::optional<std::unique_ptr<FocusEvent>> optFocusEvent = mFocusEvents.popWithTimeout(TIMEOUT); + ASSERT_TRUE(optFocusEvent.has_value()) << "consumer should have returned non-NULL event"; + std::unique_ptr<FocusEvent> focusEvent = std::move(*optFocusEvent); EXPECT_EQ(eventId, focusEvent->getId()); EXPECT_EQ(hasFocus, focusEvent->getHasFocus()); @@ -611,9 +615,9 @@ void InputPublisherAndConsumerNoResamplingTest::publishAndConsumeCaptureEvent() status = mPublisher->publishCaptureEvent(seq, eventId, captureEnabled); ASSERT_EQ(OK, status) << "publisher publishCaptureEvent should return OK"; - std::optional<CaptureEvent> event = mCaptureEvents.popWithTimeout(TIMEOUT); - - ASSERT_TRUE(event.has_value()) << "consumer should have returned non-NULL event"; + std::optional<std::unique_ptr<CaptureEvent>> optEvent = mCaptureEvents.popWithTimeout(TIMEOUT); + ASSERT_TRUE(optEvent.has_value()) << "consumer should have returned non-NULL event"; + std::unique_ptr<CaptureEvent> event = std::move(*optEvent); const CaptureEvent& captureEvent = *event; EXPECT_EQ(eventId, captureEvent.getId()); @@ -635,9 +639,9 @@ void InputPublisherAndConsumerNoResamplingTest::publishAndConsumeDragEvent() { status = mPublisher->publishDragEvent(seq, eventId, x, y, isExiting); ASSERT_EQ(OK, status) << "publisher publishDragEvent should return OK"; - std::optional<DragEvent> event = mDragEvents.popWithTimeout(TIMEOUT); - - ASSERT_TRUE(event.has_value()) << "consumer should have returned non-NULL event"; + std::optional<std::unique_ptr<DragEvent>> optEvent = mDragEvents.popWithTimeout(TIMEOUT); + ASSERT_TRUE(optEvent.has_value()) << "consumer should have returned non-NULL event"; + std::unique_ptr<DragEvent> event = std::move(*optEvent); const DragEvent& dragEvent = *event; EXPECT_EQ(eventId, dragEvent.getId()); @@ -659,8 +663,10 @@ void InputPublisherAndConsumerNoResamplingTest::publishAndConsumeTouchModeEvent( status = mPublisher->publishTouchModeEvent(seq, eventId, touchModeEnabled); ASSERT_EQ(OK, status) << "publisher publishTouchModeEvent should return OK"; - std::optional<TouchModeEvent> event = mTouchModeEvents.popWithTimeout(TIMEOUT); - ASSERT_NE(std::nullopt, event); + std::optional<std::unique_ptr<TouchModeEvent>> optEvent = + mTouchModeEvents.popWithTimeout(TIMEOUT); + ASSERT_TRUE(optEvent.has_value()); + std::unique_ptr<TouchModeEvent> event = std::move(*optEvent); const TouchModeEvent& touchModeEvent = *event; EXPECT_EQ(eventId, touchModeEvent.getId()); |