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

Commit 3dd60e21 authored by Michael Wright's avatar Michael Wright
Browse files

Add concept of gesture input monitors.

Bug: 123748692
Test: manual
Change-Id: I2abd90b622ef5d7461c783ef17fabd941103228e
parent 08014733
Loading
Loading
Loading
Loading
+16 −1
Original line number Original line Diff line number Diff line
@@ -27,12 +27,16 @@
#include <sys/types.h>
#include <sys/types.h>
#include <unistd.h>
#include <unistd.h>


#include <android-base/stringprintf.h>
#include <binder/Parcel.h>
#include <cutils/properties.h>
#include <cutils/properties.h>
#include <log/log.h>
#include <log/log.h>
#include <utils/Trace.h>


#include <binder/Parcel.h>
#include <input/InputTransport.h>
#include <input/InputTransport.h>


using android::base::StringPrintf;

namespace android {
namespace android {


// Socket buffer size.  The default is typically about 128KB, which is much larger than
// Socket buffer size.  The default is typically about 128KB, which is much larger than
@@ -420,6 +424,11 @@ status_t InputPublisher::publishKeyEvent(
        int32_t repeatCount,
        int32_t repeatCount,
        nsecs_t downTime,
        nsecs_t downTime,
        nsecs_t eventTime) {
        nsecs_t eventTime) {
    if (ATRACE_ENABLED()) {
        std::string message = StringPrintf("publishKeyEvent(inputChannel=%s, keyCode=%" PRId32 ")",
                mChannel->getName().c_str(), keyCode);
        ATRACE_NAME(message.c_str());
    }
#if DEBUG_TRANSPORT_ACTIONS
#if DEBUG_TRANSPORT_ACTIONS
    ALOGD("channel '%s' publisher ~ publishKeyEvent: seq=%u, deviceId=%d, source=0x%x, "
    ALOGD("channel '%s' publisher ~ publishKeyEvent: seq=%u, deviceId=%d, source=0x%x, "
            "action=0x%x, flags=0x%x, keyCode=%d, scanCode=%d, metaState=0x%x, repeatCount=%d,"
            "action=0x%x, flags=0x%x, keyCode=%d, scanCode=%d, metaState=0x%x, repeatCount=%d,"
@@ -472,6 +481,12 @@ status_t InputPublisher::publishMotionEvent(
        uint32_t pointerCount,
        uint32_t pointerCount,
        const PointerProperties* pointerProperties,
        const PointerProperties* pointerProperties,
        const PointerCoords* pointerCoords) {
        const PointerCoords* pointerCoords) {
    if (ATRACE_ENABLED()) {
        std::string message = StringPrintf(
                "publishMotionEvent(inputChannel=%s, action=%" PRId32 ")",
                mChannel->getName().c_str(), action);
        ATRACE_NAME(message.c_str());
    }
#if DEBUG_TRANSPORT_ACTIONS
#if DEBUG_TRANSPORT_ACTIONS
    ALOGD("channel '%s' publisher ~ publishMotionEvent: seq=%u, deviceId=%d, source=0x%x, "
    ALOGD("channel '%s' publisher ~ publishMotionEvent: seq=%u, deviceId=%d, source=0x%x, "
            "displayId=%" PRId32 ", "
            "displayId=%" PRId32 ", "
+336 −113

File changed.

Preview size limit exceeded, changes collapsed.

+96 −32
Original line number Original line Diff line number Diff line
@@ -23,6 +23,8 @@
#include <input/InputTransport.h>
#include <input/InputTransport.h>
#include <input/InputWindow.h>
#include <input/InputWindow.h>
#include <input/ISetInputWindowsListener.h>
#include <input/ISetInputWindowsListener.h>
#include <optional>
#include <ui/Region.h>
#include <utils/threads.h>
#include <utils/threads.h>
#include <utils/Timers.h>
#include <utils/Timers.h>
#include <utils/RefBase.h>
#include <utils/RefBase.h>
@@ -351,19 +353,35 @@ public:
    virtual bool transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken) = 0;
    virtual bool transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken) = 0;


    /* Registers input channels that may be used as targets for input events.
    /* Registers input channels that may be used as targets for input events.
     * If inputWindowHandle is null, and displayId is not ADISPLAY_ID_NONE,
     * the channel will receive a copy of all input events form the specific displayId.
     *
     *
     * This method may be called on any thread (usually by the input manager).
     * This method may be called on any thread (usually by the input manager).
     */
     */
    virtual status_t registerInputChannel(
    virtual status_t registerInputChannel(
            const sp<InputChannel>& inputChannel, int32_t displayId) = 0;
            const sp<InputChannel>& inputChannel, int32_t displayId) = 0;


    /* Registers input channels to be used to monitor input events.
     *
     * Each monitor must target a specific display and will only receive input events sent to that
     * display. If the monitor is a gesture monitor, it will only receive pointer events on the
     * targeted display.
     *
     * This method may be called on any thread (usually by the input manager).
     */
    virtual status_t registerInputMonitor(
            const sp<InputChannel>& inputChannel, int32_t displayId, bool gestureMonitor) = 0;

    /* Unregister input channels that will no longer receive input events.
    /* Unregister input channels that will no longer receive input events.
     *
     *
     * This method may be called on any thread (usually by the input manager).
     * This method may be called on any thread (usually by the input manager).
     */
     */
    virtual status_t unregisterInputChannel(const sp<InputChannel>& inputChannel) = 0;
    virtual status_t unregisterInputChannel(const sp<InputChannel>& inputChannel) = 0;

    /* Allows an input monitor steal the current pointer stream away from normal input windows.
     *
     * This method may be called on any thread (usually by the input manager).
     */
    virtual status_t pilferPointers(const sp<IBinder>& token) = 0;

};
};


/* Dispatches events to input targets.  Some functions of the input dispatcher, such as
/* Dispatches events to input targets.  Some functions of the input dispatcher, such as
@@ -390,35 +408,39 @@ protected:
public:
public:
    explicit InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy);
    explicit InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy);


    virtual void dump(std::string& dump);
    virtual void dump(std::string& dump) override;
    virtual void monitor();
    virtual void monitor() override;


    virtual void dispatchOnce();
    virtual void dispatchOnce() override;


    virtual void notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args);
    virtual void notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) override;
    virtual void notifyKey(const NotifyKeyArgs* args);
    virtual void notifyKey(const NotifyKeyArgs* args) override;
    virtual void notifyMotion(const NotifyMotionArgs* args);
    virtual void notifyMotion(const NotifyMotionArgs* args) override;
    virtual void notifySwitch(const NotifySwitchArgs* args);
    virtual void notifySwitch(const NotifySwitchArgs* args) override;
    virtual void notifyDeviceReset(const NotifyDeviceResetArgs* args);
    virtual void notifyDeviceReset(const NotifyDeviceResetArgs* args) override;


    virtual int32_t injectInputEvent(const InputEvent* event,
    virtual int32_t injectInputEvent(const InputEvent* event,
            int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis,
            int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis,
            uint32_t policyFlags);
            uint32_t policyFlags) override;


    virtual void setInputWindows(const std::vector<sp<InputWindowHandle> >& inputWindowHandles,
    virtual void setInputWindows(const std::vector<sp<InputWindowHandle> >& inputWindowHandles,
            int32_t displayId,
            int32_t displayId,
            const sp<ISetInputWindowsListener>& setInputWindowsListener = nullptr);
            const sp<ISetInputWindowsListener>& setInputWindowsListener = nullptr) override;
    virtual void setFocusedApplication(int32_t displayId,
    virtual void setFocusedApplication(int32_t displayId,
            const sp<InputApplicationHandle>& inputApplicationHandle);
            const sp<InputApplicationHandle>& inputApplicationHandle) override;
    virtual void setFocusedDisplay(int32_t displayId);
    virtual void setFocusedDisplay(int32_t displayId) override;
    virtual void setInputDispatchMode(bool enabled, bool frozen);
    virtual void setInputDispatchMode(bool enabled, bool frozen) override;
    virtual void setInputFilterEnabled(bool enabled);
    virtual void setInputFilterEnabled(bool enabled) override;


    virtual bool transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken);
    virtual bool transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken)
            override;


    virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel,
    virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel,
            int32_t displayId);
            int32_t displayId) override;
    virtual status_t unregisterInputChannel(const sp<InputChannel>& inputChannel);
    virtual status_t registerInputMonitor(const sp<InputChannel>& inputChannel,
            int32_t displayId, bool isGestureMonitor) override;
    virtual status_t unregisterInputChannel(const sp<InputChannel>& inputChannel) override;
    virtual status_t pilferPointers(const sp<IBinder>& token) override;


private:
private:
    template <typename T>
    template <typename T>
@@ -712,10 +734,6 @@ private:
            CANCEL_POINTER_EVENTS = 1,
            CANCEL_POINTER_EVENTS = 1,
            CANCEL_NON_POINTER_EVENTS = 2,
            CANCEL_NON_POINTER_EVENTS = 2,
            CANCEL_FALLBACK_EVENTS = 3,
            CANCEL_FALLBACK_EVENTS = 3,

            /* Cancel events where the display not specified. These events would go to the focused
             * display. */
            CANCEL_DISPLAY_UNSPECIFIED_EVENTS = 4,
        };
        };


