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

Commit 3f37b7b1 authored by Prabir Pradhan's avatar Prabir Pradhan
Browse files

SyncPointerCapture (3/n): Add Capture event to InputChannel

This CL adds the ability to send a CAPTURE event through the
InputChannel, and adds the appropriate processing logic to
InputPublisher and InputConsumer.

This will be used by the InputDispatcher to notify windows when they
have either lost or gained Pointer Capture.

Bug: 141749603
Test: atest libinput_tests
Change-Id: I102833e6f0fd1e8e9c4b3c12e7a5a737eeda2377
parent 7e186182
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -163,6 +163,9 @@ enum {

    /** Focus event */
    AINPUT_EVENT_TYPE_FOCUS = 3,

    /** Capture event */
    AINPUT_EVENT_TYPE_CAPTURE = 4,
};

/**
+24 −0
Original line number Diff line number Diff line
@@ -773,6 +773,25 @@ protected:
    bool mInTouchMode;
};

/*
 * Capture events.
 */
class CaptureEvent : public InputEvent {
public:
    virtual ~CaptureEvent() {}

    virtual int32_t getType() const override { return AINPUT_EVENT_TYPE_CAPTURE; }

    inline bool getPointerCaptureEnabled() const { return mPointerCaptureEnabled; }

    void initialize(int32_t id, bool pointerCaptureEnabled);

    void initialize(const CaptureEvent& from);

protected:
    bool mPointerCaptureEnabled;
};

