summaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorJeff Brown <jeffbrown@google.com>2010-09-27 12:33:14 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2010-09-27 12:33:14 -0700
commit6949f5da669d6ec6db24da0b561ad3466aece60d (patch)
treeedb682085d26d31c87377b2393b8f3158315c2eb /include
parent257fe6b3301570ec633d41692f450dba5f1b13d1 (diff)
parentd1b0a2bfe50e61241fab6a571941c207232d9212 (diff)
downloadframeworks_native-6949f5da669d6ec6db24da0b561ad3466aece60d.zip
frameworks_native-6949f5da669d6ec6db24da0b561ad3466aece60d.tar.gz
frameworks_native-6949f5da669d6ec6db24da0b561ad3466aece60d.tar.bz2
Merge "Add suuport for splitting touch events across windows." into gingerbread
Diffstat (limited to 'include')
-rw-r--r--include/ui/Input.h8
-rw-r--r--include/ui/InputDispatcher.h122
-rw-r--r--include/ui/InputReader.h4
-rw-r--r--include/utils/BitSet.h3
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; }