Loading include/ui/Input.h +8 −0 Original line number Diff line number Diff line Loading @@ -40,9 +40,17 @@ enum { /* * Maximum number of pointers supported per motion event. * Smallest number of pointers is 1. */ #define MAX_POINTERS 10 /* * Maximum pointer id value supported in a motion event. * Smallest pointer id is 0. * (This is limited by our use of BitSet32 to track pointer assignments.) */ #define MAX_POINTER_ID 31 /* * Declare a concrete type for the NDK's input event forward declaration. */ Loading include/ui/InputDispatcher.h +76 −46 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ #include <utils/String8.h> #include <utils/Looper.h> #include <utils/Pool.h> #include <utils/BitSet.h> #include <stddef.h> #include <unistd.h> Loading Loading @@ -89,17 +90,13 @@ struct InputTarget { * AMOTION_EVENT_ACTION_OUTSIDE to this target. */ FLAG_OUTSIDE = 0x02, /* This flag indicates that a KeyEvent or MotionEvent is being canceled. * In the case of a key event, it should be delivered with flag * AKEY_EVENT_FLAG_CANCELED set. * In the case of a motion event, it should be delivered with action * AMOTION_EVENT_ACTION_CANCEL instead. */ FLAG_CANCEL = 0x04, /* This flag indicates that the target of a MotionEvent is partly or wholly * obscured by another visible window above it. The motion event should be * delivered with flag AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED. */ FLAG_WINDOW_IS_OBSCURED = 0x08, FLAG_WINDOW_IS_OBSCURED = 0x04, /* This flag indicates that a motion event is being split across multiple windows. */ FLAG_SPLIT = 0x08, }; // The input channel to be targeted. Loading @@ -111,6 +108,13 @@ struct InputTarget { // The x and y offset to add to a MotionEvent as it is delivered. // (ignored for KeyEvents) float xOffset, yOffset; // The window type of the input target. int32_t windowType; // The subset of pointer ids to include in motion events dispatched to this input target // if FLAG_SPLIT is set. BitSet32 pointerIds; }; Loading Loading @@ -143,7 +147,7 @@ struct InputWindow { FLAG_SHOW_WALLPAPER = 0x00100000, FLAG_TURN_SCREEN_ON = 0x00200000, FLAG_DISMISS_KEYGUARD = 0x00400000, FLAG_IMMERSIVE = 0x00800000, FLAG_SPLIT_TOUCH = 0x00800000, FLAG_KEEP_SURFACE_WHILE_ANIMATING = 0x10000000, FLAG_COMPATIBLE_WINDOW = 0x20000000, FLAG_SYSTEM_ERROR = 0x40000000, Loading Loading @@ -276,7 +280,7 @@ public: const KeyEvent* keyEvent, uint32_t policyFlags) = 0; /* Poke user activity for an event dispatched to a window. */ virtual void pokeUserActivity(nsecs_t eventTime, int32_t windowType, int32_t eventType) = 0; virtual void pokeUserActivity(nsecs_t eventTime, int32_t eventType) = 0; /* Checks whether a given application pid/uid has permission to inject input events * into other applications. Loading Loading @@ -415,6 +419,16 @@ private: T* prev; }; struct InjectionState { mutable int32_t refCount; int32_t injectorPid; int32_t injectorUid; int32_t injectionResult; // initially INPUT_EVENT_INJECTION_PENDING bool injectionIsAsync; // set to true if injection is not waiting for the result int32_t pendingForegroundDispatches; // the number of foreground dispatches in progress }; struct EventEntry : Link<EventEntry> { enum { TYPE_SENTINEL, Loading @@ -423,21 +437,14 @@ private: TYPE_MOTION }; int32_t refCount; mutable int32_t refCount; int32_t type; nsecs_t eventTime; int32_t injectionResult; // initially INPUT_EVENT_INJECTION_PENDING bool injectionIsAsync; // set to true if injection is not waiting for the result int32_t injectorPid; // -1 if not injected int32_t injectorUid; // -1 if not injected InjectionState* injectionState; bool dispatchInProgress; // initially false, set to true while dispatching int32_t pendingForegroundDispatches; // the number of foreground dispatches in progress inline bool isInjected() { return injectorPid >= 0; } void recycle(); inline bool isInjected() { return injectionState != NULL; } }; struct ConfigurationChangedEntry : EventEntry { Loading @@ -463,8 +470,6 @@ private: INTERCEPT_KEY_RESULT_CONTINUE, }; InterceptKeyResult interceptKeyResult; // set based on the interception result void recycle(); }; struct MotionSample { Loading Loading @@ -521,6 +526,10 @@ private: inline bool hasForegroundTarget() const { return targetFlags & InputTarget::FLAG_FOREGROUND; } inline bool isSplit() const { return targetFlags & InputTarget::FLAG_SPLIT; } }; // A command entry captures state and behavior for an action to be performed in the Loading Loading @@ -555,7 +564,6 @@ private: KeyEntry* keyEntry; sp<InputChannel> inputChannel; sp<InputApplicationHandle> inputApplicationHandle; int32_t windowType; int32_t userActivityEventType; }; Loading Loading @@ -611,6 +619,7 @@ private: public: Allocator(); InjectionState* obtainInjectionState(int32_t injectorPid, int32_t injectorUid); ConfigurationChangedEntry* obtainConfigurationChangedEntry(nsecs_t eventTime); KeyEntry* obtainKeyEntry(nsecs_t eventTime, int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action, Loading @@ -626,6 +635,7 @@ private: int32_t targetFlags, float xOffset, float yOffset); CommandEntry* obtainCommandEntry(Command command); void releaseInjectionState(InjectionState* injectionState); void releaseEventEntry(EventEntry* entry); void releaseConfigurationChangedEntry(ConfigurationChangedEntry* entry); void releaseKeyEntry(KeyEntry* entry); Loading @@ -633,10 +643,13 @@ private: void releaseDispatchEntry(DispatchEntry* entry); void releaseCommandEntry(CommandEntry* entry); void recycleKeyEntry(KeyEntry* entry); void appendMotionSample(MotionEntry* motionEntry, nsecs_t eventTime, const PointerCoords* pointerCoords); private: Pool<InjectionState> mInjectionStatePool; Pool<ConfigurationChangedEntry> mConfigurationChangeEntryPool; Pool<KeyEntry> mKeyEntryPool; Pool<MotionEntry> mMotionEntryPool; Loading @@ -645,6 +658,7 @@ private: Pool<CommandEntry> mCommandEntryPool; void initializeEventEntry(EventEntry* entry, int32_t type, nsecs_t eventTime); void releaseEventEntryInjectionState(EventEntry* entry); }; /* Tracks dispatched key and motion event state so that cancelation events can be Loading Loading @@ -823,6 +837,7 @@ private: void setInjectionResultLocked(EventEntry* entry, int32_t injectionResult); Condition mInjectionSyncFinishedCondition; void incrementPendingForegroundDispatchesLocked(EventEntry* entry); void decrementPendingForegroundDispatchesLocked(EventEntry* entry); // Throttling state. Loading Loading @@ -858,23 +873,37 @@ private: // Dispatch state. bool mDispatchEnabled; bool mDispatchFrozen; Vector<InputWindow> mWindows; Vector<InputWindow*> mWallpaperWindows; const InputWindow* getWindowLocked(const sp<InputChannel>& inputChannel); // Focus tracking for keys, trackball, etc. InputWindow* mFocusedWindow; const InputWindow* mFocusedWindow; // Focus tracking for touch. bool mTouchDown; InputWindow* mTouchedWindow; // primary target for current down bool mTouchedWindowIsObscured; // true if other windows may obscure the target Vector<InputWindow*> mTouchedWallpaperWindows; // wallpaper targets struct OutsideTarget { InputWindow* window; bool obscured; struct TouchedWindow { const InputWindow* window; int32_t targetFlags; BitSet32 pointerIds; sp<InputChannel> channel; }; Vector<OutsideTarget> mTempTouchedOutsideTargets; // temporary outside touch targets Vector<sp<InputChannel> > mTempTouchedWallpaperChannels; // temporary wallpaper targets struct TouchState { bool down; bool split; Vector<TouchedWindow> windows; TouchState(); ~TouchState(); void reset(); void copyFrom(const TouchState& other); void addOrUpdateWindow(const InputWindow* window, int32_t targetFlags, BitSet32 pointerIds); void removeOutsideTouchWindows(); const InputWindow* getFirstForegroundWindow(); }; TouchState mTouchState; TouchState mTempTouchState; // Focused application. InputApplication* mFocusedApplication; Loading @@ -899,8 +928,6 @@ private: // The input targets that were most recently identified for dispatch. bool mCurrentInputTargetsValid; // false while targets are being recomputed Vector<InputTarget> mCurrentInputTargets; int32_t mCurrentInputWindowType; sp<InputChannel> mCurrentInputChannel; enum InputTargetWaitCause { INPUT_TARGET_WAIT_CAUSE_NONE, Loading @@ -915,7 +942,7 @@ private: // Finding targets for input events. void resetTargetsLocked(); void commitTargetsLocked(const InputWindow* window); void commitTargetsLocked(); int32_t handleTargetsNotReadyLocked(nsecs_t currentTime, const EventEntry* entry, const InputApplication* application, const InputWindow* window, nsecs_t* nextWakeupTime); Loading @@ -924,19 +951,19 @@ private: nsecs_t getTimeSpentWaitingForApplicationLocked(nsecs_t currentTime); void resetANRTimeoutsLocked(); int32_t findFocusedWindowLocked(nsecs_t currentTime, const EventEntry* entry, nsecs_t* nextWakeupTime, InputWindow** outWindow); int32_t findTouchedWindowLocked(nsecs_t currentTime, const MotionEntry* entry, nsecs_t* nextWakeupTime, InputWindow** outWindow); int32_t findFocusedWindowTargetsLocked(nsecs_t currentTime, const EventEntry* entry, nsecs_t* nextWakeupTime); int32_t findTouchedWindowTargetsLocked(nsecs_t currentTime, const MotionEntry* entry, nsecs_t* nextWakeupTime); void addWindowTargetLocked(const InputWindow* window, int32_t targetFlags); void addWindowTargetLocked(const InputWindow* window, int32_t targetFlags, BitSet32 pointerIds); void addMonitoringTargetsLocked(); void pokeUserActivityLocked(nsecs_t eventTime, int32_t windowType, int32_t eventType); bool checkInjectionPermission(const InputWindow* window, int32_t injectorPid, int32_t injectorUid); bool shouldPokeUserActivityForCurrentInputTargetsLocked(); void pokeUserActivityLocked(nsecs_t eventTime, int32_t eventType); bool checkInjectionPermission(const InputWindow* window, const InjectionState* injectionState); bool isWindowObscuredLocked(const InputWindow* window); bool isWindowFinishedWithPreviousInputLocked(const InputWindow* window); void releaseTouchedWindowLocked(); String8 getApplicationWindowLabelLocked(const InputApplication* application, const InputWindow* window); Loading @@ -955,6 +982,9 @@ private: void drainOutboundQueueLocked(Connection* connection); static int handleReceiveCallback(int receiveFd, int events, void* data); // Splitting motion events across windows. MotionEntry* splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds); // Dump state. void dumpDispatchStateLocked(String8& dump); void logDispatchStateLocked(); Loading include/ui/InputReader.h +0 −4 Original line number Diff line number Diff line Loading @@ -549,10 +549,6 @@ public: const int32_t* keyCodes, uint8_t* outFlags); protected: /* Maximum pointer id value supported. * (This is limited by our use of BitSet32 to track pointer assignments.) */ static const uint32_t MAX_POINTER_ID = 31; Mutex mLock; struct VirtualKey { Loading include/utils/BitSet.h +3 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,9 @@ struct BitSet32 { // Clears the bit set. inline void clear() { value = 0; } // Returns the number of marked bits in the set. inline uint32_t count() const { return __builtin_popcount(value); } // Returns true if the bit set does not contain any marked bits. inline bool isEmpty() const { return ! value; } Loading Loading
include/ui/Input.h +8 −0 Original line number Diff line number Diff line Loading @@ -40,9 +40,17 @@ enum { /* * Maximum number of pointers supported per motion event. * Smallest number of pointers is 1. */ #define MAX_POINTERS 10 /* * Maximum pointer id value supported in a motion event. * Smallest pointer id is 0. * (This is limited by our use of BitSet32 to track pointer assignments.) */ #define MAX_POINTER_ID 31 /* * Declare a concrete type for the NDK's input event forward declaration. */ Loading
include/ui/InputDispatcher.h +76 −46 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ #include <utils/String8.h> #include <utils/Looper.h> #include <utils/Pool.h> #include <utils/BitSet.h> #include <stddef.h> #include <unistd.h> Loading Loading @@ -89,17 +90,13 @@ struct InputTarget { * AMOTION_EVENT_ACTION_OUTSIDE to this target. */ FLAG_OUTSIDE = 0x02, /* This flag indicates that a KeyEvent or MotionEvent is being canceled. * In the case of a key event, it should be delivered with flag * AKEY_EVENT_FLAG_CANCELED set. * In the case of a motion event, it should be delivered with action * AMOTION_EVENT_ACTION_CANCEL instead. */ FLAG_CANCEL = 0x04, /* This flag indicates that the target of a MotionEvent is partly or wholly * obscured by another visible window above it. The motion event should be * delivered with flag AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED. */ FLAG_WINDOW_IS_OBSCURED = 0x08, FLAG_WINDOW_IS_OBSCURED = 0x04, /* This flag indicates that a motion event is being split across multiple windows. */ FLAG_SPLIT = 0x08, }; // The input channel to be targeted. Loading @@ -111,6 +108,13 @@ struct InputTarget { // The x and y offset to add to a MotionEvent as it is delivered. // (ignored for KeyEvents) float xOffset, yOffset; // The window type of the input target. int32_t windowType; // The subset of pointer ids to include in motion events dispatched to this input target // if FLAG_SPLIT is set. BitSet32 pointerIds; }; Loading Loading @@ -143,7 +147,7 @@ struct InputWindow { FLAG_SHOW_WALLPAPER = 0x00100000, FLAG_TURN_SCREEN_ON = 0x00200000, FLAG_DISMISS_KEYGUARD = 0x00400000, FLAG_IMMERSIVE = 0x00800000, FLAG_SPLIT_TOUCH = 0x00800000, FLAG_KEEP_SURFACE_WHILE_ANIMATING = 0x10000000, FLAG_COMPATIBLE_WINDOW = 0x20000000, FLAG_SYSTEM_ERROR = 0x40000000, Loading Loading @@ -276,7 +280,7 @@ public: const KeyEvent* keyEvent, uint32_t policyFlags) = 0; /* Poke user activity for an event dispatched to a window. */ virtual void pokeUserActivity(nsecs_t eventTime, int32_t windowType, int32_t eventType) = 0; virtual void pokeUserActivity(nsecs_t eventTime, int32_t eventType) = 0; /* Checks whether a given application pid/uid has permission to inject input events * into other applications. Loading Loading @@ -415,6 +419,16 @@ private: T* prev; }; struct InjectionState { mutable int32_t refCount; int32_t injectorPid; int32_t injectorUid; int32_t injectionResult; // initially INPUT_EVENT_INJECTION_PENDING bool injectionIsAsync; // set to true if injection is not waiting for the result int32_t pendingForegroundDispatches; // the number of foreground dispatches in progress }; struct EventEntry : Link<EventEntry> { enum { TYPE_SENTINEL, Loading @@ -423,21 +437,14 @@ private: TYPE_MOTION }; int32_t refCount; mutable int32_t refCount; int32_t type; nsecs_t eventTime; int32_t injectionResult; // initially INPUT_EVENT_INJECTION_PENDING bool injectionIsAsync; // set to true if injection is not waiting for the result int32_t injectorPid; // -1 if not injected int32_t injectorUid; // -1 if not injected InjectionState* injectionState; bool dispatchInProgress; // initially false, set to true while dispatching int32_t pendingForegroundDispatches; // the number of foreground dispatches in progress inline bool isInjected() { return injectorPid >= 0; } void recycle(); inline bool isInjected() { return injectionState != NULL; } }; struct ConfigurationChangedEntry : EventEntry { Loading @@ -463,8 +470,6 @@ private: INTERCEPT_KEY_RESULT_CONTINUE, }; InterceptKeyResult interceptKeyResult; // set based on the interception result void recycle(); }; struct MotionSample { Loading Loading @@ -521,6 +526,10 @@ private: inline bool hasForegroundTarget() const { return targetFlags & InputTarget::FLAG_FOREGROUND; } inline bool isSplit() const { return targetFlags & InputTarget::FLAG_SPLIT; } }; // A command entry captures state and behavior for an action to be performed in the Loading Loading @@ -555,7 +564,6 @@ private: KeyEntry* keyEntry; sp<InputChannel> inputChannel; sp<InputApplicationHandle> inputApplicationHandle; int32_t windowType; int32_t userActivityEventType; }; Loading Loading @@ -611,6 +619,7 @@ private: public: Allocator(); InjectionState* obtainInjectionState(int32_t injectorPid, int32_t injectorUid); ConfigurationChangedEntry* obtainConfigurationChangedEntry(nsecs_t eventTime); KeyEntry* obtainKeyEntry(nsecs_t eventTime, int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action, Loading @@ -626,6 +635,7 @@ private: int32_t targetFlags, float xOffset, float yOffset); CommandEntry* obtainCommandEntry(Command command); void releaseInjectionState(InjectionState* injectionState); void releaseEventEntry(EventEntry* entry); void releaseConfigurationChangedEntry(ConfigurationChangedEntry* entry); void releaseKeyEntry(KeyEntry* entry); Loading @@ -633,10 +643,13 @@ private: void releaseDispatchEntry(DispatchEntry* entry); void releaseCommandEntry(CommandEntry* entry); void recycleKeyEntry(KeyEntry* entry); void appendMotionSample(MotionEntry* motionEntry, nsecs_t eventTime, const PointerCoords* pointerCoords); private: Pool<InjectionState> mInjectionStatePool; Pool<ConfigurationChangedEntry> mConfigurationChangeEntryPool; Pool<KeyEntry> mKeyEntryPool; Pool<MotionEntry> mMotionEntryPool; Loading @@ -645,6 +658,7 @@ private: Pool<CommandEntry> mCommandEntryPool; void initializeEventEntry(EventEntry* entry, int32_t type, nsecs_t eventTime); void releaseEventEntryInjectionState(EventEntry* entry); }; /* Tracks dispatched key and motion event state so that cancelation events can be Loading Loading @@ -823,6 +837,7 @@ private: void setInjectionResultLocked(EventEntry* entry, int32_t injectionResult); Condition mInjectionSyncFinishedCondition; void incrementPendingForegroundDispatchesLocked(EventEntry* entry); void decrementPendingForegroundDispatchesLocked(EventEntry* entry); // Throttling state. Loading Loading @@ -858,23 +873,37 @@ private: // Dispatch state. bool mDispatchEnabled; bool mDispatchFrozen; Vector<InputWindow> mWindows; Vector<InputWindow*> mWallpaperWindows; const InputWindow* getWindowLocked(const sp<InputChannel>& inputChannel); // Focus tracking for keys, trackball, etc. InputWindow* mFocusedWindow; const InputWindow* mFocusedWindow; // Focus tracking for touch. bool mTouchDown; InputWindow* mTouchedWindow; // primary target for current down bool mTouchedWindowIsObscured; // true if other windows may obscure the target Vector<InputWindow*> mTouchedWallpaperWindows; // wallpaper targets struct OutsideTarget { InputWindow* window; bool obscured; struct TouchedWindow { const InputWindow* window; int32_t targetFlags; BitSet32 pointerIds; sp<InputChannel> channel; }; Vector<OutsideTarget> mTempTouchedOutsideTargets; // temporary outside touch targets Vector<sp<InputChannel> > mTempTouchedWallpaperChannels; // temporary wallpaper targets struct TouchState { bool down; bool split; Vector<TouchedWindow> windows; TouchState(); ~TouchState(); void reset(); void copyFrom(const TouchState& other); void addOrUpdateWindow(const InputWindow* window, int32_t targetFlags, BitSet32 pointerIds); void removeOutsideTouchWindows(); const InputWindow* getFirstForegroundWindow(); }; TouchState mTouchState; TouchState mTempTouchState; // Focused application. InputApplication* mFocusedApplication; Loading @@ -899,8 +928,6 @@ private: // The input targets that were most recently identified for dispatch. bool mCurrentInputTargetsValid; // false while targets are being recomputed Vector<InputTarget> mCurrentInputTargets; int32_t mCurrentInputWindowType; sp<InputChannel> mCurrentInputChannel; enum InputTargetWaitCause { INPUT_TARGET_WAIT_CAUSE_NONE, Loading @@ -915,7 +942,7 @@ private: // Finding targets for input events. void resetTargetsLocked(); void commitTargetsLocked(const InputWindow* window); void commitTargetsLocked(); int32_t handleTargetsNotReadyLocked(nsecs_t currentTime, const EventEntry* entry, const InputApplication* application, const InputWindow* window, nsecs_t* nextWakeupTime); Loading @@ -924,19 +951,19 @@ private: nsecs_t getTimeSpentWaitingForApplicationLocked(nsecs_t currentTime); void resetANRTimeoutsLocked(); int32_t findFocusedWindowLocked(nsecs_t currentTime, const EventEntry* entry, nsecs_t* nextWakeupTime, InputWindow** outWindow); int32_t findTouchedWindowLocked(nsecs_t currentTime, const MotionEntry* entry, nsecs_t* nextWakeupTime, InputWindow** outWindow); int32_t findFocusedWindowTargetsLocked(nsecs_t currentTime, const EventEntry* entry, nsecs_t* nextWakeupTime); int32_t findTouchedWindowTargetsLocked(nsecs_t currentTime, const MotionEntry* entry, nsecs_t* nextWakeupTime); void addWindowTargetLocked(const InputWindow* window, int32_t targetFlags); void addWindowTargetLocked(const InputWindow* window, int32_t targetFlags, BitSet32 pointerIds); void addMonitoringTargetsLocked(); void pokeUserActivityLocked(nsecs_t eventTime, int32_t windowType, int32_t eventType); bool checkInjectionPermission(const InputWindow* window, int32_t injectorPid, int32_t injectorUid); bool shouldPokeUserActivityForCurrentInputTargetsLocked(); void pokeUserActivityLocked(nsecs_t eventTime, int32_t eventType); bool checkInjectionPermission(const InputWindow* window, const InjectionState* injectionState); bool isWindowObscuredLocked(const InputWindow* window); bool isWindowFinishedWithPreviousInputLocked(const InputWindow* window); void releaseTouchedWindowLocked(); String8 getApplicationWindowLabelLocked(const InputApplication* application, const InputWindow* window); Loading @@ -955,6 +982,9 @@ private: void drainOutboundQueueLocked(Connection* connection); static int handleReceiveCallback(int receiveFd, int events, void* data); // Splitting motion events across windows. MotionEntry* splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds); // Dump state. void dumpDispatchStateLocked(String8& dump); void logDispatchStateLocked(); Loading
include/ui/InputReader.h +0 −4 Original line number Diff line number Diff line Loading @@ -549,10 +549,6 @@ public: const int32_t* keyCodes, uint8_t* outFlags); protected: /* Maximum pointer id value supported. * (This is limited by our use of BitSet32 to track pointer assignments.) */ static const uint32_t MAX_POINTER_ID = 31; Mutex mLock; struct VirtualKey { Loading
include/utils/BitSet.h +3 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,9 @@ struct BitSet32 { // Clears the bit set. inline void clear() { value = 0; } // Returns the number of marked bits in the set. inline uint32_t count() const { return __builtin_popcount(value); } // Returns true if the bit set does not contain any marked bits. inline bool isEmpty() const { return ! value; } Loading