diff options
author | Jeff Brown <jeffbrown@google.com> | 2010-09-26 22:20:12 -0700 |
---|---|---|
committer | Jeff Brown <jeffbrown@google.com> | 2010-09-26 22:20:12 -0700 |
commit | d1b0a2bfe50e61241fab6a571941c207232d9212 (patch) | |
tree | 68de1f752582e7cbdc4c4b46b2e97d2abcb2d11d /include | |
parent | a939afe2124b8e5be01be46f97b1bbf2fad5d65b (diff) | |
download | frameworks_native-d1b0a2bfe50e61241fab6a571941c207232d9212.zip frameworks_native-d1b0a2bfe50e61241fab6a571941c207232d9212.tar.gz frameworks_native-d1b0a2bfe50e61241fab6a571941c207232d9212.tar.bz2 |
Add suuport for splitting touch events across windows.
This feature is currently used to enable dragging the start and end
selection handles of a TextView at the same time. Could be used for
other things later.
Deleted some dead code in ArrowKeyMovementMethod and CursorControllers.
Change-Id: I930accd97ca1ca1917aab8a807db2c950fc7b409
Diffstat (limited to 'include')
-rw-r--r-- | include/ui/Input.h | 8 | ||||
-rw-r--r-- | include/ui/InputDispatcher.h | 122 | ||||
-rw-r--r-- | include/ui/InputReader.h | 4 | ||||
-rw-r--r-- | include/utils/BitSet.h | 3 |
4 files changed, 87 insertions, 50 deletions
diff --git a/include/ui/Input.h b/include/ui/Input.h index b587e94..21baf32 100644 --- a/include/ui/Input.h +++ b/include/ui/Input.h @@ -40,10 +40,18 @@ 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. */ struct AInputEvent { diff --git a/include/ui/InputDispatcher.h b/include/ui/InputDispatcher.h index 96b4fae..cc16012 100644 --- a/include/ui/InputDispatcher.h +++ b/include/ui/InputDispatcher.h @@ -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> @@ -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. @@ -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; }; @@ -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, @@ -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. @@ -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, @@ -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 { @@ -463,8 +470,6 @@ private: INTERCEPT_KEY_RESULT_CONTINUE, }; InterceptKeyResult interceptKeyResult; // set based on the interception result - - void recycle(); }; struct MotionSample { @@ -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 @@ -555,7 +564,6 @@ private: KeyEntry* keyEntry; sp<InputChannel> inputChannel; sp<InputApplicationHandle> inputApplicationHandle; - int32_t windowType; int32_t userActivityEventType; }; @@ -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, @@ -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); @@ -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; @@ -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 @@ -823,6 +837,7 @@ private: void setInjectionResultLocked(EventEntry* entry, int32_t injectionResult); Condition mInjectionSyncFinishedCondition; + void incrementPendingForegroundDispatchesLocked(EventEntry* entry); void decrementPendingForegroundDispatchesLocked(EventEntry* entry); // Throttling state. @@ -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; + }; + 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(); }; - Vector<OutsideTarget> mTempTouchedOutsideTargets; // temporary outside touch targets - Vector<sp<InputChannel> > mTempTouchedWallpaperChannels; // temporary wallpaper targets + + TouchState mTouchState; + TouchState mTempTouchState; // Focused application. InputApplication* mFocusedApplication; @@ -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, @@ -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); @@ -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); @@ -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(); diff --git a/include/ui/InputReader.h b/include/ui/InputReader.h index 903c3c4..e85735a 100644 --- a/include/ui/InputReader.h +++ b/include/ui/InputReader.h @@ -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 { diff --git a/include/utils/BitSet.h b/include/utils/BitSet.h index 19c8bf0..f5dbcd9 100644 --- a/include/utils/BitSet.h +++ b/include/utils/BitSet.h @@ -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; } |