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

Commit f817a6e0 authored by Jeff Brown's avatar Jeff Brown Committed by Android (Google) Code Review
Browse files

Merge "Added more robust tracking and cancelation of events." into gingerbread

parents c754c60a 90f0cee6
Loading
Loading
Loading
Loading
+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
@@ -408,6 +435,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);
@@ -447,6 +476,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
@@ -460,7 +490,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;
@@ -489,7 +518,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;
@@ -664,7 +692,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);
    };
    };


@@ -685,21 +714,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);
@@ -712,16 +739,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;
@@ -745,6 +770,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. */
@@ -794,6 +821,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;
@@ -813,12 +847,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.
@@ -840,7 +878,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;
@@ -875,7 +913,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;
@@ -984,11 +1022,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);


+0 −47
Original line number Original line Diff line number Diff line
@@ -87,49 +87,12 @@ public:
        ROTATION_270 = 3
        ROTATION_270 = 3
    };
    };


    /* Actions returned by interceptXXX methods. */
    enum {
        // The input dispatcher should do nothing and discard the input unless other
        // flags are set.
        ACTION_NONE = 0,

        // The input dispatcher should dispatch the input to the application.
        ACTION_DISPATCH = 0x00000001,
    };

    /* Gets information about the display with the specified id.
    /* Gets information about the display with the specified id.
     * Returns true if the display info is available, false otherwise.
     * Returns true if the display info is available, false otherwise.
     */
     */
    virtual bool getDisplayInfo(int32_t displayId,
    virtual bool getDisplayInfo(int32_t displayId,
            int32_t* width, int32_t* height, int32_t* orientation) = 0;
            int32_t* width, int32_t* height, int32_t* orientation) = 0;


    /* Intercepts a key event.
     * The policy can use this method as an opportunity to perform power management functions
     * and early event preprocessing such as updating policy flags.
     *
     * Returns a policy action constant such as ACTION_DISPATCH.
     */
    virtual int32_t interceptKey(nsecs_t when, int32_t deviceId,
            bool down, int32_t keyCode, int32_t scanCode, uint32_t& policyFlags) = 0;

    /* Intercepts a switch event.
     * The policy can use this method as an opportunity to perform power management functions
     * and early event preprocessing such as updating policy flags.
     *
     * Switches are not dispatched to applications so this method should
     * usually return ACTION_NONE.
     */
    virtual int32_t interceptSwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
            uint32_t& policyFlags) = 0;

    /* Intercepts a generic touch, trackball or other event.
     * The policy can use this method as an opportunity to perform power management functions
     * and early event preprocessing such as updating policy flags.
     *
     * Returns a policy action constant such as ACTION_DISPATCH.
     */
    virtual int32_t interceptGeneric(nsecs_t when, uint32_t& policyFlags) = 0;

    /* Determines whether to turn on some hacks we have to improve the touch interaction with a
    /* Determines whether to turn on some hacks we have to improve the touch interaction with a
     * certain device whose screen currently is not all that good.
     * certain device whose screen currently is not all that good.
     */
     */
@@ -403,8 +366,6 @@ public:
protected:
protected:
    InputDevice* mDevice;
    InputDevice* mDevice;
    InputReaderContext* mContext;
    InputReaderContext* mContext;

    bool applyStandardPolicyActions(nsecs_t when, int32_t policyActions);
};
};




@@ -466,8 +427,6 @@ private:


    void processKey(nsecs_t when, bool down, int32_t keyCode, int32_t scanCode,
    void processKey(nsecs_t when, bool down, int32_t keyCode, int32_t scanCode,
            uint32_t policyFlags);
            uint32_t policyFlags);
    void applyPolicyAndDispatch(nsecs_t when, uint32_t policyFlags,
            bool down, int32_t keyCode, int32_t scanCode, int32_t metaState, nsecs_t downTime);


    ssize_t findKeyDownLocked(int32_t scanCode);
    ssize_t findKeyDownLocked(int32_t scanCode);
};
};
@@ -525,8 +484,6 @@ private:
    void initializeLocked();
    void initializeLocked();


    void sync(nsecs_t when);
    void sync(nsecs_t when);
    void applyPolicyAndDispatch(nsecs_t when, int32_t motionEventAction,
            PointerCoords* pointerCoords, nsecs_t downTime);
};
};