        // The criterion to use to determine which events should be canceled.
        // The criterion to use to determine which events should be canceled.
@@ -724,14 +742,16 @@ private:
        // Descriptive reason for the cancelation.
        // Descriptive reason for the cancelation.
        const char* reason;
        const char* reason;


        // The specific keycode of the key event to cancel, or -1 to cancel any key event.
        // The specific keycode of the key event to cancel, or nullopt to cancel any key event.
        int32_t keyCode;
        std::optional<int32_t> keyCode = std::nullopt;


        // The specific device id of events to cancel, or -1 to cancel events from any device.
        // The specific device id of events to cancel, or nullopt to cancel events from any device.
        int32_t deviceId;
        std::optional<int32_t> deviceId = std::nullopt;

        // The specific display id of events to cancel, or nullopt to cancel events on any display.
        std::optional<int32_t> displayId = std::nullopt;


        CancelationOptions(Mode mode, const char* reason) :
        CancelationOptions(Mode mode, const char* reason) : mode(mode), reason(reason) { }
                mode(mode), reason(reason), keyCode(-1), deviceId(-1) { }
    };
    };


    /* Tracks dispatched key and motion event state so that cancelation events can be
    /* Tracks dispatched key and motion event state so that cancelation events can be
@@ -871,6 +891,12 @@ private:
        DispatchEntry* findWaitQueueEntry(uint32_t seq);
        DispatchEntry* findWaitQueueEntry(uint32_t seq);
    };
    };


    struct Monitor {
        sp<InputChannel> inputChannel; // never null

        explicit Monitor(const sp<InputChannel>& inputChannel);
    };

    enum DropReason {
    enum DropReason {
        DROP_REASON_NOT_DROPPED = 0,
        DROP_REASON_NOT_DROPPED = 0,
        DROP_REASON_POLICY = 1,
        DROP_REASON_POLICY = 1,
@@ -936,12 +962,24 @@ private:
    std::unordered_map<sp<IBinder>, sp<InputChannel>, IBinderHash> mInputChannelsByToken
    std::unordered_map<sp<IBinder>, sp<InputChannel>, IBinderHash> mInputChannelsByToken
            GUARDED_BY(mLock);
            GUARDED_BY(mLock);


    // Finds the display ID of the gesture monitor identified by the provided token.
    std::optional<int32_t> findGestureMonitorDisplayByTokenLocked(const sp<IBinder>& token)
            REQUIRES(mLock);

    ssize_t getConnectionIndexLocked(const sp<InputChannel>& inputChannel) REQUIRES(mLock);
    ssize_t getConnectionIndexLocked(const sp<InputChannel>& inputChannel) REQUIRES(mLock);


    // Input channels that will receive a copy of all input events sent to the provided display.
    // Input channels that will receive a copy of all input events sent to the provided display.
    std::unordered_map<int32_t, std::vector<sp<InputChannel>>> mMonitoringChannelsByDisplay
    std::unordered_map<int32_t, std::vector<Monitor>> mGlobalMonitorsByDisplay
            GUARDED_BY(mLock);

    // Input channels that will receive pointer events that start within the corresponding display.
    // These are a bit special when compared to global monitors since they'll cause gesture streams
    // to continue even when there isn't a touched window,and have the ability to steal the rest of
    // the pointer stream in order to claim it for a system gesture.
    std::unordered_map<int32_t, std::vector<Monitor>> mGestureMonitorsByDisplay
            GUARDED_BY(mLock);
            GUARDED_BY(mLock);



    // Event injection and synchronization.
    // Event injection and synchronization.
    std::condition_variable mInjectionResultAvailable;
    std::condition_variable mInjectionResultAvailable;
    bool hasInjectionPermission(int32_t injectorPid, int32_t injectorUid);
    bool hasInjectionPermission(int32_t injectorPid, int32_t injectorUid);
@@ -1016,6 +1054,16 @@ private:
        int32_t targetFlags;
        int32_t targetFlags;
        BitSet32 pointerIds;        // zero unless target flag FLAG_SPLIT is set
        BitSet32 pointerIds;        // zero unless target flag FLAG_SPLIT is set
    };
    };

    // For tracking the offsets we need to apply when adding gesture monitor targets.
    struct TouchedMonitor {
        Monitor monitor;
        float xOffset = 0.f;
        float yOffset = 0.f;

        explicit TouchedMonitor(const Monitor& monitor, float xOffset, float yOffset);
    };

    struct TouchState {
    struct TouchState {
        bool down;
        bool down;
        bool split;
        bool split;
@@ -1029,6 +1077,8 @@ private:
        // monitoring channels of the displays touched.
        // monitoring channels of the displays touched.
        std::vector<sp<InputWindowHandle>> portalWindows;
        std::vector<sp<InputWindowHandle>> portalWindows;


        std::vector<TouchedMonitor> gestureMonitors;

        TouchState();
        TouchState();
        ~TouchState();
        ~TouchState();
        void reset();
        void reset();
@@ -1036,9 +1086,11 @@ private:
        void addOrUpdateWindow(const sp<InputWindowHandle>& windowHandle,
        void addOrUpdateWindow(const sp<InputWindowHandle>& windowHandle,
                int32_t targetFlags, BitSet32 pointerIds);
                int32_t targetFlags, BitSet32 pointerIds);
        void addPortalWindow(const sp<InputWindowHandle>& windowHandle);
        void addPortalWindow(const sp<InputWindowHandle>& windowHandle);
        void addGestureMonitors(const std::vector<TouchedMonitor>& monitors);
        void removeWindow(const sp<InputWindowHandle>& windowHandle);
        void removeWindow(const sp<InputWindowHandle>& windowHandle);
        void removeWindowByToken(const sp<IBinder>& token);
        void removeWindowByToken(const sp<IBinder>& token);
        void filterNonAsIsTouchWindows();
        void filterNonAsIsTouchWindows();
        void filterNonMonitors();
        sp<InputWindowHandle> getFirstForegroundWindowHandle() const;
        sp<InputWindowHandle> getFirstForegroundWindowHandle() const;
        bool isSlippery() const;
        bool isSlippery() const;
    };
    };
@@ -1108,12 +1160,18 @@ private:
    int32_t findTouchedWindowTargetsLocked(nsecs_t currentTime, const MotionEntry* entry,
    int32_t findTouchedWindowTargetsLocked(nsecs_t currentTime, const MotionEntry* entry,
            std::vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime,
            std::vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime,
            bool* outConflictingPointerActions) REQUIRES(mLock);
            bool* outConflictingPointerActions) REQUIRES(mLock);
    std::vector<TouchedMonitor> findTouchedGestureMonitorsLocked(int32_t displayId,
            const std::vector<sp<InputWindowHandle>>& portalWindows) REQUIRES(mLock);
    void addGestureMonitors(const std::vector<Monitor>& monitors,
            std::vector<TouchedMonitor>& outTouchedMonitors, float xOffset = 0, float yOffset = 0);


    void addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
    void addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
            int32_t targetFlags, BitSet32 pointerIds, std::vector<InputTarget>& inputTargets)
            int32_t targetFlags, BitSet32 pointerIds, std::vector<InputTarget>& inputTargets)
            REQUIRES(mLock);
            REQUIRES(mLock);
    void addMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets, int32_t displayId,
    void addMonitoringTargetLocked(const Monitor& monitor, float xOffset, float yOffset,
            float xOffset = 0, float yOffset = 0) REQUIRES(mLock);
            std::vector<InputTarget>& inputTargets) REQUIRES(mLock);
    void addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
            int32_t displayId, float xOffset = 0, float yOffset = 0) REQUIRES(mLock);


    void pokeUserActivityLocked(const EventEntry* eventEntry) REQUIRES(mLock);
    void pokeUserActivityLocked(const EventEntry* eventEntry) REQUIRES(mLock);
    bool checkInjectionPermission(const sp<InputWindowHandle>& windowHandle,
    bool checkInjectionPermission(const sp<InputWindowHandle>& windowHandle,
@@ -1156,6 +1214,8 @@ private:
            const CancelationOptions& options) REQUIRES(mLock);
            const CancelationOptions& options) REQUIRES(mLock);
    void synthesizeCancelationEventsForMonitorsLocked(
    void synthesizeCancelationEventsForMonitorsLocked(
            const CancelationOptions& options) REQUIRES(mLock);
            const CancelationOptions& options) REQUIRES(mLock);
    void synthesizeCancelationEventsForMonitorsLocked(const CancelationOptions& options,
            std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) REQUIRES(mLock);
    void synthesizeCancelationEventsForInputChannelLocked(const sp<InputChannel>& channel,
    void synthesizeCancelationEventsForInputChannelLocked(const sp<InputChannel>& channel,
            const CancelationOptions& options) REQUIRES(mLock);
            const CancelationOptions& options) REQUIRES(mLock);
    void synthesizeCancelationEventsForConnectionLocked(const sp<Connection>& connection,
    void synthesizeCancelationEventsForConnectionLocked(const sp<Connection>& connection,
@@ -1169,10 +1229,14 @@ private:


    // Dump state.
    // Dump state.
    void dumpDispatchStateLocked(std::string& dump) REQUIRES(mLock);
    void dumpDispatchStateLocked(std::string& dump) REQUIRES(mLock);
    void dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors);
    void logDispatchStateLocked() REQUIRES(mLock);
    void logDispatchStateLocked() REQUIRES(mLock);


    // Registration.
    // Registration.
    void removeMonitorChannelLocked(const sp<InputChannel>& inputChannel) REQUIRES(mLock);
    void removeMonitorChannelLocked(const sp<InputChannel>& inputChannel) REQUIRES(mLock);
    void removeMonitorChannelLocked(const sp<InputChannel>& inputChannel,
        std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay)
            REQUIRES(mLock);
    status_t unregisterInputChannelLocked(const sp<InputChannel>& inputChannel, bool notify)
    status_t unregisterInputChannelLocked(const sp<InputChannel>& inputChannel, bool notify)
            REQUIRES(mLock);
            REQUIRES(mLock);


+5 −4
Original line number Original line Diff line number Diff line
@@ -416,7 +416,6 @@ protected:


        sp<InputDispatcher> mDispatcher;
        sp<InputDispatcher> mDispatcher;
        sp<InputChannel> mServerChannel, mClientChannel;
        sp<InputChannel> mServerChannel, mClientChannel;
        sp<IBinder> mToken;
        InputConsumer *mConsumer;
        InputConsumer *mConsumer;
        PreallocatedInputEventFactory mEventFactory;
        PreallocatedInputEventFactory mEventFactory;


@@ -776,8 +775,10 @@ TEST_F(InputDispatcherFocusOnTwoDisplaysTest, SetInputWindow_MultiDisplayFocus)
class FakeMonitorReceiver : public FakeInputReceiver, public RefBase {
class FakeMonitorReceiver : public FakeInputReceiver, public RefBase {
public:
public:
    FakeMonitorReceiver(const sp<InputDispatcher>& dispatcher, const std::string name,
    FakeMonitorReceiver(const sp<InputDispatcher>& dispatcher, const std::string name,
            int32_t displayId) : FakeInputReceiver(dispatcher, name, displayId) {
            int32_t displayId, bool isGestureMonitor = false)
        mDispatcher->registerInputChannel(mServerChannel, displayId);
            : FakeInputReceiver(dispatcher, name, displayId) {
        mServerChannel->setToken(new BBinder());
        mDispatcher->registerInputMonitor(mServerChannel, displayId, isGestureMonitor);
    }
    }
};
};