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

Commit 7feb2eaf authored by Siarhei Vishniakou's avatar Siarhei Vishniakou
Browse files

Add FocusEvent and InputMessage::Type::FOCUS

FocusEvents will be consumed by InputConsumer on the app side. They
will be used to notify app that focus has been gained / lost. They will
also carry information about the current state of touch mode.

Also add a new type of InputMessage with type FOCUS.
This new data structure will be used to pass focus events to the apps
from input across the socket.

Bug: 70668286
Test: presubmit
Change-Id: I88582c64ee41ecb49623b9b7f5c149eafa694788
parent 28d8c7db
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -158,7 +158,10 @@ enum {
    AINPUT_EVENT_TYPE_KEY = 1,

    /** Indicates that the input event is a motion event. */
    AINPUT_EVENT_TYPE_MOTION = 2
    AINPUT_EVENT_TYPE_MOTION = 2,

    /** Focus event */
    AINPUT_EVENT_TYPE_FOCUS = 3,
};

/**
+29 −0
Original line number Diff line number Diff line
@@ -167,6 +167,8 @@ namespace android {
class Parcel;
#endif

const char* inputEventTypeToString(int32_t type);

/*
 * Flags that flow alongside events in the input dispatch system to help with certain
 * policy decisions such as waking from device sleep.
@@ -686,6 +688,28 @@ protected:
    Vector<PointerCoords> mSamplePointerCoords;
};

/*
 * Focus events.
 */
class FocusEvent : public InputEvent {
public:
    virtual ~FocusEvent() {}

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

    inline bool getHasFocus() const { return mHasFocus; }

    inline bool getInTouchMode() const { return mInTouchMode; }

    void initialize(bool hasFocus, bool inTouchMode);

    void initialize(const FocusEvent& from);

protected:
    bool mHasFocus;
    bool mInTouchMode;
};

/*
 * Input event factory.
 */
@@ -698,6 +722,7 @@ public:

    virtual KeyEvent* createKeyEvent() = 0;
    virtual MotionEvent* createMotionEvent() = 0;
    virtual FocusEvent* createFocusEvent() = 0;
};