@@ -829,10 +786,6 @@ private:
            BitSet32 idBits, uint32_t changedId, uint32_t pointerCount,
            BitSet32 idBits, uint32_t changedId, uint32_t pointerCount,
            int32_t motionEventAction);
            int32_t motionEventAction);


    void applyPolicyAndDispatchVirtualKey(nsecs_t when, uint32_t policyFlags,
            int32_t keyEventAction, int32_t keyEventFlags,
            int32_t keyCode, int32_t scanCode, nsecs_t downTime);

    bool isPointInsideSurfaceLocked(int32_t x, int32_t y);
    bool isPointInsideSurfaceLocked(int32_t x, int32_t y);
    const VirtualKey* findVirtualKeyHitLocked(int32_t x, int32_t y);
    const VirtualKey* findVirtualKeyHitLocked(int32_t x, int32_t y);


+379 −242

File changed.

Preview size limit exceeded, changes collapsed.

+10 −72
Original line number Original line Diff line number Diff line
@@ -796,10 +796,6 @@ int32_t InputMapper::getMetaState() {
    return 0;
    return 0;
}
}


bool InputMapper::applyStandardPolicyActions(nsecs_t when, int32_t policyActions) {
    return policyActions & InputReaderPolicyInterface::ACTION_DISPATCH;
}



// --- SwitchInputMapper ---
// --- SwitchInputMapper ---


@@ -823,11 +819,7 @@ void SwitchInputMapper::process(const RawEvent* rawEvent) {
}
}


void SwitchInputMapper::processSwitch(nsecs_t when, int32_t switchCode, int32_t switchValue) {
void SwitchInputMapper::processSwitch(nsecs_t when, int32_t switchCode, int32_t switchValue) {
    uint32_t policyFlags = 0;
    getDispatcher()->notifySwitch(when, switchCode, switchValue, 0);
    int32_t policyActions = getPolicy()->interceptSwitch(
            when, switchCode, switchValue, policyFlags);

    applyStandardPolicyActions(when, policyActions);
}
}


int32_t SwitchInputMapper::getSwitchState(uint32_t sourceMask, int32_t switchCode) {
int32_t SwitchInputMapper::getSwitchState(uint32_t sourceMask, int32_t switchCode) {
@@ -983,29 +975,9 @@ void KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t keyCode,
        getContext()->updateGlobalMetaState();
        getContext()->updateGlobalMetaState();
    }
    }


    applyPolicyAndDispatch(when, policyFlags, down, keyCode, scanCode, newMetaState, downTime);
}

void KeyboardInputMapper::applyPolicyAndDispatch(nsecs_t when, uint32_t policyFlags, bool down,
        int32_t keyCode, int32_t scanCode, int32_t metaState, nsecs_t downTime) {
    int32_t policyActions = getPolicy()->interceptKey(when,
            getDeviceId(), down, keyCode, scanCode, policyFlags);

    if (! applyStandardPolicyActions(when, policyActions)) {
        return; // event dropped
    }

    int32_t keyEventAction = down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP;
    int32_t keyEventFlags = AKEY_EVENT_FLAG_FROM_SYSTEM;
    if (policyFlags & POLICY_FLAG_WOKE_HERE) {
        keyEventFlags |= AKEY_EVENT_FLAG_WOKE_HERE;
    }
    if (policyFlags & POLICY_FLAG_VIRTUAL) {
        keyEventFlags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
    }

    getDispatcher()->notifyKey(when, getDeviceId(), AINPUT_SOURCE_KEYBOARD, policyFlags,
    getDispatcher()->notifyKey(when, getDeviceId(), AINPUT_SOURCE_KEYBOARD, policyFlags,
            keyEventAction, keyEventFlags, keyCode, scanCode, metaState, downTime);
            down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,
            AKEY_EVENT_FLAG_FROM_SYSTEM, keyCode, scanCode, newMetaState, downTime);
}
}