/**
 * Base class for verified events.
 * Do not create a VerifiedInputEvent explicitly.
@@ -835,6 +854,7 @@ public:
    virtual KeyEvent* createKeyEvent() = 0;
    virtual MotionEvent* createMotionEvent() = 0;
    virtual FocusEvent* createFocusEvent() = 0;
    virtual CaptureEvent* createCaptureEvent() = 0;
};

/*
@@ -849,11 +869,13 @@ public:
    virtual KeyEvent* createKeyEvent() override { return &mKeyEvent; }
    virtual MotionEvent* createMotionEvent() override { return &mMotionEvent; }
    virtual FocusEvent* createFocusEvent() override { return &mFocusEvent; }
    virtual CaptureEvent* createCaptureEvent() override { return &mCaptureEvent; }

private:
    KeyEvent mKeyEvent;
    MotionEvent mMotionEvent;
    FocusEvent mFocusEvent;
    CaptureEvent mCaptureEvent;
};

/*
@@ -867,6 +889,7 @@ public:
    virtual KeyEvent* createKeyEvent() override;
    virtual MotionEvent* createMotionEvent() override;
    virtual FocusEvent* createFocusEvent() override;
    virtual CaptureEvent* createCaptureEvent() override;

    void recycle(InputEvent* event);

@@ -876,6 +899,7 @@ private:
    std::queue<std::unique_ptr<KeyEvent>> mKeyEventPool;
    std::queue<std::unique_ptr<MotionEvent>> mMotionEventPool;
    std::queue<std::unique_ptr<FocusEvent>> mFocusEventPool;
    std::queue<std::unique_ptr<CaptureEvent>> mCaptureEventPool;
};

} // namespace android
+20 −0
Original line number Diff line number Diff line
@@ -67,6 +67,7 @@ struct InputMessage {
        MOTION,
        FINISHED,
        FOCUS,
        CAPTURE,
    };

    struct Header {
@@ -166,6 +167,13 @@ struct InputMessage {

            inline size_t size() const { return sizeof(Focus); }
        } focus;

        struct Capture {
            int32_t eventId;
            uint32_t pointerCaptureEnabled; // actually a bool, but we maintain 8-byte alignment

            inline size_t size() const { return sizeof(Capture); }
        } capture;
    } __attribute__((aligned(8))) body;

    bool isValid(size_t actualSize) const;
@@ -182,6 +190,8 @@ struct InputMessage {
                return "FINISHED";
            case Type::FOCUS:
                return "FOCUS";
            case Type::CAPTURE:
                return "CAPTURE";
        }
    }
};
@@ -341,6 +351,15 @@ public:
     */
    status_t publishFocusEvent(uint32_t seq, int32_t eventId, bool hasFocus, bool inTouchMode);

    /* Publishes a capture event to the input channel.
     *
     * Returns OK on success.
     * Returns WOULD_BLOCK if the channel is full.
     * Returns DEAD_OBJECT if the channel's peer has been closed.
     * Other errors probably indicate that the channel is broken.
     */
    status_t publishCaptureEvent(uint32_t seq, int32_t eventId, bool pointerCaptureEnabled);

    /* Receives the finished signal from the consumer in reply to the original dispatch signal.
     * If a signal was received, returns the message sequence number,
     * and whether the consumer handled the message.
@@ -576,6 +595,7 @@ private:
    static void initializeKeyEvent(KeyEvent* event, const InputMessage* msg);
    static void initializeMotionEvent(MotionEvent* event, const InputMessage* msg);
    static void initializeFocusEvent(FocusEvent* event, const InputMessage* msg);
    static void initializeCaptureEvent(CaptureEvent* event, const InputMessage* msg);
    static void addSample(MotionEvent* event, const InputMessage* msg);
    static bool canAddSample(const Batch& batch, const InputMessage* msg);
    static ssize_t findSampleNoLaterThan(const Batch& batch, nsecs_t time);
+32 −0
Original line number Diff line number Diff line
@@ -89,6 +89,9 @@ const char* inputEventTypeToString(int32_t type) {
        case AINPUT_EVENT_TYPE_FOCUS: {
            return "FOCUS";
        }
        case AINPUT_EVENT_TYPE_CAPTURE: {
            return "CAPTURE";
        }
    }
    return "UNKNOWN";
}
@@ -754,6 +757,19 @@ void FocusEvent::initialize(const FocusEvent& from) {
    mInTouchMode = from.mInTouchMode;
}

// --- CaptureEvent ---

void CaptureEvent::initialize(int32_t id, bool pointerCaptureEnabled) {
    InputEvent::initialize(id, ReservedInputDeviceId::VIRTUAL_KEYBOARD_ID, AINPUT_SOURCE_UNKNOWN,
                           ADISPLAY_ID_NONE, INVALID_HMAC);
    mPointerCaptureEnabled = pointerCaptureEnabled;
}

void CaptureEvent::initialize(const CaptureEvent& from) {
    InputEvent::initialize(from);
    mPointerCaptureEnabled = from.mPointerCaptureEnabled;
}

// --- PooledInputEventFactory ---

PooledInputEventFactory::PooledInputEventFactory(size_t maxPoolSize) :
@@ -790,6 +806,15 @@ FocusEvent* PooledInputEventFactory::createFocusEvent() {
    return event;
}

CaptureEvent* PooledInputEventFactory::createCaptureEvent() {
    if (mCaptureEventPool.empty()) {
        return new CaptureEvent();
    }
    CaptureEvent* event = mCaptureEventPool.front().release();
    mCaptureEventPool.pop();
    return event;
}

void PooledInputEventFactory::recycle(InputEvent* event) {
    switch (event->getType()) {
    case AINPUT_EVENT_TYPE_KEY:
@@ -810,6 +835,13 @@ void PooledInputEventFactory::recycle(InputEvent* event) {
            return;
        }
        break;
    case AINPUT_EVENT_TYPE_CAPTURE:
        if (mCaptureEventPool.size() < mMaxPoolSize) {
            mCaptureEventPool.push(
                    std::unique_ptr<CaptureEvent>(static_cast<CaptureEvent*>(event)));
            return;
        }
        break;
    }
    delete event;
}
+46 −0
Original line number Diff line number Diff line
@@ -105,6 +105,8 @@ bool InputMessage::isValid(size_t actualSize) const {
                return true;
            case Type::FOCUS:
                return true;
            case Type::CAPTURE:
                return true;
        }
    }
    return false;
@@ -120,6 +122,8 @@ size_t InputMessage::size() const {
            return sizeof(Header) + body.finished.size();
        case Type::FOCUS:
            return sizeof(Header) + body.focus.size();
        case Type::CAPTURE:
            return sizeof(Header) + body.capture.size();
    }
    return sizeof(Header);
}
@@ -238,6 +242,11 @@ void InputMessage::getSanitizedCopy(InputMessage* msg) const {
            msg->body.focus.inTouchMode = body.focus.inTouchMode;
            break;
        }
        case InputMessage::Type::CAPTURE: {
            msg->body.capture.eventId = body.capture.eventId;
            msg->body.capture.pointerCaptureEnabled = body.capture.pointerCaptureEnabled;
            break;
        }
    }
}

@@ -571,6 +580,23 @@ status_t InputPublisher::publishFocusEvent(uint32_t seq, int32_t eventId, bool h
    return mChannel->sendMessage(&msg);
}

status_t InputPublisher::publishCaptureEvent(uint32_t seq, int32_t eventId,
                                             bool pointerCaptureEnabled) {
    if (ATRACE_ENABLED()) {
        std::string message =
                StringPrintf("publishCaptureEvent(inputChannel=%s, pointerCaptureEnabled=%s)",
                             mChannel->getName().c_str(), toString(pointerCaptureEnabled));
        ATRACE_NAME(message.c_str());
    }

    InputMessage msg;
    msg.header.type = InputMessage::Type::CAPTURE;
    msg.header.seq = seq;
    msg.body.capture.eventId = eventId;
    msg.body.capture.pointerCaptureEnabled = pointerCaptureEnabled ? 1 : 0;
    return mChannel->sendMessage(&msg);
}

status_t InputPublisher::receiveFinishedSignal(uint32_t* outSeq, bool* outHandled) {
    if (DEBUG_TRANSPORT_ACTIONS) {
        ALOGD("channel '%s' publisher ~ receiveFinishedSignal", mChannel->getName().c_str());
@@ -739,6 +765,16 @@ status_t InputConsumer::consume(InputEventFactoryInterface* factory, bool consum
                *outEvent = focusEvent;
                break;
            }

            case InputMessage::Type::CAPTURE: {
                CaptureEvent* captureEvent = factory->createCaptureEvent();
                if (!captureEvent) return NO_MEMORY;

                initializeCaptureEvent(captureEvent, &mMsg);
                *outSeq = mMsg.header.seq;
                *outEvent = captureEvent;
                break;
            }
        }
    }
    return OK;
@@ -1171,6 +1207,10 @@ void InputConsumer::initializeFocusEvent(FocusEvent* event, const InputMessage*
                      msg->body.focus.inTouchMode == 1);
}

void InputConsumer::initializeCaptureEvent(CaptureEvent* event, const InputMessage* msg) {
    event->initialize(msg->body.capture.eventId, msg->body.capture.pointerCaptureEnabled == 1);
}

void InputConsumer::initializeMotionEvent(MotionEvent* event, const InputMessage* msg) {
    uint32_t pointerCount = msg->body.motion.pointerCount;
    PointerProperties pointerProperties[pointerCount];
@@ -1274,6 +1314,12 @@ std::string InputConsumer::dump() const {
                                                       toString(msg.body.focus.inTouchMode));
                    break;
                }
                case InputMessage::Type::CAPTURE: {
                    out += android::base::StringPrintf("hasCapture=%s",
                                                       toString(msg.body.capture
                                                                        .pointerCaptureEnabled));
                    break;
                }
            }
            out += "\n";
        }
Loading