am 9785bf0f: am 14a288da: Merge "Add suuport for splitting touch events across windows." into gingerbread
Merge commit '9785bf0f2b6b8758aed7ded3b996a2ef0be89919' * commit '9785bf0f2b6b8758aed7ded3b996a2ef0be89919': Add suuport for splitting touch events across windows.
This commit is contained in:
commit
e457038905
@ -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.
|
||||
*/
|
||||
|
@ -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;
|
||||
};
|
||||
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;
|
||||
@ -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();
|
||||
|
@ -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 {
|
||||
|
@ -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; }
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -3366,7 +3366,7 @@ void MultiTouchInputMapper::sync(nsecs_t when) {
|
||||
if (id > MAX_POINTER_ID) {
|
||||
#if DEBUG_POINTERS
|
||||
LOGD("Pointers: Ignoring driver provided pointer id %d because "
|
||||
"it is larger than max supported id %d for optimizations",
|
||||
"it is larger than max supported id %d",
|
||||
id, MAX_POINTER_ID);
|
||||
#endif
|
||||
havePointerIds = false;
|
||||
|
Loading…
Reference in New Issue
Block a user