ssize_t KeyboardInputMapper::findKeyDownLocked(int32_t scanCode) {
ssize_t KeyboardInputMapper::findKeyDownLocked(int32_t scanCode) {
@@ -1215,26 +1187,13 @@ void TrackballInputMapper::sync(nsecs_t when) {
        }
        }
    } // release lock
    } // release lock


    applyPolicyAndDispatch(when, motionEventAction, & pointerCoords, downTime);

    mAccumulator.clear();
}

void TrackballInputMapper::applyPolicyAndDispatch(nsecs_t when, int32_t motionEventAction,
        PointerCoords* pointerCoords, nsecs_t downTime) {
    uint32_t policyFlags = 0;
    int32_t policyActions = getPolicy()->interceptGeneric(when, policyFlags);

    if (! applyStandardPolicyActions(when, policyActions)) {
        return; // event dropped
    }

    int32_t metaState = mContext->getGlobalMetaState();
    int32_t metaState = mContext->getGlobalMetaState();
    int32_t pointerId = 0;
    int32_t pointerId = 0;

    getDispatcher()->notifyMotion(when, getDeviceId(), AINPUT_SOURCE_TRACKBALL, 0,
    getDispatcher()->notifyMotion(when, getDeviceId(), AINPUT_SOURCE_TRACKBALL, policyFlags,
            motionEventAction, 0, metaState, AMOTION_EVENT_EDGE_FLAG_NONE,
            motionEventAction, 0, metaState, AMOTION_EVENT_EDGE_FLAG_NONE,
            1, & pointerId, pointerCoords, mXPrecision, mYPrecision, downTime);
            1, &pointerId, &pointerCoords, mXPrecision, mYPrecision, downTime);

    mAccumulator.clear();
}
}


int32_t TrackballInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
int32_t TrackballInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
@@ -2012,15 +1971,7 @@ void TouchInputMapper::reset() {
}
}


void TouchInputMapper::syncTouch(nsecs_t when, bool havePointerIds) {
void TouchInputMapper::syncTouch(nsecs_t when, bool havePointerIds) {
    // Apply generic policy actions.

    uint32_t policyFlags = 0;
    uint32_t policyFlags = 0;
    int32_t policyActions = getPolicy()->interceptGeneric(when, policyFlags);

    if (! applyStandardPolicyActions(when, policyActions)) {
        mLastTouch.clear();
        return; // event dropped
    }


    // Preprocess pointer data.
    // Preprocess pointer data.


@@ -2160,24 +2111,11 @@ TouchInputMapper::TouchResult TouchInputMapper::consumeOffScreenTouches(
    } // release lock
    } // release lock


    // Dispatch virtual key.
    // Dispatch virtual key.
    applyPolicyAndDispatchVirtualKey(when, policyFlags, keyEventAction, keyEventFlags,
            keyCode, scanCode, downTime);
    return touchResult;
}

void TouchInputMapper::applyPolicyAndDispatchVirtualKey(nsecs_t when, uint32_t policyFlags,
        int32_t keyEventAction, int32_t keyEventFlags,
        int32_t keyCode, int32_t scanCode, nsecs_t downTime) {
    int32_t metaState = mContext->getGlobalMetaState();
    int32_t metaState = mContext->getGlobalMetaState();

    policyFlags |= POLICY_FLAG_VIRTUAL;
    policyFlags |= POLICY_FLAG_VIRTUAL;
    int32_t policyActions = getPolicy()->interceptKey(when, getDeviceId(),
            keyEventAction == AKEY_EVENT_ACTION_DOWN, keyCode, scanCode, policyFlags);

    if (applyStandardPolicyActions(when, policyActions)) {
    getDispatcher()->notifyKey(when, getDeviceId(), AINPUT_SOURCE_KEYBOARD, policyFlags,
    getDispatcher()->notifyKey(when, getDeviceId(), AINPUT_SOURCE_KEYBOARD, policyFlags,
            keyEventAction, keyEventFlags, keyCode, scanCode, metaState, downTime);
            keyEventAction, keyEventFlags, keyCode, scanCode, metaState, downTime);
    }
    return touchResult;
}
}


void TouchInputMapper::dispatchTouches(nsecs_t when, uint32_t policyFlags) {
void TouchInputMapper::dispatchTouches(nsecs_t when, uint32_t policyFlags) {