summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Brown <jeffbrown@google.com>2010-07-29 18:18:33 -0700
committerJeff Brown <jeffbrown@google.com>2010-07-30 14:43:58 -0700
commit6328cdc89e099806a1893b89e4c724d596272d9e (patch)
tree691dfe8a5296cdc6c6773351b21114e7a34aec86
parent04d7e83e65e246e154b5b346e3eb0081b741ae88 (diff)
downloadframeworks_base-6328cdc89e099806a1893b89e4c724d596272d9e.zip
frameworks_base-6328cdc89e099806a1893b89e4c724d596272d9e.tar.gz
frameworks_base-6328cdc89e099806a1893b89e4c724d596272d9e.tar.bz2
Improve thread safety of input mappers.
Also fixed bug where old touch screen size could be reported by getMotionRange if an orientation change occurred but the user has not yet touched the screen. Bug: 2877345 Change-Id: I7878f47458f310ed6ebe6a5d1b2c9bec2c598ab9
-rw-r--r--include/ui/InputReader.h150
-rw-r--r--libs/ui/InputReader.cpp919
2 files changed, 579 insertions, 490 deletions
diff --git a/include/ui/InputReader.h b/include/ui/InputReader.h
index d7ec8ea..6bf1bfa 100644
--- a/include/ui/InputReader.h
+++ b/include/ui/InputReader.h
@@ -210,7 +210,7 @@ public:
* IMPORTANT INVARIANT:
* Because the policy and dispatcher can potentially block or cause re-entrance into
* the input reader, the input reader never calls into other components while holding
- * an exclusive internal lock.
+ * an exclusive internal lock whenever re-entrance can happen.
*/
class InputReader : public InputReaderInterface, private InputReaderContext {
public:
@@ -414,6 +414,8 @@ public:
virtual int32_t getMetaState();
private:
+ Mutex mLock;
+
struct KeyDown {
int32_t keyCode;
int32_t scanCode;
@@ -423,17 +425,22 @@ private:
uint32_t mSources;
int32_t mKeyboardType;
- Vector<KeyDown> mKeyDowns; // keys that are down
- int32_t mMetaState;
- nsecs_t mDownTime; // time of most recent key down
+ struct LockedState {
+ Vector<KeyDown> keyDowns; // keys that are down
+ int32_t metaState;
+ nsecs_t downTime; // time of most recent key down
+ } mLocked;
- void initialize();
+ void initializeLocked();
bool isKeyboardOrGamepadKey(int32_t scanCode);
+
void processKey(nsecs_t when, bool down, int32_t keyCode, int32_t scanCode,
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 findKeyDown(int32_t scanCode);
+ ssize_t findKeyDownLocked(int32_t scanCode);
};
@@ -451,6 +458,8 @@ private:
// Amount that trackball needs to move in order to generate a key event.
static const int32_t TRACKBALL_MOVEMENT_THRESHOLD = 6;
+ Mutex mLock;
+
int32_t mAssociatedDisplayId;
struct Accumulator {
@@ -475,17 +484,21 @@ private:
}
} mAccumulator;
- bool mDown;
- nsecs_t mDownTime;
-
float mXScale;
float mYScale;
float mXPrecision;
float mYPrecision;
- void initialize();
+ struct LockedState {
+ bool down;
+ nsecs_t downTime;
+ } mLocked;
+
+ void initializeLocked();
void sync(nsecs_t when);
+ void applyPolicyAndDispatch(nsecs_t when, int32_t motionEventAction,
+ PointerCoords* pointerCoords, nsecs_t downTime);
};
@@ -509,6 +522,8 @@ protected:
* (This is limited by our use of BitSet32 to track pointer assignments.) */
static const uint32_t MAX_POINTER_ID = 31;
+ Mutex mLock;
+
struct VirtualKey {
int32_t keyCode;
int32_t scanCode;
@@ -561,7 +576,6 @@ protected:
};
int32_t mAssociatedDisplayId;
- Vector<VirtualKey> mVirtualKeys;
// Immutable configuration parameters.
struct Parameters {
@@ -583,67 +597,65 @@ protected:
RawAbsoluteAxisInfo orientation;
} mAxes;
- // The surface orientation and width and height set by configureSurface().
- int32_t mSurfaceOrientation;
- int32_t mSurfaceWidth, mSurfaceHeight;
-
- // Translation and scaling factors, orientation-independent.
- int32_t mXOrigin;
- float mXScale;
- float mXPrecision;
-
- int32_t mYOrigin;
- float mYScale;
- float mYPrecision;
-
- int32_t mPressureOrigin;
- float mPressureScale;
-
- int32_t mSizeOrigin;
- float mSizeScale;
-
- float mOrientationScale;
-
- // Oriented motion ranges for input device info.
- struct OrientedRanges {
- InputDeviceInfo::MotionRange x;
- InputDeviceInfo::MotionRange y;
- InputDeviceInfo::MotionRange pressure;
- InputDeviceInfo::MotionRange size;
- InputDeviceInfo::MotionRange touchMajor;
- InputDeviceInfo::MotionRange touchMinor;
- InputDeviceInfo::MotionRange toolMajor;
- InputDeviceInfo::MotionRange toolMinor;
- InputDeviceInfo::MotionRange orientation;
- } mOrientedRanges;
-
- // Oriented dimensions and precision.
- float mOrientedSurfaceWidth, mOrientedSurfaceHeight;
- float mOrientedXPrecision, mOrientedYPrecision;
-
- // The touch data of the current sample being processed.
+ // Current and previous touch sample data.
TouchData mCurrentTouch;
-
- // The touch data of the previous sample that was processed. This is updated
- // incrementally while the current sample is being processed.
TouchData mLastTouch;
// The time the primary pointer last went down.
nsecs_t mDownTime;
- struct CurrentVirtualKeyState {
- bool down;
- nsecs_t downTime;
- int32_t keyCode;
- int32_t scanCode;
- } mCurrentVirtualKey;
-
- // Lock for virtual key state.
- Mutex mVirtualKeyLock; // methods use "Lvk" suffix
+ struct LockedState {
+ Vector<VirtualKey> virtualKeys;
+
+ // The surface orientation and width and height set by configureSurfaceLocked().
+ int32_t surfaceOrientation;
+ int32_t surfaceWidth, surfaceHeight;
+
+ // Translation and scaling factors, orientation-independent.
+ int32_t xOrigin;
+ float xScale;
+ float xPrecision;
+
+ int32_t yOrigin;
+ float yScale;
+ float yPrecision;
+
+ int32_t pressureOrigin;
+ float pressureScale;
+
+ int32_t sizeOrigin;
+ float sizeScale;
+
+ float orientationScale;
+
+ // Oriented motion ranges for input device info.
+ struct OrientedRanges {
+ InputDeviceInfo::MotionRange x;
+ InputDeviceInfo::MotionRange y;
+ InputDeviceInfo::MotionRange pressure;
+ InputDeviceInfo::MotionRange size;
+ InputDeviceInfo::MotionRange touchMajor;
+ InputDeviceInfo::MotionRange touchMinor;
+ InputDeviceInfo::MotionRange toolMajor;
+ InputDeviceInfo::MotionRange toolMinor;
+ InputDeviceInfo::MotionRange orientation;
+ } orientedRanges;
+
+ // Oriented dimensions and precision.
+ float orientedSurfaceWidth, orientedSurfaceHeight;
+ float orientedXPrecision, orientedYPrecision;
+
+ struct CurrentVirtualKeyState {
+ bool down;
+ nsecs_t downTime;
+ int32_t keyCode;
+ int32_t scanCode;
+ } currentVirtualKey;
+ } mLocked;
virtual void configureAxes();
- virtual bool configureSurface();
- virtual void configureVirtualKeys();
+ virtual bool configureSurfaceLocked();
+ virtual void configureVirtualKeysLocked();
enum TouchResult {
// Dispatch the touch normally.
@@ -696,15 +708,19 @@ private:
uint64_t distance : 48; // squared distance
};
- void initialize();
+ void initializeLocked();
TouchResult consumeOffScreenTouches(nsecs_t when, uint32_t policyFlags);
void dispatchTouches(nsecs_t when, uint32_t policyFlags);
void dispatchTouch(nsecs_t when, uint32_t policyFlags, TouchData* touch,
BitSet32 idBits, uint32_t changedId, int32_t motionEventAction);
- bool isPointInsideSurface(int32_t x, int32_t y);
- const VirtualKey* findVirtualKeyHitLvk(int32_t x, int32_t y);
+ 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);
+ const VirtualKey* findVirtualKeyHitLocked(int32_t x, int32_t y);
bool applyBadTouchFilter();
bool applyJumpyTouchFilter();
diff --git a/libs/ui/InputReader.cpp b/libs/ui/InputReader.cpp
index 56e2977..6618702 100644
--- a/libs/ui/InputReader.cpp
+++ b/libs/ui/InputReader.cpp
@@ -713,15 +713,15 @@ KeyboardInputMapper::KeyboardInputMapper(InputDevice* device, int32_t associated
uint32_t sources, int32_t keyboardType) :
InputMapper(device), mAssociatedDisplayId(associatedDisplayId), mSources(sources),
mKeyboardType(keyboardType) {
- initialize();
+ initializeLocked();
}
KeyboardInputMapper::~KeyboardInputMapper() {
}
-void KeyboardInputMapper::initialize() {
- mMetaState = AMETA_NONE;
- mDownTime = 0;
+void KeyboardInputMapper::initializeLocked() {
+ mLocked.metaState = AMETA_NONE;
+ mLocked.downTime = 0;
}
uint32_t KeyboardInputMapper::getSources() {
@@ -735,17 +735,27 @@ void KeyboardInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
}
void KeyboardInputMapper::reset() {
- // Synthesize key up event on reset if keys are currently down.
- while (! mKeyDowns.isEmpty()) {
- const KeyDown& keyDown = mKeyDowns.top();
+ for (;;) {
+ int32_t keyCode, scanCode;
+ { // acquire lock
+ AutoMutex _l(mLock);
+
+ // Synthesize key up event on reset if keys are currently down.
+ if (mLocked.keyDowns.isEmpty()) {
+ initializeLocked();
+ break; // done
+ }
+
+ const KeyDown& keyDown = mLocked.keyDowns.top();
+ keyCode = keyDown.keyCode;
+ scanCode = keyDown.scanCode;
+ } // release lock
+
nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC);
- processKey(when, false, keyDown.keyCode, keyDown.scanCode, 0);
+ processKey(when, false, keyCode, scanCode, 0);
}
InputMapper::reset();
-
- // Reinitialize.
- initialize();
getContext()->updateGlobalMetaState();
}
@@ -768,56 +778,76 @@ bool KeyboardInputMapper::isKeyboardOrGamepadKey(int32_t scanCode) {
|| (scanCode >= BTN_GAMEPAD && scanCode < BTN_DIGI);
}
-void KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t keyCode, int32_t scanCode,
- uint32_t policyFlags) {
- if (down) {
- // Rotate key codes according to orientation.
- if (mAssociatedDisplayId >= 0) {
- int32_t orientation;
- if (! getPolicy()->getDisplayInfo(mAssociatedDisplayId, NULL, NULL, & orientation)) {
- return;
+void KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t keyCode,
+ int32_t scanCode, uint32_t policyFlags) {
+ int32_t newMetaState;
+ nsecs_t downTime;
+ bool metaStateChanged = false;
+
+ { // acquire lock
+ AutoMutex _l(mLock);
+
+ if (down) {
+ // Rotate key codes according to orientation if needed.
+ // Note: getDisplayInfo is non-reentrant so we can continue holding the lock.
+ if (mAssociatedDisplayId >= 0) {
+ int32_t orientation;
+ if (! getPolicy()->getDisplayInfo(mAssociatedDisplayId, NULL, NULL, & orientation)) {
+ return;
+ }
+
+ keyCode = rotateKeyCode(keyCode, orientation);
}
- keyCode = rotateKeyCode(keyCode, orientation);
- }
+ // Add key down.
+ ssize_t keyDownIndex = findKeyDownLocked(scanCode);
+ if (keyDownIndex >= 0) {
+ // key repeat, be sure to use same keycode as before in case of rotation
+ keyCode = mLocked.keyDowns.top().keyCode;
+ } else {
+ // key down
+ mLocked.keyDowns.push();
+ KeyDown& keyDown = mLocked.keyDowns.editTop();
+ keyDown.keyCode = keyCode;
+ keyDown.scanCode = scanCode;
+ }
- // Add key down.
- ssize_t keyDownIndex = findKeyDown(scanCode);
- if (keyDownIndex >= 0) {
- // key repeat, be sure to use same keycode as before in case of rotation
- keyCode = mKeyDowns.top().keyCode;
+ mLocked.downTime = when;
} else {
- // key down
- mKeyDowns.push();
- KeyDown& keyDown = mKeyDowns.editTop();
- keyDown.keyCode = keyCode;
- keyDown.scanCode = scanCode;
+ // Remove key down.
+ ssize_t keyDownIndex = findKeyDownLocked(scanCode);
+ if (keyDownIndex >= 0) {
+ // key up, be sure to use same keycode as before in case of rotation
+ keyCode = mLocked.keyDowns.top().keyCode;
+ mLocked.keyDowns.removeAt(size_t(keyDownIndex));
+ } else {
+ // key was not actually down
+ LOGI("Dropping key up from device %s because the key was not down. "
+ "keyCode=%d, scanCode=%d",
+ getDeviceName().string(), keyCode, scanCode);
+ return;
+ }
}
- } else {
- // Remove key down.
- ssize_t keyDownIndex = findKeyDown(scanCode);
- if (keyDownIndex >= 0) {
- // key up, be sure to use same keycode as before in case of rotation
- keyCode = mKeyDowns.top().keyCode;
- mKeyDowns.removeAt(size_t(keyDownIndex));
- } else {
- // key was not actually down
- LOGI("Dropping key up from device %s because the key was not down. "
- "keyCode=%d, scanCode=%d",
- getDeviceName().string(), keyCode, scanCode);
- return;
+
+ int32_t oldMetaState = mLocked.metaState;
+ newMetaState = updateMetaState(keyCode, down, oldMetaState);
+ if (oldMetaState != newMetaState) {
+ mLocked.metaState = newMetaState;
+ metaStateChanged = true;
}
- }
- int32_t oldMetaState = mMetaState;
- int32_t newMetaState = updateMetaState(keyCode, down, oldMetaState);
- if (oldMetaState != newMetaState) {
- mMetaState = newMetaState;
+ downTime = mLocked.downTime;
+ } // release lock
+
+ if (metaStateChanged) {
getContext()->updateGlobalMetaState();
}
- /* Apply policy. */
+ 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);
@@ -825,30 +855,20 @@ void KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t keyCode, i
return; // event dropped
}
- /* Enqueue key event for dispatch. */
-
- int32_t keyEventAction;
- if (down) {
- mDownTime = when;
- keyEventAction = AKEY_EVENT_ACTION_DOWN;
- } else {
- keyEventAction = AKEY_EVENT_ACTION_UP;
- }
-
+ 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 = keyEventFlags | AKEY_EVENT_FLAG_WOKE_HERE;
}
getDispatcher()->notifyKey(when, getDeviceId(), AINPUT_SOURCE_KEYBOARD, policyFlags,
- keyEventAction, keyEventFlags, keyCode, scanCode,
- mMetaState, mDownTime);
+ keyEventAction, keyEventFlags, keyCode, scanCode, metaState, downTime);
}
-ssize_t KeyboardInputMapper::findKeyDown(int32_t scanCode) {
- size_t n = mKeyDowns.size();
+ssize_t KeyboardInputMapper::findKeyDownLocked(int32_t scanCode) {
+ size_t n = mLocked.keyDowns.size();
for (size_t i = 0; i < n; i++) {
- if (mKeyDowns[i].scanCode == scanCode) {
+ if (mLocked.keyDowns[i].scanCode == scanCode) {
return i;
}
}
@@ -869,7 +889,10 @@ bool KeyboardInputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numC
}
int32_t KeyboardInputMapper::getMetaState() {
- return mMetaState;
+ { // acquire lock
+ AutoMutex _l(mLock);
+ return mLocked.metaState;
+ } // release lock
}
@@ -882,7 +905,7 @@ TrackballInputMapper::TrackballInputMapper(InputDevice* device, int32_t associat
mXScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD;
mYScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD;
- initialize();
+ initializeLocked();
}
TrackballInputMapper::~TrackballInputMapper() {
@@ -899,26 +922,33 @@ void TrackballInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
info->addMotionRange(AINPUT_MOTION_RANGE_Y, -1.0f, 1.0f, 0.0f, mYScale);
}
-void TrackballInputMapper::initialize() {
+void TrackballInputMapper::initializeLocked() {
mAccumulator.clear();
- mDown = false;
- mDownTime = 0;
+ mLocked.down = false;
+ mLocked.downTime = 0;
}
void TrackballInputMapper::reset() {
- // Synthesize trackball button up event on reset if trackball button is currently down.
- if (mDown) {
+ for (;;) {
+ { // acquire lock
+ AutoMutex _l(mLock);
+
+ if (! mLocked.down) {
+ initializeLocked();
+ break; // done
+ }
+ } // release lock
+
+ // Synthesize trackball button up event on reset.
nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC);
- mAccumulator.fields |= Accumulator::FIELD_BTN_MOUSE;
+ mAccumulator.fields = Accumulator::FIELD_BTN_MOUSE;
mAccumulator.btnMouse = false;
sync(when);
+ mAccumulator.clear();
}
InputMapper::reset();
-
- // Reinitialize.
- initialize();
}
void TrackballInputMapper::process(const RawEvent* rawEvent) {
@@ -962,33 +992,79 @@ void TrackballInputMapper::process(const RawEvent* rawEvent) {
}
void TrackballInputMapper::sync(nsecs_t when) {
- /* Get display properties so for rotation based on display orientation. */
+ int motionEventAction;
+ PointerCoords pointerCoords;
+ nsecs_t downTime;
+ { // acquire lock
+ AutoMutex _l(mLock);
- int32_t orientation;
- if (mAssociatedDisplayId >= 0) {
- if (! getPolicy()->getDisplayInfo(mAssociatedDisplayId, NULL, NULL, & orientation)) {
- return;
- }
- } else {
- orientation = InputReaderPolicyInterface::ROTATION_0;
- }
+ uint32_t fields = mAccumulator.fields;
+ bool downChanged = fields & Accumulator::FIELD_BTN_MOUSE;
- /* Update saved trackball state */
+ if (downChanged) {
+ if (mAccumulator.btnMouse) {
+ mLocked.down = true;
+ mLocked.downTime = when;
+ } else {
+ mLocked.down = false;
+ }
+ }
- uint32_t fields = mAccumulator.fields;
- bool downChanged = fields & Accumulator::FIELD_BTN_MOUSE;
+ downTime = mLocked.downTime;
+ float x = fields & Accumulator::FIELD_REL_X ? mAccumulator.relX * mXScale : 0.0f;
+ float y = fields & Accumulator::FIELD_REL_Y ? mAccumulator.relY * mYScale : 0.0f;
- if (downChanged) {
- if (mAccumulator.btnMouse) {
- mDown = true;
- mDownTime = when;
+ if (downChanged) {
+ motionEventAction = mLocked.down ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
} else {
- mDown = false;
+ motionEventAction = AMOTION_EVENT_ACTION_MOVE;
+ }
+
+ pointerCoords.x = x;
+ pointerCoords.y = y;
+ pointerCoords.pressure = mLocked.down ? 1.0f : 0.0f;
+ pointerCoords.size = 0;
+ pointerCoords.touchMajor = 0;
+ pointerCoords.touchMinor = 0;
+ pointerCoords.toolMajor = 0;
+ pointerCoords.toolMinor = 0;
+ pointerCoords.orientation = 0;
+
+ if (mAssociatedDisplayId >= 0 && (x != 0.0f || y != 0.0f)) {
+ // Rotate motion based on display orientation if needed.
+ // Note: getDisplayInfo is non-reentrant so we can continue holding the lock.
+ int32_t orientation;
+ if (! getPolicy()->getDisplayInfo(mAssociatedDisplayId, NULL, NULL, & orientation)) {
+ return;
+ }
+
+ float temp;
+ switch (orientation) {
+ case InputReaderPolicyInterface::ROTATION_90:
+ temp = pointerCoords.x;
+ pointerCoords.x = pointerCoords.y;
+ pointerCoords.y = - temp;
+ break;
+
+ case InputReaderPolicyInterface::ROTATION_180:
+ pointerCoords.x = - pointerCoords.x;
+ pointerCoords.y = - pointerCoords.y;
+ break;
+
+ case InputReaderPolicyInterface::ROTATION_270:
+ temp = pointerCoords.x;
+ pointerCoords.x = - pointerCoords.y;
+ pointerCoords.y = temp;
+ break;
+ }
}
- }
+ } // release lock
- /* Apply policy */
+ applyPolicyAndDispatch(when, motionEventAction, & pointerCoords, downTime);
+}
+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);
@@ -996,62 +1072,24 @@ void TrackballInputMapper::sync(nsecs_t when) {
return; // event dropped
}
- /* Enqueue motion event for dispatch. */
-
- int32_t motionEventAction;
- if (downChanged) {
- motionEventAction = mDown ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
- } else {
- motionEventAction = AMOTION_EVENT_ACTION_MOVE;
- }
-
+ int32_t metaState = mContext->getGlobalMetaState();
int32_t pointerId = 0;
- PointerCoords pointerCoords;
- pointerCoords.x = fields & Accumulator::FIELD_REL_X
- ? mAccumulator.relX * mXScale : 0;
- pointerCoords.y = fields & Accumulator::FIELD_REL_Y
- ? mAccumulator.relY * mYScale : 0;
- pointerCoords.pressure = 1.0f; // XXX Consider making this 1.0f if down, 0 otherwise.
- pointerCoords.size = 0;
- pointerCoords.touchMajor = 0;
- pointerCoords.touchMinor = 0;
- pointerCoords.toolMajor = 0;
- pointerCoords.toolMinor = 0;
- pointerCoords.orientation = 0;
-
- float temp;
- switch (orientation) {
- case InputReaderPolicyInterface::ROTATION_90:
- temp = pointerCoords.x;
- pointerCoords.x = pointerCoords.y;
- pointerCoords.y = - temp;
- break;
-
- case InputReaderPolicyInterface::ROTATION_180:
- pointerCoords.x = - pointerCoords.x;
- pointerCoords.y = - pointerCoords.y;
- break;
- case InputReaderPolicyInterface::ROTATION_270:
- temp = pointerCoords.x;
- pointerCoords.x = - pointerCoords.y;
- pointerCoords.y = temp;
- break;
- }
-
- int32_t metaState = mContext->getGlobalMetaState();
getDispatcher()->notifyMotion(when, getDeviceId(), AINPUT_SOURCE_TRACKBALL, policyFlags,
motionEventAction, metaState, AMOTION_EVENT_EDGE_FLAG_NONE,
- 1, & pointerId, & pointerCoords, mXPrecision, mYPrecision, mDownTime);
+ 1, & pointerId, pointerCoords, mXPrecision, mYPrecision, downTime);
}
// --- TouchInputMapper ---
TouchInputMapper::TouchInputMapper(InputDevice* device, int32_t associatedDisplayId) :
- InputMapper(device), mAssociatedDisplayId(associatedDisplayId),
- mSurfaceOrientation(-1), mSurfaceWidth(-1), mSurfaceHeight(-1) {
- initialize();
+ InputMapper(device), mAssociatedDisplayId(associatedDisplayId) {
+ mLocked.surfaceOrientation = -1;
+ mLocked.surfaceWidth = -1;
+ mLocked.surfaceHeight = -1;
+
+ initializeLocked();
}
TouchInputMapper::~TouchInputMapper() {
@@ -1064,26 +1102,29 @@ uint32_t TouchInputMapper::getSources() {
void TouchInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
InputMapper::populateDeviceInfo(info);
- // FIXME: Should ensure the surface information is up to date so that orientation changes
- // are noticed immediately. Unfortunately we will need to add some extra locks here
- // to prevent race conditions.
- // configureSurface();
+ { // acquire lock
+ AutoMutex _l(mLock);
+
+ // Ensure surface information is up to date so that orientation changes are
+ // noticed immediately.
+ configureSurfaceLocked();
- info->addMotionRange(AINPUT_MOTION_RANGE_X, mOrientedRanges.x);
- info->addMotionRange(AINPUT_MOTION_RANGE_Y, mOrientedRanges.y);
- info->addMotionRange(AINPUT_MOTION_RANGE_PRESSURE, mOrientedRanges.pressure);
- info->addMotionRange(AINPUT_MOTION_RANGE_SIZE, mOrientedRanges.size);
- info->addMotionRange(AINPUT_MOTION_RANGE_TOUCH_MAJOR, mOrientedRanges.touchMajor);
- info->addMotionRange(AINPUT_MOTION_RANGE_TOUCH_MINOR, mOrientedRanges.touchMinor);
- info->addMotionRange(AINPUT_MOTION_RANGE_TOOL_MAJOR, mOrientedRanges.toolMajor);
- info->addMotionRange(AINPUT_MOTION_RANGE_TOOL_MINOR, mOrientedRanges.toolMinor);
- info->addMotionRange(AINPUT_MOTION_RANGE_ORIENTATION, mOrientedRanges.orientation);
+ info->addMotionRange(AINPUT_MOTION_RANGE_X, mLocked.orientedRanges.x);
+ info->addMotionRange(AINPUT_MOTION_RANGE_Y, mLocked.orientedRanges.y);
+ info->addMotionRange(AINPUT_MOTION_RANGE_PRESSURE, mLocked.orientedRanges.pressure);
+ info->addMotionRange(AINPUT_MOTION_RANGE_SIZE, mLocked.orientedRanges.size);
+ info->addMotionRange(AINPUT_MOTION_RANGE_TOUCH_MAJOR, mLocked.orientedRanges.touchMajor);
+ info->addMotionRange(AINPUT_MOTION_RANGE_TOUCH_MINOR, mLocked.orientedRanges.touchMinor);
+ info->addMotionRange(AINPUT_MOTION_RANGE_TOOL_MAJOR, mLocked.orientedRanges.toolMajor);
+ info->addMotionRange(AINPUT_MOTION_RANGE_TOOL_MINOR, mLocked.orientedRanges.toolMinor);
+ info->addMotionRange(AINPUT_MOTION_RANGE_ORIENTATION, mLocked.orientedRanges.orientation);
+ } // release lock
}
-void TouchInputMapper::initialize() {
+void TouchInputMapper::initializeLocked() {
+ mCurrentTouch.clear();
mLastTouch.clear();
mDownTime = 0;
- mCurrentVirtualKey.down = false;
for (uint32_t i = 0; i < MAX_POINTERS; i++) {
mAveragingTouchFilter.historyStart[i] = 0;
@@ -1091,6 +1132,8 @@ void TouchInputMapper::initialize() {
}
mJumpyTouchFilter.jumpyPointsDropped = 0;
+
+ mLocked.currentVirtualKey.down = false;
}
void TouchInputMapper::configure() {
@@ -1104,48 +1147,52 @@ void TouchInputMapper::configure() {
// Configure absolute axis information.
configureAxes();
- // Configure pressure factors.
- if (mAxes.pressure.valid) {
- mPressureOrigin = mAxes.pressure.minValue;
- mPressureScale = 1.0f / mAxes.pressure.getRange();
- } else {
- mPressureOrigin = 0;
- mPressureScale = 1.0f;
- }
+ { // acquire lock
+ AutoMutex _l(mLock);
- mOrientedRanges.pressure.min = 0.0f;
- mOrientedRanges.pressure.max = 1.0f;
- mOrientedRanges.pressure.flat = 0.0f;
- mOrientedRanges.pressure.fuzz = mPressureScale;
+ // Configure pressure factors.
+ if (mAxes.pressure.valid) {
+ mLocked.pressureOrigin = mAxes.pressure.minValue;
+ mLocked.pressureScale = 1.0f / mAxes.pressure.getRange();
+ } else {
+ mLocked.pressureOrigin = 0;
+ mLocked.pressureScale = 1.0f;
+ }
- // Configure size factors.
- if (mAxes.size.valid) {
- mSizeOrigin = mAxes.size.minValue;
- mSizeScale = 1.0f / mAxes.size.getRange();
- } else {
- mSizeOrigin = 0;
- mSizeScale = 1.0f;
- }
+ mLocked.orientedRanges.pressure.min = 0.0f;
+ mLocked.orientedRanges.pressure.max = 1.0f;
+ mLocked.orientedRanges.pressure.flat = 0.0f;
+ mLocked.orientedRanges.pressure.fuzz = mLocked.pressureScale;
- mOrientedRanges.size.min = 0.0f;
- mOrientedRanges.size.max = 1.0f;
- mOrientedRanges.size.flat = 0.0f;
- mOrientedRanges.size.fuzz = mSizeScale;
+ // Configure size factors.
+ if (mAxes.size.valid) {
+ mLocked.sizeOrigin = mAxes.size.minValue;
+ mLocked.sizeScale = 1.0f / mAxes.size.getRange();
+ } else {
+ mLocked.sizeOrigin = 0;
+ mLocked.sizeScale = 1.0f;
+ }
- // Configure orientation factors.
- if (mAxes.orientation.valid && mAxes.orientation.maxValue > 0) {
- mOrientationScale = float(M_PI_2) / mAxes.orientation.maxValue;
- } else {
- mOrientationScale = 0.0f;
- }
+ mLocked.orientedRanges.size.min = 0.0f;
+ mLocked.orientedRanges.size.max = 1.0f;
+ mLocked.orientedRanges.size.flat = 0.0f;
+ mLocked.orientedRanges.size.fuzz = mLocked.sizeScale;
- mOrientedRanges.orientation.min = - M_PI_2;
- mOrientedRanges.orientation.max = M_PI_2;
- mOrientedRanges.orientation.flat = 0;
- mOrientedRanges.orientation.fuzz = mOrientationScale;
+ // Configure orientation factors.
+ if (mAxes.orientation.valid && mAxes.orientation.maxValue > 0) {
+ mLocked.orientationScale = float(M_PI_2) / mAxes.orientation.maxValue;
+ } else {
+ mLocked.orientationScale = 0.0f;
+ }
+
+ mLocked.orientedRanges.orientation.min = - M_PI_2;
+ mLocked.orientedRanges.orientation.max = M_PI_2;
+ mLocked.orientedRanges.orientation.flat = 0;
+ mLocked.orientedRanges.orientation.fuzz = mLocked.orientationScale;
- // Configure surface dimensions and orientation.
- configureSurface();
+ // Configure surface dimensions and orientation.
+ configureSurfaceLocked();
+ } // release lock
}
void TouchInputMapper::configureAxes() {
@@ -1160,11 +1207,12 @@ void TouchInputMapper::configureAxes() {
mAxes.orientation.valid = false;
}
-bool TouchInputMapper::configureSurface() {
+bool TouchInputMapper::configureSurfaceLocked() {
// Update orientation and dimensions if needed.
int32_t orientation;
int32_t width, height;
if (mAssociatedDisplayId >= 0) {
+ // Note: getDisplayInfo is non-reentrant so we can continue holding the lock.
if (! getPolicy()->getDisplayInfo(mAssociatedDisplayId, & width, & height, & orientation)) {
return false;
}
@@ -1174,150 +1222,152 @@ bool TouchInputMapper::configureSurface() {
height = mAxes.y.getRange();
}
- bool orientationChanged = mSurfaceOrientation != orientation;
+ bool orientationChanged = mLocked.surfaceOrientation != orientation;
if (orientationChanged) {
- mSurfaceOrientation = orientation;
+ mLocked.surfaceOrientation = orientation;
}
- bool sizeChanged = mSurfaceWidth != width || mSurfaceHeight != height;
+ bool sizeChanged = mLocked.surfaceWidth != width || mLocked.surfaceHeight != height;
if (sizeChanged) {
- mSurfaceWidth = width;
- mSurfaceHeight = height;
+ mLocked.surfaceWidth = width;
+ mLocked.surfaceHeight = height;
// Compute size-dependent translation and scaling factors and place virtual keys.
if (mAxes.x.valid && mAxes.y.valid) {
- mXOrigin = mAxes.x.minValue;
- mYOrigin = mAxes.y.minValue;
+ mLocked.xOrigin = mAxes.x.minValue;
+ mLocked.yOrigin = mAxes.y.minValue;
LOGI("Device configured: id=0x%x, name=%s (display size was changed)",
getDeviceId(), getDeviceName().string());
- mXScale = float(width) / mAxes.x.getRange();
- mYScale = float(height) / mAxes.y.getRange();
- mXPrecision = 1.0f / mXScale;
- mYPrecision = 1.0f / mYScale;
+ mLocked.xScale = float(width) / mAxes.x.getRange();
+ mLocked.yScale = float(height) / mAxes.y.getRange();
+ mLocked.xPrecision = 1.0f / mLocked.xScale;
+ mLocked.yPrecision = 1.0f / mLocked.yScale;
- configureVirtualKeys();
+ configureVirtualKeysLocked();
} else {
- mXOrigin = 0;
- mYOrigin = 0;
- mXScale = 1.0f;
- mYScale = 1.0f;
- mXPrecision = 1.0f;
- mYPrecision = 1.0f;
+ mLocked.xOrigin = 0;
+ mLocked.yOrigin = 0;
+ mLocked.xScale = 1.0f;
+ mLocked.yScale = 1.0f;
+ mLocked.xPrecision = 1.0f;
+ mLocked.yPrecision = 1.0f;
}
// Configure touch and tool area ranges.
float diagonal = sqrt(float(width * width + height * height));
- float diagonalFuzz = sqrt(mXScale * mXScale + mYScale * mYScale);
+ float diagonalFuzz = sqrt(mLocked.xScale * mLocked.xScale
+ + mLocked.yScale * mLocked.yScale);
- mOrientedRanges.touchMajor.min = 0.0f;
- mOrientedRanges.touchMajor.max = diagonal;
- mOrientedRanges.touchMajor.flat = 0.0f;
- mOrientedRanges.touchMajor.fuzz = diagonalFuzz;
- mOrientedRanges.touchMinor = mOrientedRanges.touchMajor;
+ InputDeviceInfo::MotionRange area;
+ area.min = 0.0f;
+ area.max = diagonal;
+ area.flat = 0.0f;
+ area.fuzz = diagonalFuzz;
- mOrientedRanges.toolMinor = mOrientedRanges.toolMajor = mOrientedRanges.touchMajor;
+ mLocked.orientedRanges.touchMajor = area;
+ mLocked.orientedRanges.touchMinor = area;
+
+ mLocked.orientedRanges.toolMajor = area;
+ mLocked.orientedRanges.toolMinor = area;
}
if (orientationChanged || sizeChanged) {
// Compute oriented surface dimensions, precision, and scales.
float orientedXScale, orientedYScale;
- switch (mSurfaceOrientation) {
+ switch (mLocked.surfaceOrientation) {
case InputReaderPolicyInterface::ROTATION_90:
case InputReaderPolicyInterface::ROTATION_270:
- mOrientedSurfaceWidth = mSurfaceHeight;
- mOrientedSurfaceHeight = mSurfaceWidth;
- mOrientedXPrecision = mYPrecision;
- mOrientedYPrecision = mXPrecision;
- orientedXScale = mYScale;
- orientedYScale = mXScale;
+ mLocked.orientedSurfaceWidth = mLocked.surfaceHeight;
+ mLocked.orientedSurfaceHeight = mLocked.surfaceWidth;
+ mLocked.orientedXPrecision = mLocked.yPrecision;
+ mLocked.orientedYPrecision = mLocked.xPrecision;
+ orientedXScale = mLocked.yScale;
+ orientedYScale = mLocked.xScale;
break;
default:
- mOrientedSurfaceWidth = mSurfaceWidth;
- mOrientedSurfaceHeight = mSurfaceHeight;
- mOrientedXPrecision = mXPrecision;
- mOrientedYPrecision = mYPrecision;
- orientedXScale = mXScale;
- orientedYScale = mYScale;
+ mLocked.orientedSurfaceWidth = mLocked.surfaceWidth;
+ mLocked.orientedSurfaceHeight = mLocked.surfaceHeight;
+ mLocked.orientedXPrecision = mLocked.xPrecision;
+ mLocked.orientedYPrecision = mLocked.yPrecision;
+ orientedXScale = mLocked.xScale;
+ orientedYScale = mLocked.yScale;
break;
}
// Configure position ranges.
- mOrientedRanges.x.min = 0;
- mOrientedRanges.x.max = mOrientedSurfaceWidth;
- mOrientedRanges.x.flat = 0;
- mOrientedRanges.x.fuzz = orientedXScale;
+ mLocked.orientedRanges.x.min = 0;
+ mLocked.orientedRanges.x.max = mLocked.orientedSurfaceWidth;
+ mLocked.orientedRanges.x.flat = 0;
+ mLocked.orientedRanges.x.fuzz = orientedXScale;
- mOrientedRanges.y.min = 0;
- mOrientedRanges.y.max = mOrientedSurfaceHeight;
- mOrientedRanges.y.flat = 0;
- mOrientedRanges.y.fuzz = orientedYScale;
+ mLocked.orientedRanges.y.min = 0;
+ mLocked.orientedRanges.y.max = mLocked.orientedSurfaceHeight;
+ mLocked.orientedRanges.y.flat = 0;
+ mLocked.orientedRanges.y.fuzz = orientedYScale;
}
return true;
}
-void TouchInputMapper::configureVirtualKeys() {
+void TouchInputMapper::configureVirtualKeysLocked() {
assert(mAxes.x.valid && mAxes.y.valid);
+ // Note: getVirtualKeyDefinitions is non-reentrant so we can continue holding the lock.
Vector<InputReaderPolicyInterface::VirtualKeyDefinition> virtualKeyDefinitions;
getPolicy()->getVirtualKeyDefinitions(getDeviceName(), virtualKeyDefinitions);
- { // acquire virtual key lock
- AutoMutex _l(mVirtualKeyLock);
-
- mVirtualKeys.clear();
+ mLocked.virtualKeys.clear();
- if (virtualKeyDefinitions.size() == 0) {
- return;
- }
+ if (virtualKeyDefinitions.size() == 0) {
+ return;
+ }
- mVirtualKeys.setCapacity(virtualKeyDefinitions.size());
+ mLocked.virtualKeys.setCapacity(virtualKeyDefinitions.size());
- int32_t touchScreenLeft = mAxes.x.minValue;
- int32_t touchScreenTop = mAxes.y.minValue;
- int32_t touchScreenWidth = mAxes.x.getRange();
- int32_t touchScreenHeight = mAxes.y.getRange();
+ int32_t touchScreenLeft = mAxes.x.minValue;
+ int32_t touchScreenTop = mAxes.y.minValue;
+ int32_t touchScreenWidth = mAxes.x.getRange();
+ int32_t touchScreenHeight = mAxes.y.getRange();
- for (size_t i = 0; i < virtualKeyDefinitions.size(); i++) {
- const InputReaderPolicyInterface::VirtualKeyDefinition& virtualKeyDefinition =
- virtualKeyDefinitions[i];
+ for (size_t i = 0; i < virtualKeyDefinitions.size(); i++) {
+ const InputReaderPolicyInterface::VirtualKeyDefinition& virtualKeyDefinition =
+ virtualKeyDefinitions[i];
- mVirtualKeys.add();
- VirtualKey& virtualKey = mVirtualKeys.editTop();
+ mLocked.virtualKeys.add();
+ VirtualKey& virtualKey = mLocked.virtualKeys.editTop();
- virtualKey.scanCode = virtualKeyDefinition.scanCode;
- int32_t keyCode;
- uint32_t flags;
- if (getEventHub()->scancodeToKeycode(getDeviceId(), virtualKey.scanCode,
- & keyCode, & flags)) {
- LOGW(" VirtualKey %d: could not obtain key code, ignoring", virtualKey.scanCode);
- mVirtualKeys.pop(); // drop the key
- continue;
- }
+ virtualKey.scanCode = virtualKeyDefinition.scanCode;
+ int32_t keyCode;
+ uint32_t flags;
+ if (getEventHub()->scancodeToKeycode(getDeviceId(), virtualKey.scanCode,
+ & keyCode, & flags)) {
+ LOGW(" VirtualKey %d: could not obtain key code, ignoring", virtualKey.scanCode);
+ mLocked.virtualKeys.pop(); // drop the key
+ continue;
+ }
- virtualKey.keyCode = keyCode;
- virtualKey.flags = flags;
+ virtualKey.keyCode = keyCode;
+ virtualKey.flags = flags;
- // convert the key definition's display coordinates into touch coordinates for a hit box
- int32_t halfWidth = virtualKeyDefinition.width / 2;
- int32_t halfHeight = virtualKeyDefinition.height / 2;
+ // convert the key definition's display coordinates into touch coordinates for a hit box
+ int32_t halfWidth = virtualKeyDefinition.width / 2;
+ int32_t halfHeight = virtualKeyDefinition.height / 2;
- virtualKey.hitLeft = (virtualKeyDefinition.centerX - halfWidth)
- * touchScreenWidth / mSurfaceWidth + touchScreenLeft;
- virtualKey.hitRight= (virtualKeyDefinition.centerX + halfWidth)
- * touchScreenWidth / mSurfaceWidth + touchScreenLeft;
- virtualKey.hitTop = (virtualKeyDefinition.centerY - halfHeight)
- * touchScreenHeight / mSurfaceHeight + touchScreenTop;
- virtualKey.hitBottom = (virtualKeyDefinition.centerY + halfHeight)
- * touchScreenHeight / mSurfaceHeight + touchScreenTop;
+ virtualKey.hitLeft = (virtualKeyDefinition.centerX - halfWidth)
+ * touchScreenWidth / mLocked.surfaceWidth + touchScreenLeft;
+ virtualKey.hitRight= (virtualKeyDefinition.centerX + halfWidth)
+ * touchScreenWidth / mLocked.surfaceWidth + touchScreenLeft;
+ virtualKey.hitTop = (virtualKeyDefinition.centerY - halfHeight)
+ * touchScreenHeight / mLocked.surfaceHeight + touchScreenTop;
+ virtualKey.hitBottom = (virtualKeyDefinition.centerY + halfHeight)
+ * touchScreenHeight / mLocked.surfaceHeight + touchScreenTop;
- LOGI(" VirtualKey %d: keyCode=%d hitLeft=%d hitRight=%d hitTop=%d hitBottom=%d",
- virtualKey.scanCode, virtualKey.keyCode,
- virtualKey.hitLeft, virtualKey.hitRight, virtualKey.hitTop, virtualKey.hitBottom);
- }
- } // release virtual key lock
+ LOGI(" VirtualKey %d: keyCode=%d hitLeft=%d hitRight=%d hitTop=%d hitBottom=%d",
+ virtualKey.scanCode, virtualKey.keyCode,
+ virtualKey.hitLeft, virtualKey.hitRight, virtualKey.hitTop, virtualKey.hitBottom);
+ }
}
void TouchInputMapper::reset() {
@@ -1329,20 +1379,16 @@ void TouchInputMapper::reset() {
syncTouch(when, true);
}
- InputMapper::reset();
+ { // acquire lock
+ AutoMutex _l(mLock);
+ initializeLocked();
+ } // release lock
- // Reinitialize.
- initialize();
+ InputMapper::reset();
}
void TouchInputMapper::syncTouch(nsecs_t when, bool havePointerIds) {
- /* Refresh associated display information and update our size configuration if needed. */
-
- if (! configureSurface()) {
- return;
- }
-
- /* Apply policy */
+ // Apply generic policy actions.
uint32_t policyFlags = 0;
int32_t policyActions = getPolicy()->interceptGeneric(when, policyFlags);
@@ -1352,7 +1398,7 @@ void TouchInputMapper::syncTouch(nsecs_t when, bool havePointerIds) {
return; // event dropped
}
- /* Preprocess pointer data */
+ // Preprocess pointer data.
if (mParameters.useBadTouchFilter) {
if (applyBadTouchFilter()) {
@@ -1381,14 +1427,14 @@ void TouchInputMapper::syncTouch(nsecs_t when, bool havePointerIds) {
savedTouch = & mCurrentTouch;
}
- /* Process touches and virtual keys */
+ // Process touches and virtual keys.
TouchResult touchResult = consumeOffScreenTouches(when, policyFlags);
if (touchResult == DISPATCH_TOUCH) {
dispatchTouches(when, policyFlags);
}
- /* Copy current touch to last touch in preparation for the next cycle. */
+ // Copy current touch to last touch in preparation for the next cycle.
if (touchResult == DROP_STROKE) {
mLastTouch.clear();
@@ -1403,13 +1449,19 @@ TouchInputMapper::TouchResult TouchInputMapper::consumeOffScreenTouches(
int32_t keyCode, scanCode, downTime;
TouchResult touchResult;
- { // acquire virtual key lock
- AutoMutex _l(mVirtualKeyLock);
+ { // acquire lock
+ AutoMutex _l(mLock);
+
+ // Update surface size and orientation, including virtual key positions.
+ if (! configureSurfaceLocked()) {
+ return DROP_STROKE;
+ }
- if (mCurrentVirtualKey.down) {
+ // Check for virtual key press.
+ if (mLocked.currentVirtualKey.down) {
if (mCurrentTouch.pointerCount == 0) {
// Pointer went up while virtual key was down.
- mCurrentVirtualKey.down = false;
+ mLocked.currentVirtualKey.down = false;
#if DEBUG_VIRTUAL_KEYS
LOGD("VirtualKeys: Generating key up: keyCode=%d, scanCode=%d",
mCurrentVirtualKey.keyCode, mCurrentVirtualKey.scanCode);
@@ -1423,8 +1475,8 @@ TouchInputMapper::TouchResult TouchInputMapper::consumeOffScreenTouches(
if (mCurrentTouch.pointerCount == 1) {
int32_t x = mCurrentTouch.pointers[0].x;
int32_t y = mCurrentTouch.pointers[0].y;
- const VirtualKey* virtualKey = findVirtualKeyHitLvk(x, y);
- if (virtualKey && virtualKey->keyCode == mCurrentVirtualKey.keyCode) {
+ const VirtualKey* virtualKey = findVirtualKeyHitLocked(x, y);
+ if (virtualKey && virtualKey->keyCode == mLocked.currentVirtualKey.keyCode) {
// Pointer is still within the space of the virtual key.
return SKIP_TOUCH;
}
@@ -1434,7 +1486,7 @@ TouchInputMapper::TouchResult TouchInputMapper::consumeOffScreenTouches(
// Send key cancellation and drop the stroke so subsequent motions will be
// considered fresh downs. This is useful when the user swipes away from the
// virtual key area into the main display surface.
- mCurrentVirtualKey.down = false;
+ mLocked.currentVirtualKey.down = false;
#if DEBUG_VIRTUAL_KEYS
LOGD("VirtualKeys: Canceling key: keyCode=%d, scanCode=%d",
mCurrentVirtualKey.keyCode, mCurrentVirtualKey.scanCode);
@@ -1449,16 +1501,16 @@ TouchInputMapper::TouchResult TouchInputMapper::consumeOffScreenTouches(
// Pointer just went down. Handle off-screen touches, if needed.
int32_t x = mCurrentTouch.pointers[0].x;
int32_t y = mCurrentTouch.pointers[0].y;
- if (! isPointInsideSurface(x, y)) {
+ if (! isPointInsideSurfaceLocked(x, y)) {
// If exactly one pointer went down, check for virtual key hit.
// Otherwise we will drop the entire stroke.
if (mCurrentTouch.pointerCount == 1) {
- const VirtualKey* virtualKey = findVirtualKeyHitLvk(x, y);
+ const VirtualKey* virtualKey = findVirtualKeyHitLocked(x, y);
if (virtualKey) {
- mCurrentVirtualKey.down = true;
- mCurrentVirtualKey.downTime = when;
- mCurrentVirtualKey.keyCode = virtualKey->keyCode;
- mCurrentVirtualKey.scanCode = virtualKey->scanCode;
+ mLocked.currentVirtualKey.down = true;
+ mLocked.currentVirtualKey.downTime = when;
+ mLocked.currentVirtualKey.keyCode = virtualKey->keyCode;
+ mLocked.currentVirtualKey.scanCode = virtualKey->scanCode;
#if DEBUG_VIRTUAL_KEYS
LOGD("VirtualKeys: Generating key down: keyCode=%d, scanCode=%d",
mCurrentVirtualKey.keyCode, mCurrentVirtualKey.scanCode);
@@ -1478,12 +1530,20 @@ TouchInputMapper::TouchResult TouchInputMapper::consumeOffScreenTouches(
DispatchVirtualKey:
// Collect remaining state needed to dispatch virtual key.
- keyCode = mCurrentVirtualKey.keyCode;
- scanCode = mCurrentVirtualKey.scanCode;
- downTime = mCurrentVirtualKey.downTime;
- } // release virtual key lock
+ keyCode = mLocked.currentVirtualKey.keyCode;
+ scanCode = mLocked.currentVirtualKey.scanCode;
+ downTime = mLocked.currentVirtualKey.downTime;
+ } // release lock
// 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();
if (keyEventAction == AKEY_EVENT_ACTION_DOWN) {
@@ -1497,7 +1557,6 @@ TouchInputMapper::TouchResult TouchInputMapper::consumeOffScreenTouches(
getDispatcher()->notifyKey(when, getDeviceId(), AINPUT_SOURCE_KEYBOARD, policyFlags,
keyEventAction, keyEventFlags, keyCode, scanCode, metaState, downTime);
}
- return touchResult;
}
void TouchInputMapper::dispatchTouches(nsecs_t when, uint32_t policyFlags) {
@@ -1566,107 +1625,118 @@ void TouchInputMapper::dispatchTouch(nsecs_t when, uint32_t policyFlags,
uint32_t pointerCount = 0;
int32_t pointerIds[MAX_POINTERS];
PointerCoords pointerCoords[MAX_POINTERS];
+ int32_t motionEventEdgeFlags = 0;
+ float xPrecision, yPrecision;
+
+ { // acquire lock
+ AutoMutex _l(mLock);
+
+ // Walk through the the active pointers and map touch screen coordinates (TouchData) into
+ // display coordinates (PointerCoords) and adjust for display orientation.
+ while (! idBits.isEmpty()) {
+ uint32_t id = idBits.firstMarkedBit();
+ idBits.clearBit(id);
+ uint32_t index = touch->idToIndex[id];
+
+ float x = float(touch->pointers[index].x - mLocked.xOrigin) * mLocked.xScale;
+ float y = float(touch->pointers[index].y - mLocked.yOrigin) * mLocked.yScale;
+ float pressure = float(touch->pointers[index].pressure - mLocked.pressureOrigin)
+ * mLocked.pressureScale;
+ float size = float(touch->pointers[index].size - mLocked.sizeOrigin)
+ * mLocked.sizeScale;
+
+ float orientation = float(touch->pointers[index].orientation)
+ * mLocked.orientationScale;
+
+ float touchMajor, touchMinor, toolMajor, toolMinor;
+ if (abs(orientation) <= M_PI_4) {
+ // Nominally vertical orientation: scale major axis by Y, and scale minor axis by X.
+ touchMajor = float(touch->pointers[index].touchMajor) * mLocked.yScale;
+ touchMinor = float(touch->pointers[index].touchMinor) * mLocked.xScale;
+ toolMajor = float(touch->pointers[index].toolMajor) * mLocked.yScale;
+ toolMinor = float(touch->pointers[index].toolMinor) * mLocked.xScale;
+ } else {
+ // Nominally horizontal orientation: scale major axis by X, and scale minor axis by Y.
+ touchMajor = float(touch->pointers[index].touchMajor) * mLocked.xScale;
+ touchMinor = float(touch->pointers[index].touchMinor) * mLocked.yScale;
+ toolMajor = float(touch->pointers[index].toolMajor) * mLocked.xScale;
+ toolMinor = float(touch->pointers[index].toolMinor) * mLocked.yScale;
+ }
- // Walk through the the active pointers and map touch screen coordinates (TouchData) into
- // display coordinates (PointerCoords) and adjust for display orientation.
- while (! idBits.isEmpty()) {
- uint32_t id = idBits.firstMarkedBit();
- idBits.clearBit(id);
- uint32_t index = touch->idToIndex[id];
-
- float x = float(touch->pointers[index].x - mXOrigin) * mXScale;
- float y = float(touch->pointers[index].y - mYOrigin) * mYScale;
- float pressure = float(touch->pointers[index].pressure - mPressureOrigin) * mPressureScale;
- float size = float(touch->pointers[index].size - mSizeOrigin) * mSizeScale;
-
- float orientation = float(touch->pointers[index].orientation) * mOrientationScale;
-
- float touchMajor, touchMinor, toolMajor, toolMinor;
- if (abs(orientation) <= M_PI_4) {
- // Nominally vertical orientation: scale major axis by Y, and scale minor axis by X.
- touchMajor = float(touch->pointers[index].touchMajor) * mYScale;
- touchMinor = float(touch->pointers[index].touchMinor) * mXScale;
- toolMajor = float(touch->pointers[index].toolMajor) * mYScale;
- toolMinor = float(touch->pointers[index].toolMinor) * mXScale;
- } else {
- // Nominally horizontal orientation: scale major axis by X, and scale minor axis by Y.
- touchMajor = float(touch->pointers[index].touchMajor) * mXScale;
- touchMinor = float(touch->pointers[index].touchMinor) * mYScale;
- toolMajor = float(touch->pointers[index].toolMajor) * mXScale;
- toolMinor = float(touch->pointers[index].toolMinor) * mYScale;
- }
-
- switch (mSurfaceOrientation) {
- case InputReaderPolicyInterface::ROTATION_90: {
- float xTemp = x;
- x = y;
- y = mSurfaceWidth - xTemp;
- orientation -= M_PI_2;
- if (orientation < - M_PI_2) {
- orientation += M_PI;
+ switch (mLocked.surfaceOrientation) {
+ case InputReaderPolicyInterface::ROTATION_90: {
+ float xTemp = x;
+ x = y;
+ y = mLocked.surfaceWidth - xTemp;
+ orientation -= M_PI_2;
+ if (orientation < - M_PI_2) {
+ orientation += M_PI;
+ }
+ break;
+ }
+ case InputReaderPolicyInterface::ROTATION_180: {
+ x = mLocked.surfaceWidth - x;
+ y = mLocked.surfaceHeight - y;
+ orientation = - orientation;
+ break;
+ }
+ case InputReaderPolicyInterface::ROTATION_270: {
+ float xTemp = x;
+ x = mLocked.surfaceHeight - y;
+ y = xTemp;
+ orientation += M_PI_2;
+ if (orientation > M_PI_2) {
+ orientation -= M_PI;
+ }
+ break;
}
- break;
- }
- case InputReaderPolicyInterface::ROTATION_180: {
- x = mSurfaceWidth - x;
- y = mSurfaceHeight - y;
- orientation = - orientation;
- break;
- }
- case InputReaderPolicyInterface::ROTATION_270: {
- float xTemp = x;
- x = mSurfaceHeight - y;
- y = xTemp;
- orientation += M_PI_2;
- if (orientation > M_PI_2) {
- orientation -= M_PI;
}
- break;
- }
- }
-
- pointerIds[pointerCount] = int32_t(id);
- pointerCoords[pointerCount].x = x;
- pointerCoords[pointerCount].y = y;
- pointerCoords[pointerCount].pressure = pressure;
- pointerCoords[pointerCount].size = size;
- pointerCoords[pointerCount].touchMajor = touchMajor;
- pointerCoords[pointerCount].touchMinor = touchMinor;
- pointerCoords[pointerCount].toolMajor = toolMajor;
- pointerCoords[pointerCount].toolMinor = toolMinor;
- pointerCoords[pointerCount].orientation = orientation;
+ pointerIds[pointerCount] = int32_t(id);
- if (id == changedId) {
- motionEventAction |= pointerCount << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
- }
+ pointerCoords[pointerCount].x = x;
+ pointerCoords[pointerCount].y = y;
+ pointerCoords[pointerCount].pressure = pressure;
+ pointerCoords[pointerCount].size = size;
+ pointerCoords[pointerCount].touchMajor = touchMajor;
+ pointerCoords[pointerCount].touchMinor = touchMinor;
+ pointerCoords[pointerCount].toolMajor = toolMajor;
+ pointerCoords[pointerCount].toolMinor = toolMinor;
+ pointerCoords[pointerCount].orientation = orientation;
- pointerCount += 1;
- }
+ if (id == changedId) {
+ motionEventAction |= pointerCount << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
+ }
- // Check edge flags by looking only at the first pointer since the flags are
- // global to the event.
- int32_t motionEventEdgeFlags = 0;
- if (motionEventAction == AMOTION_EVENT_ACTION_DOWN) {
- if (pointerCoords[0].x <= 0) {
- motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_LEFT;
- } else if (pointerCoords[0].x >= mOrientedSurfaceWidth) {
- motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_RIGHT;
+ pointerCount += 1;
}
- if (pointerCoords[0].y <= 0) {
- motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_TOP;
- } else if (pointerCoords[0].y >= mOrientedSurfaceHeight) {
- motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_BOTTOM;
+
+ // Check edge flags by looking only at the first pointer since the flags are
+ // global to the event.
+ if (motionEventAction == AMOTION_EVENT_ACTION_DOWN) {
+ if (pointerCoords[0].x <= 0) {
+ motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_LEFT;
+ } else if (pointerCoords[0].x >= mLocked.orientedSurfaceWidth) {
+ motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_RIGHT;
+ }
+ if (pointerCoords[0].y <= 0) {
+ motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_TOP;
+ } else if (pointerCoords[0].y >= mLocked.orientedSurfaceHeight) {
+ motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_BOTTOM;
+ }
}
- }
+
+ xPrecision = mLocked.orientedXPrecision;
+ yPrecision = mLocked.orientedYPrecision;
+ } // release lock
getDispatcher()->notifyMotion(when, getDeviceId(), AINPUT_SOURCE_TOUCHSCREEN, policyFlags,
motionEventAction, getContext()->getGlobalMetaState(), motionEventEdgeFlags,
pointerCount, pointerIds, pointerCoords,
- mOrientedXPrecision, mOrientedYPrecision, mDownTime);
+ xPrecision, yPrecision, mDownTime);
}
-bool TouchInputMapper::isPointInsideSurface(int32_t x, int32_t y) {
+bool TouchInputMapper::isPointInsideSurfaceLocked(int32_t x, int32_t y) {
if (mAxes.x.valid && mAxes.y.valid) {
return x >= mAxes.x.minValue && x <= mAxes.x.maxValue
&& y >= mAxes.y.minValue && y <= mAxes.y.maxValue;
@@ -1674,9 +1744,11 @@ bool TouchInputMapper::isPointInsideSurface(int32_t x, int32_t y) {
return true;
}
-const TouchInputMapper::VirtualKey* TouchInputMapper::findVirtualKeyHitLvk(int32_t x, int32_t y) {
- for (size_t i = 0; i < mVirtualKeys.size(); i++) {
- const VirtualKey& virtualKey = mVirtualKeys[i];
+const TouchInputMapper::VirtualKey* TouchInputMapper::findVirtualKeyHitLocked(
+ int32_t x, int32_t y) {
+ size_t numVirtualKeys = mLocked.virtualKeys.size();
+ for (size_t i = 0; i < numVirtualKeys; i++) {
+ const VirtualKey& virtualKey = mLocked.virtualKeys[i];
#if DEBUG_VIRTUAL_KEYS
LOGD("VirtualKeys: Hit test (%d, %d): keyCode=%d, scanCode=%d, "
@@ -2224,50 +2296,53 @@ void TouchInputMapper::applyAveragingTouchFilter() {
}
int32_t TouchInputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
- { // acquire virtual key lock
- AutoMutex _l(mVirtualKeyLock);
+ { // acquire lock
+ AutoMutex _l(mLock);
- if (mCurrentVirtualKey.down && mCurrentVirtualKey.keyCode == keyCode) {
+ if (mLocked.currentVirtualKey.down && mLocked.currentVirtualKey.keyCode == keyCode) {
return AKEY_STATE_VIRTUAL;
}
- for (size_t i = 0; i < mVirtualKeys.size(); i++) {
- const VirtualKey& virtualKey = mVirtualKeys[i];
+ size_t numVirtualKeys = mLocked.virtualKeys.size();
+ for (size_t i = 0; i < numVirtualKeys; i++) {
+ const VirtualKey& virtualKey = mLocked.virtualKeys[i];
if (virtualKey.keyCode == keyCode) {
return AKEY_STATE_UP;
}
}
- } // release virtual key lock
+ } // release lock
return AKEY_STATE_UNKNOWN;
}
int32_t TouchInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
- { // acquire virtual key lock
- AutoMutex _l(mVirtualKeyLock);
+ { // acquire lock
+ AutoMutex _l(mLock);
- if (mCurrentVirtualKey.down && mCurrentVirtualKey.scanCode == scanCode) {
+ if (mLocked.currentVirtualKey.down && mLocked.currentVirtualKey.scanCode == scanCode) {
return AKEY_STATE_VIRTUAL;
}
- for (size_t i = 0; i < mVirtualKeys.size(); i++) {
- const VirtualKey& virtualKey = mVirtualKeys[i];
+ size_t numVirtualKeys = mLocked.virtualKeys.size();
+ for (size_t i = 0; i < numVirtualKeys; i++) {
+ const VirtualKey& virtualKey = mLocked.virtualKeys[i];
if (virtualKey.scanCode == scanCode) {
return AKEY_STATE_UP;
}
}
- } // release virtual key lock
+ } // release lock
return AKEY_STATE_UNKNOWN;
}
bool TouchInputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
const int32_t* keyCodes, uint8_t* outFlags) {
- { // acquire virtual key lock
- AutoMutex _l(mVirtualKeyLock);
+ { // acquire lock
+ AutoMutex _l(mLock);
- for (size_t i = 0; i < mVirtualKeys.size(); i++) {
- const VirtualKey& virtualKey = mVirtualKeys[i];
+ size_t numVirtualKeys = mLocked.virtualKeys.size();
+ for (size_t i = 0; i < numVirtualKeys; i++) {
+ const VirtualKey& virtualKey = mLocked.virtualKeys[i];
for (size_t i = 0; i < numCodes; i++) {
if (virtualKey.keyCode == keyCodes[i]) {
@@ -2275,7 +2350,7 @@ bool TouchInputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCode
}
}
}
- } // release virtual key lock
+ } // release lock
return true;
}
@@ -2304,7 +2379,6 @@ void SingleTouchInputMapper::initialize() {
void SingleTouchInputMapper::reset() {
TouchInputMapper::reset();
- // Reinitialize.
initialize();
}
@@ -2436,7 +2510,6 @@ void MultiTouchInputMapper::initialize() {
void MultiTouchInputMapper::reset() {
TouchInputMapper::reset();
- // Reinitialize.
initialize();
}