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

Commit 3891ec97 authored by Siarhei Vishniakou's avatar Siarhei Vishniakou Committed by Chavi Weingarten
Browse files

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
parent acb53f92
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -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;
};

/**
+51 −45
Original line number Diff line number Diff line
@@ -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,
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,
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,
    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());
                      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();
            }
        }
+36 −30
Original line number Diff line number Diff line
@@ -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());