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

Commit dd8b0c90 authored by Jeff Brown's avatar Jeff Brown Committed by Android Git Automerger
Browse files

am 41aabeb5: am 1e6a3a53: Merge "Added more robust tracking and cancelation of...

am 41aabeb5: am 1e6a3a53: Merge "Added more robust tracking and cancelation of events." into gingerbread

Merge commit '41aabeb5'

* commit '41aabeb5':
  Added more robust tracking and cancelation of events.
parents 5d3f6073 41aabeb5
Loading
Loading
Loading
Loading
+6 −4
Original line number Original line Diff line number Diff line
@@ -46,10 +46,12 @@ import android.view.KeyCharacterMap.KeyData;
 * with the special action {@link #ACTION_MULTIPLE} that either specifies
 * with the special action {@link #ACTION_MULTIPLE} that either specifies
 * that single repeated key code or a sequence of characters to insert.
 * that single repeated key code or a sequence of characters to insert.
 * </p><p>
 * </p><p>
 * In general, the framework makes no guarantees that the key events delivered
 * In general, the framework cannot guarantee that the key events it delivers
 * to a view constitute a complete key press.  In particular, there is no
 * to a view always constitute complete key sequences since some events may be dropped
 * guarantee that a view will always receive a key event with {@link #ACTION_UP}
 * or modified by containing views before they are delivered.  The view implementation
 * for each {@link #ACTION_DOWN} that was delivered.
 * should be prepared to handle {@link #FLAG_CANCELED} and should tolerate anomalous
 * situations such as receiving a new {@link #ACTION_DOWN} without first having
 * received an {@link #ACTION_UP} for the prior key press.
 * </p><p>
 * </p><p>
 * Refer to {@link InputDevice} for more information about how different kinds of
 * Refer to {@link InputDevice} for more information about how different kinds of
 * input devices and sources represent keys and buttons.
 * input devices and sources represent keys and buttons.
+6 −4
Original line number Original line Diff line number Diff line
@@ -82,10 +82,12 @@ import android.os.SystemClock;
 *     }
 *     }
 * }
 * }
 * </code></pre></p><p>
 * </code></pre></p><p>
 * In general, the framework makes no guarantees that the motion events delivered
 * In general, the framework cannot guarantee that the motion events it delivers
 * to a view constitute a complete gesture.  In particular, there is no
 * to a view always constitute a complete motion sequences since some events may be dropped
 * guarantee that a view will always receive a motion event with {@link #ACTION_UP}
 * or modified by containing views before they are delivered.  The view implementation
 * for each {@link #ACTION_DOWN} that was delivered.
 * should be prepared to handle {@link #ACTION_CANCEL} and should tolerate anomalous
 * situations such as receiving a new {@link #ACTION_DOWN} without first having
 * received an {@link #ACTION_UP} for the prior gesture.
 * </p><p>
 * </p><p>
 * Refer to {@link InputDevice} for more information about how different kinds of
 * Refer to {@link InputDevice} for more information about how different kinds of
 * input devices and sources represent pointer coordinates.
 * input devices and sources represent pointer coordinates.
+2 −0
Original line number Original line Diff line number Diff line
@@ -65,6 +65,7 @@ import android.view.animation.Animation;
 * @hide
 * @hide
 */
 */
public interface WindowManagerPolicy {
public interface WindowManagerPolicy {
    // Policy flags.  These flags are also defined in frameworks/base/include/ui/Input.h.
    public final static int FLAG_WAKE = 0x00000001;
    public final static int FLAG_WAKE = 0x00000001;
    public final static int FLAG_WAKE_DROPPED = 0x00000002;
    public final static int FLAG_WAKE_DROPPED = 0x00000002;
    public final static int FLAG_SHIFT = 0x00000004;
    public final static int FLAG_SHIFT = 0x00000004;
@@ -79,6 +80,7 @@ public interface WindowManagerPolicy {


    public final static int FLAG_WOKE_HERE = 0x10000000;
    public final static int FLAG_WOKE_HERE = 0x10000000;
    public final static int FLAG_BRIGHT_HERE = 0x20000000;
    public final static int FLAG_BRIGHT_HERE = 0x20000000;
    public final static int FLAG_PASS_TO_USER = 0x40000000;


    public final static boolean WATCH_POINTER = false;
    public final static boolean WATCH_POINTER = false;


+7 −0
Original line number Original line Diff line number Diff line
@@ -71,6 +71,8 @@ namespace android {
/*
/*
 * Flags that flow alongside events in the input dispatch system to help with certain
 * Flags that flow alongside events in the input dispatch system to help with certain
 * policy decisions such as waking from device sleep.
 * policy decisions such as waking from device sleep.
 *
 * These flags are also defined in frameworks/base/core/java/android/view/WindowManagerPolicy.java.
 */
 */
enum {
enum {
    /* These flags originate in RawEvents and are generally set in the key map.
    /* These flags originate in RawEvents and are generally set in the key map.
@@ -102,6 +104,11 @@ enum {
    // Indicates that the screen was dim when the event was received and the event
    // Indicates that the screen was dim when the event was received and the event
    // should brighten the device.
    // should brighten the device.
    POLICY_FLAG_BRIGHT_HERE = 0x20000000,
    POLICY_FLAG_BRIGHT_HERE = 0x20000000,

    // Indicates that the event should be dispatched to applications.
    // The input event should still be sent to the InputDispatcher so that it can see all
    // input events received include those that it will not deliver.
    POLICY_FLAG_PASS_TO_USER = 0x40000000,
};
};


/*
/*
+67 −23
Original line number Original line Diff line number Diff line
@@ -282,10 +282,35 @@ public:
     */
     */
    virtual int32_t getMaxEventsPerSecond() = 0;
    virtual int32_t getMaxEventsPerSecond() = 0;


    /* Intercepts a key event immediately before queueing it.
     * The policy can use this method as an opportunity to perform power management functions
     * and early event preprocessing such as updating policy flags.
     *
     * This method is expected to set the POLICY_FLAG_PASS_TO_USER policy flag if the event
     * should be dispatched to applications.
     */
    virtual void interceptKeyBeforeQueueing(nsecs_t when, int32_t deviceId,
            int32_t action, int32_t& flags, int32_t keyCode, int32_t scanCode,
            uint32_t& policyFlags) = 0;

    /* Intercepts a generic touch, trackball or other event before queueing it.
     * The policy can use this method as an opportunity to perform power management functions
     * and early event preprocessing such as updating policy flags.
     *
     * This method is expected to set the POLICY_FLAG_PASS_TO_USER policy flag if the event
     * should be dispatched to applications.
     */
    virtual void interceptGenericBeforeQueueing(nsecs_t when, uint32_t& policyFlags) = 0;

    /* Allows the policy a chance to intercept a key before dispatching. */
    /* Allows the policy a chance to intercept a key before dispatching. */
    virtual bool interceptKeyBeforeDispatching(const sp<InputChannel>& inputChannel,
    virtual bool interceptKeyBeforeDispatching(const sp<InputChannel>& inputChannel,
            const KeyEvent* keyEvent, uint32_t policyFlags) = 0;
            const KeyEvent* keyEvent, uint32_t policyFlags) = 0;


    /* Notifies the policy about switch events.
     */
    virtual void notifySwitch(nsecs_t when,
            int32_t switchCode, int32_t switchValue, uint32_t policyFlags) = 0;

    /* Poke user activity for an event dispatched to a window. */
    /* Poke user activity for an event dispatched to a window. */
    virtual void pokeUserActivity(nsecs_t eventTime, int32_t eventType) = 0;
    virtual void pokeUserActivity(nsecs_t eventTime, int32_t eventType) = 0;


@@ -333,6 +358,8 @@ public:
            int32_t metaState, int32_t edgeFlags,
            int32_t metaState, int32_t edgeFlags,
            uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
            uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
            float xPrecision, float yPrecision, nsecs_t downTime) = 0;
            float xPrecision, float yPrecision, nsecs_t downTime) = 0;
    virtual void notifySwitch(nsecs_t when,
            int32_t switchCode, int32_t switchValue, uint32_t policyFlags) = 0;


    /* Injects an input event and optionally waits for sync.
    /* Injects an input event and optionally waits for sync.
     * The synchronization mode determines whether the method blocks while waiting for
     * The synchronization mode determines whether the method blocks while waiting for
@@ -416,6 +443,8 @@ public:
            int32_t metaState, int32_t edgeFlags,
            int32_t metaState, int32_t edgeFlags,
            uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
            uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
            float xPrecision, float yPrecision, nsecs_t downTime);
            float xPrecision, float yPrecision, nsecs_t downTime);
    virtual void notifySwitch(nsecs_t when,
            int32_t switchCode, int32_t switchValue, uint32_t policyFlags) ;


    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);
@@ -458,6 +487,7 @@ private:
        mutable int32_t refCount;
        mutable int32_t refCount;
        int32_t type;
        int32_t type;
        nsecs_t eventTime;
        nsecs_t eventTime;
        uint32_t policyFlags;
        InjectionState* injectionState;
        InjectionState* injectionState;


        bool dispatchInProgress; // initially false, set to true while dispatching
        bool dispatchInProgress; // initially false, set to true while dispatching
@@ -471,7 +501,6 @@ private:
    struct KeyEntry : EventEntry {
    struct KeyEntry : EventEntry {
        int32_t deviceId;
        int32_t deviceId;
        int32_t source;
        int32_t source;
        uint32_t policyFlags;
        int32_t action;
        int32_t action;
        int32_t flags;
        int32_t flags;
        int32_t keyCode;
        int32_t keyCode;
@@ -500,7 +529,6 @@ private:
    struct MotionEntry : EventEntry {
    struct MotionEntry : EventEntry {
        int32_t deviceId;
        int32_t deviceId;
        int32_t source;
        int32_t source;
        uint32_t policyFlags;
        int32_t action;
        int32_t action;
        int32_t flags;
        int32_t flags;
        int32_t metaState;
        int32_t metaState;
@@ -675,7 +703,8 @@ private:
        Pool<DispatchEntry> mDispatchEntryPool;
        Pool<DispatchEntry> mDispatchEntryPool;
        Pool<CommandEntry> mCommandEntryPool;
        Pool<CommandEntry> mCommandEntryPool;


        void initializeEventEntry(EventEntry* entry, int32_t type, nsecs_t eventTime);
        void initializeEventEntry(EventEntry* entry, int32_t type, nsecs_t eventTime,
                uint32_t policyFlags);
        void releaseEventEntryInjectionState(EventEntry* entry);
        void releaseEventEntryInjectionState(EventEntry* entry);
    };
    };


@@ -696,21 +725,19 @@ private:
            BROKEN
            BROKEN
        };
        };


        // Specifies the sources to cancel.
        enum CancelationOptions {
            CANCEL_ALL_EVENTS = 0,
            CANCEL_POINTER_EVENTS = 1,
            CANCEL_NON_POINTER_EVENTS = 2,
        };

        InputState();
        InputState();
        ~InputState();
        ~InputState();


        // Returns true if there is no state to be canceled.
        // Returns true if there is no state to be canceled.
        bool isNeutral() const;
        bool isNeutral() const;


        // Returns true if the input state believes it is out of sync.
        bool isOutOfSync() const;

        // Sets the input state to be out of sync if it is not neutral.
        void setOutOfSync();

        // Resets the input state out of sync flag.
        void resetOutOfSync();

        // Records tracking information for an event that has just been published.
        // Records tracking information for an event that has just been published.
        // Returns whether the event is consistent with the current input state.
        // Returns whether the event is consistent with the current input state.
        Consistency trackEvent(const EventEntry* entry);
        Consistency trackEvent(const EventEntry* entry);
@@ -723,16 +750,14 @@ private:
        // Returns whether the event is consistent with the current input state.
        // Returns whether the event is consistent with the current input state.
        Consistency trackMotion(const MotionEntry* entry);
        Consistency trackMotion(const MotionEntry* entry);


        // Synthesizes cancelation events for the current state.
        // Synthesizes cancelation events for the current state and resets the tracked state.
        void synthesizeCancelationEvents(Allocator* allocator,
        void synthesizeCancelationEvents(nsecs_t currentTime, Allocator* allocator,
                Vector<EventEntry*>& outEvents) const;
                Vector<EventEntry*>& outEvents, CancelationOptions options);


        // Clears the current state.
        // Clears the current state.
        void clear();
        void clear();


    private:
    private:
        bool mIsOutOfSync;

        struct KeyMemento {
        struct KeyMemento {
            int32_t deviceId;
            int32_t deviceId;
            int32_t source;
            int32_t source;
@@ -756,6 +781,8 @@ private:


        Vector<KeyMemento> mKeyMementos;
        Vector<KeyMemento> mKeyMementos;
        Vector<MotionMemento> mMotionMementos;
        Vector<MotionMemento> mMotionMementos;

        static bool shouldCancelEvent(int32_t eventSource, CancelationOptions options);
    };
    };


    /* Manages the dispatch state associated with a single input channel. */
    /* Manages the dispatch state associated with a single input channel. */
@@ -805,6 +832,13 @@ private:
        status_t initialize();
        status_t initialize();
    };
    };


    enum DropReason {
        DROP_REASON_NOT_DROPPED = 0,
        DROP_REASON_POLICY = 1,
        DROP_REASON_APP_SWITCH = 2,
        DROP_REASON_DISABLED = 3,
    };

    sp<InputDispatcherPolicyInterface> mPolicy;
    sp<InputDispatcherPolicyInterface> mPolicy;


    Mutex mLock;
    Mutex mLock;
@@ -824,12 +858,16 @@ private:
    // Enqueues an inbound event.  Returns true if mLooper->wake() should be called.
    // Enqueues an inbound event.  Returns true if mLooper->wake() should be called.
    bool enqueueInboundEventLocked(EventEntry* entry);
    bool enqueueInboundEventLocked(EventEntry* entry);


    // Cleans up input state when dropping an inbound event.
    void dropInboundEventLocked(EventEntry* entry, DropReason dropReason);

    // App switch latency optimization.
    // App switch latency optimization.
    bool mAppSwitchSawKeyDown;
    nsecs_t mAppSwitchDueTime;
    nsecs_t mAppSwitchDueTime;


    static bool isAppSwitchKey(int32_t keyCode);
    static bool isAppSwitchKeyCode(int32_t keyCode);
    bool isAppSwitchKeyEventLocked(KeyEntry* keyEntry);
    bool isAppSwitchPendingLocked();
    bool isAppSwitchPendingLocked();
    bool detectPendingAppSwitchLocked(KeyEntry* inboundKeyEntry);
    void resetPendingAppSwitchLocked(bool handled);
    void resetPendingAppSwitchLocked(bool handled);


    // All registered connections mapped by receive pipe file descriptor.
    // All registered connections mapped by receive pipe file descriptor.
@@ -851,7 +889,7 @@ private:


    // Event injection and synchronization.
    // Event injection and synchronization.
    Condition mInjectionResultAvailableCondition;
    Condition mInjectionResultAvailableCondition;
    EventEntry* createEntryFromInjectedInputEventLocked(const InputEvent* event);
    bool hasInjectionPermission(int32_t injectorPid, int32_t injectorUid);
    void setInjectionResultLocked(EventEntry* entry, int32_t injectionResult);
    void setInjectionResultLocked(EventEntry* entry, int32_t injectionResult);


    Condition mInjectionSyncFinishedCondition;
    Condition mInjectionSyncFinishedCondition;
@@ -886,7 +924,7 @@ private:
    void drainInboundQueueLocked();
    void drainInboundQueueLocked();
    void releasePendingEventLocked();
    void releasePendingEventLocked();
    void releaseInboundEventLocked(EventEntry* entry);
    void releaseInboundEventLocked(EventEntry* entry);
    bool isEventFromReliableSourceLocked(EventEntry* entry);
    bool isEventFromTrustedSourceLocked(EventEntry* entry);


    // Dispatch state.
    // Dispatch state.
    bool mDispatchEnabled;
    bool mDispatchEnabled;
@@ -995,11 +1033,17 @@ private:
    void startDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection);
    void startDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection);
    void finishDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection);
    void finishDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection);
    void startNextDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection);
    void startNextDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection);
    void abortDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection,
    void abortBrokenDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection);
            bool broken);
    void drainOutboundQueueLocked(Connection* connection);
    void drainOutboundQueueLocked(Connection* connection);
    static int handleReceiveCallback(int receiveFd, int events, void* data);
    static int handleReceiveCallback(int receiveFd, int events, void* data);


    void synthesizeCancelationEventsForAllConnectionsLocked(
            InputState::CancelationOptions options, const char* reason);
    void synthesizeCancelationEventsForInputChannelLocked(const sp<InputChannel>& channel,
            InputState::CancelationOptions options, const char* reason);
    void synthesizeCancelationEventsForConnectionLocked(const sp<Connection>& connection,
            InputState::CancelationOptions options, const char* reason);

    // Splitting motion events across windows.
    // Splitting motion events across windows.
    MotionEntry* splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds);
    MotionEntry* splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds);


Loading