/*
@@ -711,10 +736,12 @@ public:

    virtual KeyEvent* createKeyEvent() override { return &mKeyEvent; }
    virtual MotionEvent* createMotionEvent() override { return &mMotionEvent; }
    virtual FocusEvent* createFocusEvent() override { return &mFocusEvent; }

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

/*
@@ -727,6 +754,7 @@ public:

    virtual KeyEvent* createKeyEvent() override;
    virtual MotionEvent* createMotionEvent() override;
    virtual FocusEvent* createFocusEvent() override;

    void recycle(InputEvent* event);

@@ -735,6 +763,7 @@ private:

    std::queue<std::unique_ptr<KeyEvent>> mKeyEventPool;
    std::queue<std::unique_ptr<MotionEvent>> mMotionEventPool;
    std::queue<std::unique_ptr<FocusEvent>> mFocusEventPool;
};

} // namespace android
+25 −9
Original line number Diff line number Diff line
@@ -64,6 +64,7 @@ struct InputMessage {
        KEY,
        MOTION,
        FINISHED,
        FOCUS,
    };

    struct Header {
@@ -92,9 +93,7 @@ struct InputMessage {
            uint32_t empty2;
            nsecs_t downTime __attribute__((aligned(8)));

            inline size_t size() const {
                return sizeof(Key);
            }
            inline size_t size() const { return sizeof(Key); }
        } key;

        struct Motion {
@@ -110,7 +109,7 @@ struct InputMessage {
            int32_t metaState;
            int32_t buttonState;
            MotionClassification classification; // base type: uint8_t
            uint8_t empty2[3];
            uint8_t empty2[3];                   // 3 bytes to fill gap created by classification
            int32_t edgeFlags;
            nsecs_t downTime __attribute__((aligned(8)));
            float xOffset;
@@ -148,10 +147,17 @@ struct InputMessage {
            uint32_t seq;
            uint32_t handled; // actually a bool, but we must maintain 8-byte alignment

            inline size_t size() const {
                return sizeof(Finished);
            }
            inline size_t size() const { return sizeof(Finished); }
        } finished;

        struct Focus {
            uint32_t seq;
            // The following two fields take up 4 bytes total
            uint16_t hasFocus;    // actually a bool
            uint16_t inTouchMode; // actually a bool, but we must maintain 8-byte alignment

            inline size_t size() const { return sizeof(Focus); }
        } focus;
    } __attribute__((aligned(8))) body;

    bool isValid(size_t actualSize) const;
@@ -294,6 +300,15 @@ public:
                                uint32_t pointerCount, const PointerProperties* pointerProperties,
                                const PointerCoords* pointerCoords);

    /* Publishes a focus 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 publishFocusEvent(uint32_t seq, bool hasFocus, bool inTouchMode);

    /* 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.
@@ -349,8 +364,8 @@ public:
     * Returns NO_MEMORY if the event could not be created.
     * Other errors probably indicate that the channel is broken.
     */
    status_t consume(InputEventFactoryInterface* factory, bool consumeBatches,
            nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent);
    status_t consume(InputEventFactoryInterface* factory, bool consumeBatches, nsecs_t frameTime,
                     uint32_t* outSeq, InputEvent** outEvent);

    /* Sends a finished signal to the publisher to inform it that the message
     * with the specified sequence number has finished being process and whether
@@ -521,6 +536,7 @@ private:
    static void rewriteMessage(TouchState& state, InputMessage& msg);
    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 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);
+45 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@
#include <limits.h>

#include <input/Input.h>
#include <input/InputDevice.h>
#include <input/InputEventLabels.h>

#ifdef __ANDROID__
@@ -41,6 +42,21 @@ const char* motionClassificationToString(MotionClassification classification) {

// --- InputEvent ---

const char* inputEventTypeToString(int32_t type) {
    switch (type) {
        case AINPUT_EVENT_TYPE_KEY: {
            return "KEY";
        }
        case AINPUT_EVENT_TYPE_MOTION: {
            return "MOTION";
        }
        case AINPUT_EVENT_TYPE_FOCUS: {
            return "FOCUS";
        }
    }
    return "UNKNOWN";
}

void InputEvent::initialize(int32_t deviceId, int32_t source, int32_t displayId) {
    mDeviceId = deviceId;
    mSource = source;
@@ -587,6 +603,20 @@ int32_t MotionEvent::getAxisFromLabel(const char* label) {
    return getAxisByLabel(label);
}

// --- FocusEvent ---

void FocusEvent::initialize(bool hasFocus, bool inTouchMode) {
    InputEvent::initialize(ReservedInputDeviceId::VIRTUAL_KEYBOARD_ID, AINPUT_SOURCE_UNKNOWN,
                           ADISPLAY_ID_NONE);
    mHasFocus = hasFocus;
    mInTouchMode = inTouchMode;
}

void FocusEvent::initialize(const FocusEvent& from) {
    InputEvent::initialize(from);
    mHasFocus = from.mHasFocus;
    mInTouchMode = from.mInTouchMode;
}

// --- PooledInputEventFactory ---

@@ -615,6 +645,15 @@ MotionEvent* PooledInputEventFactory::createMotionEvent() {
    return event;
}

FocusEvent* PooledInputEventFactory::createFocusEvent() {
    if (mFocusEventPool.empty()) {
        return new FocusEvent();
    }
    FocusEvent* event = mFocusEventPool.front().release();
    mFocusEventPool.pop();
    return event;
}

void PooledInputEventFactory::recycle(InputEvent* event) {
    switch (event->getType()) {
    case AINPUT_EVENT_TYPE_KEY:
@@ -629,6 +668,12 @@ void PooledInputEventFactory::recycle(InputEvent* event) {
            return;
        }
        break;
    case AINPUT_EVENT_TYPE_FOCUS:
        if (mFocusEventPool.size() < mMaxPoolSize) {
            mFocusEventPool.push(std::unique_ptr<FocusEvent>(static_cast<FocusEvent*>(event)));
            return;
        }
        break;
    }
    delete event;
}
+54 −13
Original line number Diff line number Diff line
@@ -103,6 +103,8 @@ bool InputMessage::isValid(size_t actualSize) const {
                return body.motion.pointerCount > 0 && body.motion.pointerCount <= MAX_POINTERS;
            case Type::FINISHED:
                return true;
            case Type::FOCUS:
                return true;
        }
    }
    return false;
@@ -116,6 +118,8 @@ size_t InputMessage::size() const {
            return sizeof(Header) + body.motion.size();
        case Type::FINISHED:
            return sizeof(Header) + body.finished.size();
        case Type::FOCUS:
            return sizeof(Header) + body.focus.size();
    }
    return sizeof(Header);
}
@@ -220,6 +224,12 @@ void InputMessage::getSanitizedCopy(InputMessage* msg) const {
            msg->body.finished.handled = body.finished.handled;
            break;
        }
        case InputMessage::Type::FOCUS: {
            msg->body.focus.seq = body.focus.seq;
            msg->body.focus.hasFocus = body.focus.hasFocus;
            msg->body.focus.inTouchMode = body.focus.inTouchMode;
            break;
        }
    }
}

@@ -529,6 +539,23 @@ status_t InputPublisher::publishMotionEvent(
    return mChannel->sendMessage(&msg);
}

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

    InputMessage msg;
    msg.header.type = InputMessage::Type::FOCUS;
    msg.body.focus.seq = seq;
    msg.body.focus.hasFocus = hasFocus ? 1 : 0;
    msg.body.focus.inTouchMode = inTouchMode ? 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());
@@ -565,8 +592,8 @@ bool InputConsumer::isTouchResamplingEnabled() {
    return property_get_bool(PROPERTY_RESAMPLING_ENABLED, true);
}

status_t InputConsumer::consume(InputEventFactoryInterface* factory,
        bool consumeBatches, nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent) {
status_t InputConsumer::consume(InputEventFactoryInterface* factory, bool consumeBatches,
                                nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent) {
    if (DEBUG_TRANSPORT_ACTIONS) {
        ALOGD("channel '%s' consumer ~ consume: consumeBatches=%s, frameTime=%" PRId64,
              mChannel->getName().c_str(), toString(consumeBatches), frameTime);
@@ -689,6 +716,16 @@ status_t InputConsumer::consume(InputEventFactoryInterface* factory,
                                 "InputConsumer!");
                break;
            }

            case InputMessage::Type::FOCUS: {
                FocusEvent* focusEvent = factory->createFocusEvent();
                if (!focusEvent) return NO_MEMORY;

                initializeFocusEvent(focusEvent, &mMsg);
                *outSeq = mMsg.body.focus.seq;
                *outEvent = focusEvent;
                break;
            }
        }
    }
    return OK;
@@ -1113,6 +1150,10 @@ void InputConsumer::initializeKeyEvent(KeyEvent* event, const InputMessage* msg)
            msg->body.key.eventTime);
}

void InputConsumer::initializeFocusEvent(FocusEvent* event, const InputMessage* msg) {
    event->initialize(msg->body.focus.hasFocus == 1, msg->body.focus.inTouchMode == 1);
}

void InputConsumer::initializeMotionEvent(MotionEvent* event, const InputMessage* msg) {
    uint32_t pointerCount = msg->body.motion.pointerCount;
    PointerProperties pointerProperties[pointerCount];
Loading