summaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/ui/EventHub.h76
-rw-r--r--include/ui/Input.h83
-rw-r--r--include/ui/InputDevice.h353
-rw-r--r--include/ui/InputManager.h49
-rw-r--r--include/ui/InputReader.h753
5 files changed, 770 insertions, 544 deletions
diff --git a/include/ui/EventHub.h b/include/ui/EventHub.h
index 5be17d3..dab35b3 100644
--- a/include/ui/EventHub.h
+++ b/include/ui/EventHub.h
@@ -60,6 +60,31 @@ namespace android {
class KeyLayoutMap;
/*
+ * A raw event as retrieved from the EventHub.
+ */
+struct RawEvent {
+ nsecs_t when;
+ int32_t deviceId;
+ int32_t type;
+ int32_t scanCode;
+ int32_t keyCode;
+ int32_t value;
+ uint32_t flags;
+};
+
+/* Describes an absolute axis. */
+struct RawAbsoluteAxisInfo {
+ bool valid; // true if the information is valid, false otherwise
+
+ int32_t minValue; // minimum value
+ int32_t maxValue; // maximum value
+ int32_t flat; // center flat position, eg. flat == 8 means center is between -8 and 8
+ int32_t fuzz; // error tolerance, eg. fuzz == 4 means value is +/- 4 due to noise
+
+ inline int32_t getRange() { return maxValue - minValue; }
+};
+
+/*
* Input device classes.
*/
enum {
@@ -82,7 +107,10 @@ enum {
INPUT_DEVICE_CLASS_DPAD = 0x00000020,
/* The input device is a gamepad (implies keyboard). */
- INPUT_DEVICE_CLASS_GAMEPAD = 0x00000040
+ INPUT_DEVICE_CLASS_GAMEPAD = 0x00000040,
+
+ /* The input device has switches. */
+ INPUT_DEVICE_CLASS_SWITCH = 0x00000080,
};
/*
@@ -114,8 +142,8 @@ public:
virtual String8 getDeviceName(int32_t deviceId) const = 0;
- virtual int getAbsoluteInfo(int32_t deviceId, int axis, int *outMinValue,
- int* outMaxValue, int* outFlat, int* outFuzz) const = 0;
+ virtual status_t getAbsoluteAxisInfo(int32_t deviceId, int axis,
+ RawAbsoluteAxisInfo* outAxisInfo) const = 0;
virtual status_t scancodeToKeycode(int32_t deviceId, int scancode,
int32_t* outKeycode, uint32_t* outFlags) const = 0;
@@ -131,26 +159,19 @@ public:
* If the device needs to remain awake longer than that, then the caller is responsible
* for taking care of it (say, by poking the power manager user activity timer).
*/
- virtual bool getEvent(int32_t* outDeviceId, int32_t* outType,
- int32_t* outScancode, int32_t* outKeycode, uint32_t *outFlags,
- int32_t* outValue, nsecs_t* outWhen) = 0;
+ virtual bool getEvent(RawEvent* outEvent) = 0;
/*
* Query current input state.
- * deviceId may be -1 to search for the device automatically, filtered by class.
- * deviceClasses may be -1 to ignore device class while searching.
*/
- virtual int32_t getScanCodeState(int32_t deviceId, int32_t deviceClasses,
- int32_t scanCode) const = 0;
- virtual int32_t getKeyCodeState(int32_t deviceId, int32_t deviceClasses,
- int32_t keyCode) const = 0;
- virtual int32_t getSwitchState(int32_t deviceId, int32_t deviceClasses,
- int32_t sw) const = 0;
+ virtual int32_t getScanCodeState(int32_t deviceId, int32_t scanCode) const = 0;
+ virtual int32_t getKeyCodeState(int32_t deviceId, int32_t keyCode) const = 0;
+ virtual int32_t getSwitchState(int32_t deviceId, int32_t sw) const = 0;
/*
* Examine key input devices for specific framework keycode support
*/
- virtual bool hasKeys(size_t numCodes, const int32_t* keyCodes,
+ virtual bool markSupportedKeyCodes(int32_t deviceId, size_t numCodes, const int32_t* keyCodes,
uint8_t* outFlags) const = 0;
};
@@ -165,33 +186,28 @@ public:
virtual String8 getDeviceName(int32_t deviceId) const;
- virtual int getAbsoluteInfo(int32_t deviceId, int axis, int *outMinValue,
- int* outMaxValue, int* outFlat, int* outFuzz) const;
-
+ virtual status_t getAbsoluteAxisInfo(int32_t deviceId, int axis,
+ RawAbsoluteAxisInfo* outAxisInfo) const;
+
virtual status_t scancodeToKeycode(int32_t deviceId, int scancode,
int32_t* outKeycode, uint32_t* outFlags) const;
virtual void addExcludedDevice(const char* deviceName);
- virtual int32_t getScanCodeState(int32_t deviceId, int32_t deviceClasses,
- int32_t scanCode) const;
- virtual int32_t getKeyCodeState(int32_t deviceId, int32_t deviceClasses,
- int32_t keyCode) const;
- virtual int32_t getSwitchState(int32_t deviceId, int32_t deviceClasses,
- int32_t sw) const;
+ virtual int32_t getScanCodeState(int32_t deviceId, int32_t scanCode) const;
+ virtual int32_t getKeyCodeState(int32_t deviceId, int32_t keyCode) const;
+ virtual int32_t getSwitchState(int32_t deviceId, int32_t sw) const;
- virtual bool hasKeys(size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) const;
+ virtual bool markSupportedKeyCodes(int32_t deviceId, size_t numCodes,
+ const int32_t* keyCodes, uint8_t* outFlags) const;
- virtual bool getEvent(int32_t* outDeviceId, int32_t* outType,
- int32_t* outScancode, int32_t* outKeycode, uint32_t *outFlags,
- int32_t* outValue, nsecs_t* outWhen);
+ virtual bool getEvent(RawEvent* outEvent);
protected:
virtual ~EventHub();
private:
bool openPlatformInput(void);
- int32_t convertDeviceKey_TI_P2(int code);
int open_device(const char *device);
int close_device(const char *device);
@@ -220,6 +236,8 @@ private:
int32_t getScanCodeStateLocked(device_t* device, int32_t scanCode) const;
int32_t getKeyCodeStateLocked(device_t* device, int32_t keyCode) const;
int32_t getSwitchStateLocked(device_t* device, int32_t sw) const;
+ bool markSupportedKeyCodesLocked(device_t* device, size_t numCodes,
+ const int32_t* keyCodes, uint8_t* outFlags) const;
// Protect all internal state.
mutable Mutex mLock;
diff --git a/include/ui/Input.h b/include/ui/Input.h
index d9b1091..2385973 100644
--- a/include/ui/Input.h
+++ b/include/ui/Input.h
@@ -23,7 +23,10 @@
#include <android/input.h>
#include <utils/Vector.h>
+#include <utils/KeyedVector.h>
#include <utils/Timers.h>
+#include <utils/RefBase.h>
+#include <utils/String8.h>
/*
* Additional private constants not defined in ndk/ui/input.h.
@@ -47,21 +50,16 @@ struct AInputEvent {
virtual ~AInputEvent() { }
};
-namespace android {
-
/*
- * A raw event as retrieved from the EventHub.
+ * Declare a concrete type for the NDK's input device forward declaration.
*/
-struct RawEvent {
- nsecs_t when;
- int32_t deviceId;
- int32_t type;
- int32_t scanCode;
- int32_t keyCode;
- int32_t value;
- uint32_t flags;
+struct AInputDevice {
+ virtual ~AInputDevice() { }
};
+
+namespace android {
+
/*
* Flags that flow alongside events in the input dispatch system to help with certain
* policy decisions such as waking from device sleep.
@@ -424,6 +422,69 @@ private:
MotionEvent mMotionEvent;
};
+/*
+ * Describes the characteristics and capabilities of an input device.
+ */
+class InputDeviceInfo {
+public:
+ InputDeviceInfo();
+ InputDeviceInfo(const InputDeviceInfo& other);
+ ~InputDeviceInfo();
+
+ struct MotionRange {
+ float min;
+ float max;
+ float flat;
+ float fuzz;
+ };
+
+ void initialize(int32_t id, const String8& name);
+
+ inline int32_t getId() const { return mId; }
+ inline const String8 getName() const { return mName; }
+ inline uint32_t getSources() const { return mSources; }
+
+ const MotionRange* getMotionRange(int32_t rangeType) const;
+
+ void addSource(uint32_t source);
+ void addMotionRange(int32_t rangeType, float min, float max, float flat, float fuzz);
+ void addMotionRange(int32_t rangeType, const MotionRange& range);
+
+ inline void setKeyboardType(int32_t keyboardType) { mKeyboardType = keyboardType; }
+ inline int32_t getKeyboardType() const { return mKeyboardType; }
+
+private:
+ int32_t mId;
+ String8 mName;
+ uint32_t mSources;
+ int32_t mKeyboardType;
+
+ KeyedVector<int32_t, MotionRange> mMotionRanges;
+};
+
+/*
+ * Provides remote access to information about an input device.
+ *
+ * Note: This is essentially a wrapper for Binder calls into the Window Manager Service.
+ */
+class InputDeviceProxy : public RefBase, public AInputDevice {
+protected:
+ InputDeviceProxy();
+ virtual ~InputDeviceProxy();
+
+public:
+ static void getDeviceIds(Vector<int32_t>& outIds);
+
+ static sp<InputDeviceProxy> getDevice(int32_t id);
+
+ inline const InputDeviceInfo* getInfo() { return & mInfo; }
+
+ // TODO add hasKeys, keymap, etc...
+
+private:
+ InputDeviceInfo mInfo;
+};
+
} // namespace android
diff --git a/include/ui/InputDevice.h b/include/ui/InputDevice.h
deleted file mode 100644
index 3b9c70e..0000000
--- a/include/ui/InputDevice.h
+++ /dev/null
@@ -1,353 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _UI_INPUT_DEVICE_H
-#define _UI_INPUT_DEVICE_H
-
-#include <ui/EventHub.h>
-#include <ui/Input.h>
-#include <utils/KeyedVector.h>
-#include <utils/threads.h>
-#include <utils/Timers.h>
-#include <utils/RefBase.h>
-#include <utils/String8.h>
-#include <utils/BitSet.h>
-
-#include <stddef.h>
-#include <unistd.h>
-
-/* Maximum pointer id value supported.
- * (This is limited by our use of BitSet32 to track pointer assignments.) */
-#define MAX_POINTER_ID 31
-
-/* Maximum number of historical samples to average. */
-#define AVERAGING_HISTORY_SIZE 5
-
-
-namespace android {
-
-extern int32_t updateMetaState(int32_t keyCode, bool down, int32_t oldMetaState);
-extern int32_t rotateKeyCode(int32_t keyCode, int32_t orientation);
-
-
-/*
- * An input device structure tracks the state of a single input device.
- *
- * This structure is only used by ReaderThread and is not intended to be shared with
- * DispatcherThread (because that would require locking). This works out fine because
- * DispatcherThread is only interested in cooked event data anyways and does not need
- * any of the low-level data from InputDevice.
- */
-struct InputDevice {
- struct AbsoluteAxisInfo {
- bool valid; // set to true if axis parameters are known, false otherwise
-
- int32_t minValue; // minimum value
- int32_t maxValue; // maximum value
- int32_t range; // range of values, equal to maxValue - minValue
- int32_t flat; // center flat position, eg. flat == 8 means center is between -8 and 8
- int32_t fuzz; // error tolerance, eg. fuzz == 4 means value is +/- 4 due to noise
- };
-
- struct VirtualKey {
- int32_t keyCode;
- int32_t scanCode;
- uint32_t flags;
-
- // computed hit box, specified in touch screen coords based on known display size
- int32_t hitLeft;
- int32_t hitTop;
- int32_t hitRight;
- int32_t hitBottom;
-
- inline bool isHit(int32_t x, int32_t y) const {
- return x >= hitLeft && x <= hitRight && y >= hitTop && y <= hitBottom;
- }
- };
-
- struct KeyboardState {
- struct Current {
- int32_t metaState;
- nsecs_t downTime; // time of most recent key down
- } current;
-
- void reset();
- };
-
- struct TrackballState {
- struct Accumulator {
- enum {
- FIELD_BTN_MOUSE = 1,
- FIELD_REL_X = 2,
- FIELD_REL_Y = 4
- };
-
- uint32_t fields;
-
- bool btnMouse;
- int32_t relX;
- int32_t relY;
-
- inline void clear() {
- fields = 0;
- }
-
- inline bool isDirty() {
- return fields != 0;
- }
- } accumulator;
-
- struct Current {
- bool down;
- nsecs_t downTime;
- } current;
-
- struct Precalculated {
- float xScale;
- float yScale;
- float xPrecision;
- float yPrecision;
- } precalculated;
-
- void reset();
- };
-
- struct SingleTouchScreenState {
- struct Accumulator {
- enum {
- FIELD_BTN_TOUCH = 1,
- FIELD_ABS_X = 2,
- FIELD_ABS_Y = 4,
- FIELD_ABS_PRESSURE = 8,
- FIELD_ABS_TOOL_WIDTH = 16
- };
-
- uint32_t fields;
-
- bool btnTouch;
- int32_t absX;
- int32_t absY;
- int32_t absPressure;
- int32_t absToolWidth;
-
- inline void clear() {
- fields = 0;
- }
-
- inline bool isDirty() {
- return fields != 0;
- }
- } accumulator;
-
- struct Current {
- bool down;
- int32_t x;
- int32_t y;
- int32_t pressure;
- int32_t size;
- } current;
-
- void reset();
- };
-
- struct MultiTouchScreenState {
- struct Accumulator {
- enum {
- FIELD_ABS_MT_POSITION_X = 1,
- FIELD_ABS_MT_POSITION_Y = 2,
- FIELD_ABS_MT_TOUCH_MAJOR = 4,
- FIELD_ABS_MT_TOUCH_MINOR = 8,
- FIELD_ABS_MT_WIDTH_MAJOR = 16,
- FIELD_ABS_MT_WIDTH_MINOR = 32,
- FIELD_ABS_MT_ORIENTATION = 64,
- FIELD_ABS_MT_TRACKING_ID = 128
- };
-
- uint32_t pointerCount;
- struct Pointer {
- uint32_t fields;
-
- int32_t absMTPositionX;
- int32_t absMTPositionY;
- int32_t absMTTouchMajor;
- int32_t absMTTouchMinor;
- int32_t absMTWidthMajor;
- int32_t absMTWidthMinor;
- int32_t absMTOrientation;
- int32_t absMTTrackingId;
-
- inline void clear() {
- fields = 0;
- }
- } pointers[MAX_POINTERS + 1]; // + 1 to remove the need for extra range checks
-
- inline void clear() {
- pointerCount = 0;
- pointers[0].clear();
- }
-
- inline bool isDirty() {
- return pointerCount != 0;
- }
- } accumulator;
-
- void reset();
- };
-
- struct PointerData {
- uint32_t id;
- int32_t x;
- int32_t y;
- int32_t pressure;
- int32_t size;
- int32_t touchMajor;
- int32_t touchMinor;
- int32_t toolMajor;
- int32_t toolMinor;
- int32_t orientation;
- };
-
- struct TouchData {
- uint32_t pointerCount;
- PointerData pointers[MAX_POINTERS];
- BitSet32 idBits;
- uint32_t idToIndex[MAX_POINTER_ID + 1];
-
- void copyFrom(const TouchData& other);
-
- inline void clear() {
- pointerCount = 0;
- idBits.clear();
- }
- };
-
- // common state used for both single-touch and multi-touch screens after the initial
- // touch decoding has been performed
- struct TouchScreenState {
- Vector<VirtualKey> virtualKeys;
-
- struct Parameters {
- bool useBadTouchFilter;
- bool useJumpyTouchFilter;
- bool useAveragingTouchFilter;
-
- AbsoluteAxisInfo xAxis;
- AbsoluteAxisInfo yAxis;
- AbsoluteAxisInfo pressureAxis;
- AbsoluteAxisInfo sizeAxis;
- AbsoluteAxisInfo orientationAxis;
- } parameters;
-
- // The touch data of the current sample being processed.
- TouchData currentTouch;
-
- // The touch data of the previous sample that was processed. This is updated
- // incrementally while the current sample is being processed.
- TouchData lastTouch;
-
- // The time the primary pointer last went down.
- nsecs_t downTime;
-
- struct CurrentVirtualKeyState {
- enum Status {
- STATUS_UP,
- STATUS_DOWN,
- STATUS_CANCELED
- };
-
- Status status;
- nsecs_t downTime;
- int32_t keyCode;
- int32_t scanCode;
- } currentVirtualKey;
-
- struct AveragingTouchFilterState {
- // Individual history tracks are stored by pointer id
- uint32_t historyStart[MAX_POINTERS];
- uint32_t historyEnd[MAX_POINTERS];
- struct {
- struct {
- int32_t x;
- int32_t y;
- int32_t pressure;
- } pointers[MAX_POINTERS];
- } historyData[AVERAGING_HISTORY_SIZE];
- } averagingTouchFilter;
-
- struct JumpTouchFilterState {
- int32_t jumpyPointsDropped;
- } jumpyTouchFilter;
-
- struct Precalculated {
- int32_t xOrigin;
- float xScale;
-
- int32_t yOrigin;
- float yScale;
-
- int32_t pressureOrigin;
- float pressureScale;
-
- int32_t sizeOrigin;
- float sizeScale;
-
- float orientationScale;
- } precalculated;
-
- void reset();
-
- bool applyBadTouchFilter();
- bool applyJumpyTouchFilter();
- void applyAveragingTouchFilter();
- void calculatePointerIds();
-
- bool isPointInsideDisplay(int32_t x, int32_t y) const;
- const InputDevice::VirtualKey* findVirtualKeyHit() const;
- };
-
- InputDevice(int32_t id, uint32_t classes, String8 name);
-
- int32_t id;
- uint32_t classes;
- String8 name;
- bool ignored;
-
- KeyboardState keyboard;
- TrackballState trackball;
- TouchScreenState touchScreen;
- union {
- SingleTouchScreenState singleTouchScreen;
- MultiTouchScreenState multiTouchScreen;
- };
-
- void reset();
-
- inline bool isKeyboard() const { return classes & INPUT_DEVICE_CLASS_KEYBOARD; }
- inline bool isAlphaKey() const { return classes & INPUT_DEVICE_CLASS_ALPHAKEY; }
- inline bool isTrackball() const { return classes & INPUT_DEVICE_CLASS_TRACKBALL; }
- inline bool isDPad() const { return classes & INPUT_DEVICE_CLASS_DPAD; }
- inline bool isSingleTouchScreen() const { return (classes
- & (INPUT_DEVICE_CLASS_TOUCHSCREEN | INPUT_DEVICE_CLASS_TOUCHSCREEN_MT))
- == INPUT_DEVICE_CLASS_TOUCHSCREEN; }
- inline bool isMultiTouchScreen() const { return classes
- & INPUT_DEVICE_CLASS_TOUCHSCREEN_MT; }
- inline bool isTouchScreen() const { return classes
- & (INPUT_DEVICE_CLASS_TOUCHSCREEN | INPUT_DEVICE_CLASS_TOUCHSCREEN_MT); }
-};
-
-} // namespace android
-
-#endif // _UI_INPUT_DEVICE_H
diff --git a/include/ui/InputManager.h b/include/ui/InputManager.h
index e755238..7ebec10 100644
--- a/include/ui/InputManager.h
+++ b/include/ui/InputManager.h
@@ -96,22 +96,28 @@ public:
virtual void preemptInputDispatch() = 0;
/* Gets input device configuration. */
- virtual void getInputConfiguration(InputConfiguration* outConfiguration) const = 0;
+ virtual void getInputConfiguration(InputConfiguration* outConfiguration) = 0;
- /*
- * Queries current input state.
- * deviceId may be -1 to search for the device automatically, filtered by class.
- * deviceClasses may be -1 to ignore device class while searching.
+ /* Gets information about the specified input device.
+ * Returns OK if the device information was obtained or NAME_NOT_FOUND if there
+ * was no such device.
*/
- virtual int32_t getScanCodeState(int32_t deviceId, int32_t deviceClasses,
- int32_t scanCode) const = 0;
- virtual int32_t getKeyCodeState(int32_t deviceId, int32_t deviceClasses,
- int32_t keyCode) const = 0;
- virtual int32_t getSwitchState(int32_t deviceId, int32_t deviceClasses,
- int32_t sw) const = 0;
+ virtual status_t getInputDeviceInfo(int32_t deviceId, InputDeviceInfo* outDeviceInfo) = 0;
+
+ /* Gets the list of all registered device ids. */
+ virtual void getInputDeviceIds(Vector<int32_t>& outDeviceIds) = 0;
+
+ /* Queries current input state. */
+ virtual int32_t getScanCodeState(int32_t deviceId, uint32_t sourceMask,
+ int32_t scanCode) = 0;
+ virtual int32_t getKeyCodeState(int32_t deviceId, uint32_t sourceMask,
+ int32_t keyCode) = 0;
+ virtual int32_t getSwitchState(int32_t deviceId, uint32_t sourceMask,
+ int32_t sw) = 0;
/* Determines whether physical keys exist for the given framework-domain key codes. */
- virtual bool hasKeys(size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) const = 0;
+ virtual bool hasKeys(int32_t deviceId, uint32_t sourceMask,
+ size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) = 0;
};
class InputManager : public InputManagerInterface {
@@ -140,14 +146,17 @@ public:
virtual void preemptInputDispatch();
- virtual void getInputConfiguration(InputConfiguration* outConfiguration) const;
- virtual int32_t getScanCodeState(int32_t deviceId, int32_t deviceClasses,
- int32_t scanCode) const;
- virtual int32_t getKeyCodeState(int32_t deviceId, int32_t deviceClasses,
- int32_t keyCode) const;
- virtual int32_t getSwitchState(int32_t deviceId, int32_t deviceClasses,
- int32_t sw) const;
- virtual bool hasKeys(size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) const;
+ virtual void getInputConfiguration(InputConfiguration* outConfiguration);
+ virtual status_t getInputDeviceInfo(int32_t deviceId, InputDeviceInfo* outDeviceInfo);
+ virtual void getInputDeviceIds(Vector<int32_t>& outDeviceIds);
+ virtual int32_t getScanCodeState(int32_t deviceId, uint32_t sourceMask,
+ int32_t scanCode);
+ virtual int32_t getKeyCodeState(int32_t deviceId, uint32_t sourceMask,
+ int32_t keyCode);
+ virtual int32_t getSwitchState(int32_t deviceId, uint32_t sourceMask,
+ int32_t sw);
+ virtual bool hasKeys(int32_t deviceId, uint32_t sourceMask,
+ size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags);
private:
sp<InputReaderInterface> mReader;
diff --git a/include/ui/InputReader.h b/include/ui/InputReader.h
index 14bea65..d7ec8ea 100644
--- a/include/ui/InputReader.h
+++ b/include/ui/InputReader.h
@@ -19,7 +19,6 @@
#include <ui/EventHub.h>
#include <ui/Input.h>
-#include <ui/InputDevice.h>
#include <ui/InputDispatcher.h>
#include <utils/KeyedVector.h>
#include <utils/threads.h>
@@ -33,6 +32,10 @@
namespace android {
+class InputDevice;
+class InputMapper;
+
+
/*
* Input reader policy interface.
*
@@ -68,14 +71,6 @@ public:
// The input dispatcher should perform special filtering in preparation for
// a pending app switch.
ACTION_APP_SWITCH_COMING = 0x00000002,
-
- // The input dispatcher should add POLICY_FLAG_WOKE_HERE to the policy flags it
- // passes through the dispatch pipeline.
- ACTION_WOKE_HERE = 0x00000004,
-
- // The input dispatcher should add POLICY_FLAG_BRIGHT_HERE to the policy flags it
- // passes through the dispatch pipeline.
- ACTION_BRIGHT_HERE = 0x00000008,
};
/* Describes a virtual key. */
@@ -101,38 +96,30 @@ public:
/* Intercepts a key event.
* The policy can use this method as an opportunity to perform power management functions
- * and early event preprocessing.
+ * and early event preprocessing such as updating policy flags.
*
* Returns a policy action constant such as ACTION_DISPATCH.
*/
virtual int32_t interceptKey(nsecs_t when, int32_t deviceId,
- bool down, int32_t keyCode, int32_t scanCode, uint32_t policyFlags) = 0;
+ bool down, int32_t keyCode, int32_t scanCode, uint32_t& policyFlags) = 0;
- /* Intercepts a trackball event.
+ /* Intercepts a switch event.
* The policy can use this method as an opportunity to perform power management functions
- * and early event preprocessing.
+ * and early event preprocessing such as updating policy flags.
*
- * Returns a policy action constant such as ACTION_DISPATCH.
+ * Switches are not dispatched to applications so this method should
+ * usually return ACTION_NONE.
*/
- virtual int32_t interceptTrackball(nsecs_t when, bool buttonChanged, bool buttonDown,
- bool rolled) = 0;
+ virtual int32_t interceptSwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
+ uint32_t& policyFlags) = 0;
- /* Intercepts a touch event.
+ /* Intercepts a generic touch, trackball or other event.
* The policy can use this method as an opportunity to perform power management functions
- * and early event preprocessing.
+ * and early event preprocessing such as updating policy flags.
*
* Returns a policy action constant such as ACTION_DISPATCH.
*/
- virtual int32_t interceptTouch(nsecs_t when) = 0;
-
- /* Intercepts a switch event.
- * The policy can use this method as an opportunity to perform power management functions
- * and early event preprocessing.
- *
- * Switches are not dispatched to applications so this method should
- * usually return ACTION_NONE.
- */
- virtual int32_t interceptSwitch(nsecs_t when, int32_t switchCode, int32_t switchValue) = 0;
+ virtual int32_t interceptGeneric(nsecs_t when, uint32_t& policyFlags) = 0;
/* Determines whether to turn on some hacks we have to improve the touch interaction with a
* certain device whose screen currently is not all that good.
@@ -167,32 +154,52 @@ public:
*/
virtual void loopOnce() = 0;
- /* Gets the current virtual key. Returns false if not down.
+ /* Gets the current input device configuration.
*
* This method may be called on any thread (usually by the input manager).
*/
- virtual bool getCurrentVirtualKey(int32_t* outKeyCode, int32_t* outScanCode) const = 0;
+ virtual void getInputConfiguration(InputConfiguration* outConfiguration) = 0;
- /* Gets the current input device configuration.
+ /* Gets information about the specified input device.
+ * Returns OK if the device information was obtained or NAME_NOT_FOUND if there
+ * was no such device.
*
* This method may be called on any thread (usually by the input manager).
*/
- virtual void getCurrentInputConfiguration(InputConfiguration* outConfiguration) const = 0;
+ virtual status_t getInputDeviceInfo(int32_t deviceId, InputDeviceInfo* outDeviceInfo) = 0;
- /*
- * Query current input state.
- * deviceId may be -1 to search for the device automatically, filtered by class.
- * deviceClasses may be -1 to ignore device class while searching.
- */
- virtual int32_t getCurrentScanCodeState(int32_t deviceId, int32_t deviceClasses,
- int32_t scanCode) const = 0;
- virtual int32_t getCurrentKeyCodeState(int32_t deviceId, int32_t deviceClasses,
- int32_t keyCode) const = 0;
- virtual int32_t getCurrentSwitchState(int32_t deviceId, int32_t deviceClasses,
- int32_t sw) const = 0;
+ /* Gets the list of all registered device ids. */
+ virtual void getInputDeviceIds(Vector<int32_t>& outDeviceIds) = 0;
+
+ /* Query current input state. */
+ virtual int32_t getScanCodeState(int32_t deviceId, uint32_t sourceMask,
+ int32_t scanCode) = 0;
+ virtual int32_t getKeyCodeState(int32_t deviceId, uint32_t sourceMask,
+ int32_t keyCode) = 0;
+ virtual int32_t getSwitchState(int32_t deviceId, uint32_t sourceMask,
+ int32_t sw) = 0;
/* Determine whether physical keys exist for the given framework-domain key codes. */
- virtual bool hasKeys(size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) const = 0;
+ virtual bool hasKeys(int32_t deviceId, uint32_t sourceMask,
+ size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) = 0;
+};
+
+
+/* Internal interface used by individual input devices to access global input device state
+ * and parameters maintained by the input reader.
+ */
+class InputReaderContext {
+protected:
+ InputReaderContext() { }
+ virtual ~InputReaderContext() { }
+
+public:
+ virtual void updateGlobalMetaState() = 0;
+ virtual int32_t getGlobalMetaState() = 0;
+
+ virtual InputReaderPolicyInterface* getPolicy() = 0;
+ virtual InputDispatcherInterface* getDispatcher() = 0;
+ virtual EventHubInterface* getEventHub() = 0;
};
@@ -201,10 +208,11 @@ public:
* event filtering in low power states, are controlled by a separate policy object.
*
* IMPORTANT INVARIANT:
- * Because the policy can potentially block or cause re-entrance into the input reader,
- * the input reader never calls into the policy while holding its internal locks.
+ * 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.
*/
-class InputReader : public InputReaderInterface {
+class InputReader : public InputReaderInterface, private InputReaderContext {
public:
InputReader(const sp<EventHubInterface>& eventHub,
const sp<InputReaderPolicyInterface>& policy,
@@ -213,107 +221,69 @@ public:
virtual void loopOnce();
- virtual bool getCurrentVirtualKey(int32_t* outKeyCode, int32_t* outScanCode) const;
+ virtual void getInputConfiguration(InputConfiguration* outConfiguration);
- virtual void getCurrentInputConfiguration(InputConfiguration* outConfiguration) const;
+ virtual status_t getInputDeviceInfo(int32_t deviceId, InputDeviceInfo* outDeviceInfo);
+ virtual void getInputDeviceIds(Vector<int32_t>& outDeviceIds);
- virtual int32_t getCurrentScanCodeState(int32_t deviceId, int32_t deviceClasses,
- int32_t scanCode) const;
- virtual int32_t getCurrentKeyCodeState(int32_t deviceId, int32_t deviceClasses,
- int32_t keyCode) const;
- virtual int32_t getCurrentSwitchState(int32_t deviceId, int32_t deviceClasses,
- int32_t sw) const;
+ virtual int32_t getScanCodeState(int32_t deviceId, uint32_t sourceMask,
+ int32_t scanCode);
+ virtual int32_t getKeyCodeState(int32_t deviceId, uint32_t sourceMask,
+ int32_t keyCode);
+ virtual int32_t getSwitchState(int32_t deviceId, uint32_t sourceMask,
+ int32_t sw);
- virtual bool hasKeys(size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) const;
+ virtual bool hasKeys(int32_t deviceId, uint32_t sourceMask,
+ size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags);
private:
- // Lock that must be acquired while manipulating state that may be concurrently accessed
- // from other threads by input state query methods. It should be held for as short a
- // time as possible.
- //
- // Exported state:
- // - global virtual key code and scan code
- // - device list and immutable properties of devices such as id, name, and class
- // (but not other internal device state)
- mutable Mutex mExportedStateLock;
-
- // current virtual key information (lock mExportedStateLock)
- int32_t mExportedVirtualKeyCode;
- int32_t mExportedVirtualScanCode;
-
- // current input configuration (lock mExportedStateLock)
- InputConfiguration mExportedInputConfiguration;
-
- // combined key meta state
- int32_t mGlobalMetaState;
-
sp<EventHubInterface> mEventHub;
sp<InputReaderPolicyInterface> mPolicy;
sp<InputDispatcherInterface> mDispatcher;
+ virtual InputReaderPolicyInterface* getPolicy() { return mPolicy.get(); }
+ virtual InputDispatcherInterface* getDispatcher() { return mDispatcher.get(); }
+ virtual EventHubInterface* getEventHub() { return mEventHub.get(); }
+
+ // This reader/writer lock guards the list of input devices.
+ // The writer lock must be held whenever the list of input devices is modified
+ // and then promptly released.
+ // The reader lock must be held whenever the list of input devices is traversed or an
+ // input device in the list is accessed.
+ // This lock only protects the registry and prevents inadvertent deletion of device objects
+ // that are in use. Individual devices are responsible for guarding their own internal state
+ // as needed for concurrent operation.
+ RWLock mDeviceRegistryLock;
KeyedVector<int32_t, InputDevice*> mDevices;
- // display properties needed to translate touch screen coordinates into display coordinates
- int32_t mDisplayOrientation;
- int32_t mDisplayWidth;
- int32_t mDisplayHeight;
-
- // low-level input event decoding
+ // low-level input event decoding and device management
void process(const RawEvent* rawEvent);
- void handleDeviceAdded(const RawEvent* rawEvent);
- void handleDeviceRemoved(const RawEvent* rawEvent);
- void handleSync(const RawEvent* rawEvent);
- void handleKey(const RawEvent* rawEvent);
- void handleRelativeMotion(const RawEvent* rawEvent);
- void handleAbsoluteMotion(const RawEvent* rawEvent);
- void handleSwitch(const RawEvent* rawEvent);
-
- // input policy processing and dispatch
- void onKey(nsecs_t when, InputDevice* device, bool down,
- int32_t keyCode, int32_t scanCode, uint32_t policyFlags);
- void onSwitch(nsecs_t when, InputDevice* device, int32_t switchCode, int32_t switchValue);
- void onSingleTouchScreenStateChanged(nsecs_t when, InputDevice* device);
- void onMultiTouchScreenStateChanged(nsecs_t when, InputDevice* device);
- void onTouchScreenChanged(nsecs_t when, InputDevice* device, bool havePointerIds);
- void onTrackballStateChanged(nsecs_t when, InputDevice* device);
- void onConfigurationChanged(nsecs_t when);
-
- bool applyStandardInputDispatchPolicyActions(nsecs_t when,
- int32_t policyActions, uint32_t* policyFlags);
-
- bool consumeVirtualKeyTouches(nsecs_t when, InputDevice* device, uint32_t policyFlags);
- void dispatchVirtualKey(nsecs_t when, InputDevice* device, uint32_t policyFlags,
- int32_t keyEventAction, int32_t keyEventFlags);
- void dispatchTouches(nsecs_t when, InputDevice* device, uint32_t policyFlags);
- void dispatchTouch(nsecs_t when, InputDevice* device, uint32_t policyFlags,
- InputDevice::TouchData* touch, BitSet32 idBits, uint32_t changedId,
- int32_t motionEventAction);
-
- // display
- void resetDisplayProperties();
- bool refreshDisplayProperties();
-
- // device management
- InputDevice* getDevice(int32_t deviceId);
- InputDevice* getNonIgnoredDevice(int32_t deviceId);
+
void addDevice(nsecs_t when, int32_t deviceId);
- void removeDevice(nsecs_t when, InputDevice* device);
- void configureDevice(InputDevice* device);
- void configureDeviceForCurrentDisplaySize(InputDevice* device);
- void configureVirtualKeys(InputDevice* device);
- void configureAbsoluteAxisInfo(InputDevice* device, int axis, const char* name,
- InputDevice::AbsoluteAxisInfo* out);
+ void removeDevice(nsecs_t when, int32_t deviceId);
+ InputDevice* createDevice(int32_t deviceId, const String8& name, uint32_t classes);
void configureExcludedDevices();
- // global meta state management for all devices
- void resetGlobalMetaState();
- int32_t globalMetaState();
+ void consumeEvent(const RawEvent* rawEvent);
+
+ void handleConfigurationChanged(nsecs_t when);
- // virtual key management
- void updateExportedVirtualKeyState();
+ // state management for all devices
+ Mutex mStateLock;
- // input configuration management
- void updateExportedInputConfiguration();
+ int32_t mGlobalMetaState;
+ virtual void updateGlobalMetaState();
+ virtual int32_t getGlobalMetaState();
+
+ InputConfiguration mInputConfiguration;
+ void updateInputConfiguration();
+
+ // state queries
+ typedef int32_t (InputDevice::*GetStateFunc)(uint32_t sourceMask, int32_t code);
+ int32_t getState(int32_t deviceId, uint32_t sourceMask, int32_t code,
+ GetStateFunc getStateFunc);
+ bool markSupportedKeyCodes(int32_t deviceId, uint32_t sourceMask, size_t numCodes,
+ const int32_t* keyCodes, uint8_t* outFlags);
};
@@ -329,6 +299,527 @@ private:
virtual bool threadLoop();
};
+
+/* Represents the state of a single input device. */
+class InputDevice {
+public:
+ InputDevice(InputReaderContext* context, int32_t id, const String8& name);
+ ~InputDevice();
+
+ inline InputReaderContext* getContext() { return mContext; }
+ inline int32_t getId() { return mId; }
+ inline const String8& getName() { return mName; }
+ inline uint32_t getSources() { return mSources; }
+
+ inline bool isIgnored() { return mMappers.isEmpty(); }
+
+ void addMapper(InputMapper* mapper);
+ void configure();
+ void reset();
+ void process(const RawEvent* rawEvent);
+
+ void getDeviceInfo(InputDeviceInfo* outDeviceInfo);
+ int32_t getKeyCodeState(uint32_t sourceMask, int32_t keyCode);
+ int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode);
+ int32_t getSwitchState(uint32_t sourceMask, int32_t switchCode);
+ bool markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
+ const int32_t* keyCodes, uint8_t* outFlags);
+
+ int32_t getMetaState();
+
+private:
+ InputReaderContext* mContext;
+ int32_t mId;
+
+ Vector<InputMapper*> mMappers;
+
+ String8 mName;
+ uint32_t mSources;
+
+ typedef int32_t (InputMapper::*GetStateFunc)(uint32_t sourceMask, int32_t code);
+ int32_t getState(uint32_t sourceMask, int32_t code, GetStateFunc getStateFunc);
+};
+
+
+/* An input mapper transforms raw input events into cooked event data.
+ * A single input device can have multiple associated input mappers in order to interpret
+ * different classes of events.
+ */
+class InputMapper {
+public:
+ InputMapper(InputDevice* device);
+ virtual ~InputMapper();
+
+ inline InputDevice* getDevice() { return mDevice; }
+ inline int32_t getDeviceId() { return mDevice->getId(); }
+ inline const String8 getDeviceName() { return mDevice->getName(); }
+ inline InputReaderContext* getContext() { return mContext; }
+ inline InputReaderPolicyInterface* getPolicy() { return mContext->getPolicy(); }
+ inline InputDispatcherInterface* getDispatcher() { return mContext->getDispatcher(); }
+ inline EventHubInterface* getEventHub() { return mContext->getEventHub(); }
+
+ virtual uint32_t getSources() = 0;
+ virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo);
+ virtual void configure();
+ virtual void reset();
+ virtual void process(const RawEvent* rawEvent) = 0;
+
+ virtual int32_t getKeyCodeState(uint32_t sourceMask, int32_t keyCode);
+ virtual int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode);
+ virtual int32_t getSwitchState(uint32_t sourceMask, int32_t switchCode);
+ virtual bool markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
+ const int32_t* keyCodes, uint8_t* outFlags);
+
+ virtual int32_t getMetaState();
+
+protected:
+ InputDevice* mDevice;
+ InputReaderContext* mContext;
+
+ bool applyStandardPolicyActions(nsecs_t when, int32_t policyActions);
+};
+
+
+class SwitchInputMapper : public InputMapper {
+public:
+ SwitchInputMapper(InputDevice* device);
+ virtual ~SwitchInputMapper();
+
+ virtual uint32_t getSources();
+ virtual void process(const RawEvent* rawEvent);
+
+ virtual int32_t getSwitchState(uint32_t sourceMask, int32_t switchCode);
+
+private:
+ void processSwitch(nsecs_t when, int32_t switchCode, int32_t switchValue);
+};
+
+
+class KeyboardInputMapper : public InputMapper {
+public:
+ KeyboardInputMapper(InputDevice* device, int32_t associatedDisplayId, uint32_t sources,
+ int32_t keyboardType);
+ virtual ~KeyboardInputMapper();
+
+ virtual uint32_t getSources();
+ virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo);
+ virtual void reset();
+ virtual void process(const RawEvent* rawEvent);
+
+ virtual int32_t getKeyCodeState(uint32_t sourceMask, int32_t keyCode);
+ virtual int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode);
+ virtual bool markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
+ const int32_t* keyCodes, uint8_t* outFlags);
+
+ virtual int32_t getMetaState();
+
+private:
+ struct KeyDown {
+ int32_t keyCode;
+ int32_t scanCode;
+ };
+
+ int32_t mAssociatedDisplayId;
+ 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
+
+ void initialize();
+
+ bool isKeyboardOrGamepadKey(int32_t scanCode);
+ void processKey(nsecs_t when, bool down, int32_t keyCode, int32_t scanCode,
+ uint32_t policyFlags);
+
+ ssize_t findKeyDown(int32_t scanCode);
+};
+
+
+class TrackballInputMapper : public InputMapper {
+public:
+ TrackballInputMapper(InputDevice* device, int32_t associatedDisplayId);
+ virtual ~TrackballInputMapper();
+
+ virtual uint32_t getSources();
+ virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo);
+ virtual void reset();
+ virtual void process(const RawEvent* rawEvent);
+
+private:
+ // Amount that trackball needs to move in order to generate a key event.
+ static const int32_t TRACKBALL_MOVEMENT_THRESHOLD = 6;
+
+ int32_t mAssociatedDisplayId;
+
+ struct Accumulator {
+ enum {
+ FIELD_BTN_MOUSE = 1,
+ FIELD_REL_X = 2,
+ FIELD_REL_Y = 4
+ };
+
+ uint32_t fields;
+
+ bool btnMouse;
+ int32_t relX;
+ int32_t relY;
+
+ inline void clear() {
+ fields = 0;
+ }
+
+ inline bool isDirty() {
+ return fields != 0;
+ }
+ } mAccumulator;
+
+ bool mDown;
+ nsecs_t mDownTime;
+
+ float mXScale;
+ float mYScale;
+ float mXPrecision;
+ float mYPrecision;
+
+ void initialize();
+
+ void sync(nsecs_t when);
+};
+
+
+class TouchInputMapper : public InputMapper {
+public:
+ TouchInputMapper(InputDevice* device, int32_t associatedDisplayId);
+ virtual ~TouchInputMapper();
+
+ virtual uint32_t getSources();
+ virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo);
+ virtual void configure();
+ virtual void reset();
+
+ virtual int32_t getKeyCodeState(uint32_t sourceMask, int32_t keyCode);
+ virtual int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode);
+ virtual bool markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
+ 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;
+
+ struct VirtualKey {
+ int32_t keyCode;
+ int32_t scanCode;
+ uint32_t flags;
+
+ // computed hit box, specified in touch screen coords based on known display size
+ int32_t hitLeft;
+ int32_t hitTop;
+ int32_t hitRight;
+ int32_t hitBottom;
+
+ inline bool isHit(int32_t x, int32_t y) const {
+ return x >= hitLeft && x <= hitRight && y >= hitTop && y <= hitBottom;
+ }
+ };
+
+ struct PointerData {
+ uint32_t id;
+ int32_t x;
+ int32_t y;
+ int32_t pressure;
+ int32_t size;
+ int32_t touchMajor;
+ int32_t touchMinor;
+ int32_t toolMajor;
+ int32_t toolMinor;
+ int32_t orientation;
+ };
+
+ struct TouchData {
+ uint32_t pointerCount;
+ PointerData pointers[MAX_POINTERS];
+ BitSet32 idBits;
+ uint32_t idToIndex[MAX_POINTER_ID + 1];
+
+ void copyFrom(const TouchData& other) {
+ pointerCount = other.pointerCount;
+ idBits = other.idBits;
+
+ for (uint32_t i = 0; i < pointerCount; i++) {
+ pointers[i] = other.pointers[i];
+ idToIndex[i] = other.idToIndex[i];
+ }
+ }
+
+ inline void clear() {
+ pointerCount = 0;
+ idBits.clear();
+ }
+ };
+
+ int32_t mAssociatedDisplayId;
+ Vector<VirtualKey> mVirtualKeys;
+
+ // Immutable configuration parameters.
+ struct Parameters {
+ bool useBadTouchFilter;
+ bool useJumpyTouchFilter;
+ bool useAveragingTouchFilter;
+ } mParameters;
+
+ // Raw axis information.
+ struct Axes {
+ RawAbsoluteAxisInfo x;
+ RawAbsoluteAxisInfo y;
+ RawAbsoluteAxisInfo pressure;
+ RawAbsoluteAxisInfo size;
+ RawAbsoluteAxisInfo touchMajor;
+ RawAbsoluteAxisInfo touchMinor;
+ RawAbsoluteAxisInfo toolMajor;
+ RawAbsoluteAxisInfo toolMinor;
+ 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.
+ 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
+
+ virtual void configureAxes();
+ virtual bool configureSurface();
+ virtual void configureVirtualKeys();
+
+ enum TouchResult {
+ // Dispatch the touch normally.
+ DISPATCH_TOUCH,
+ // Do not dispatch the touch, but keep tracking the current stroke.
+ SKIP_TOUCH,
+ // Do not dispatch the touch, and drop all information associated with the current stoke
+ // so the next movement will appear as a new down.
+ DROP_STROKE
+ };
+
+ void syncTouch(nsecs_t when, bool havePointerIds);
+
+private:
+ /* Maximum number of historical samples to average. */
+ static const uint32_t AVERAGING_HISTORY_SIZE = 5;
+
+ /* Slop distance for jumpy pointer detection.
+ * The vertical range of the screen divided by this is our epsilon value. */
+ static const uint32_t JUMPY_EPSILON_DIVISOR = 212;
+
+ /* Number of jumpy points to drop for touchscreens that need it. */
+ static const uint32_t JUMPY_TRANSITION_DROPS = 3;
+ static const uint32_t JUMPY_DROP_LIMIT = 3;
+
+ /* Maximum squared distance for averaging.
+ * If moving farther than this, turn of averaging to avoid lag in response. */
+ static const uint64_t AVERAGING_DISTANCE_LIMIT = 75 * 75;
+
+ struct AveragingTouchFilterState {
+ // Individual history tracks are stored by pointer id
+ uint32_t historyStart[MAX_POINTERS];
+ uint32_t historyEnd[MAX_POINTERS];
+ struct {
+ struct {
+ int32_t x;
+ int32_t y;
+ int32_t pressure;
+ } pointers[MAX_POINTERS];
+ } historyData[AVERAGING_HISTORY_SIZE];
+ } mAveragingTouchFilter;
+
+ struct JumpTouchFilterState {
+ uint32_t jumpyPointsDropped;
+ } mJumpyTouchFilter;
+
+ struct PointerDistanceHeapElement {
+ uint32_t currentPointerIndex : 8;
+ uint32_t lastPointerIndex : 8;
+ uint64_t distance : 48; // squared distance
+ };
+
+ void initialize();
+
+ 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);
+
+ bool applyBadTouchFilter();
+ bool applyJumpyTouchFilter();
+ void applyAveragingTouchFilter();
+ void calculatePointerIds();
+};
+
+
+class SingleTouchInputMapper : public TouchInputMapper {
+public:
+ SingleTouchInputMapper(InputDevice* device, int32_t associatedDisplayId);
+ virtual ~SingleTouchInputMapper();
+
+ virtual void reset();
+ virtual void process(const RawEvent* rawEvent);
+
+protected:
+ virtual void configureAxes();
+
+private:
+ struct Accumulator {
+ enum {
+ FIELD_BTN_TOUCH = 1,
+ FIELD_ABS_X = 2,
+ FIELD_ABS_Y = 4,
+ FIELD_ABS_PRESSURE = 8,
+ FIELD_ABS_TOOL_WIDTH = 16
+ };
+
+ uint32_t fields;
+
+ bool btnTouch;
+ int32_t absX;
+ int32_t absY;
+ int32_t absPressure;
+ int32_t absToolWidth;
+
+ inline void clear() {
+ fields = 0;
+ }
+
+ inline bool isDirty() {
+ return fields != 0;
+ }
+ } mAccumulator;
+
+ bool mDown;
+ int32_t mX;
+ int32_t mY;
+ int32_t mPressure;
+ int32_t mSize;
+
+ void initialize();
+
+ void sync(nsecs_t when);
+};
+
+
+class MultiTouchInputMapper : public TouchInputMapper {
+public:
+ MultiTouchInputMapper(InputDevice* device, int32_t associatedDisplayId);
+ virtual ~MultiTouchInputMapper();
+
+ virtual void reset();
+ virtual void process(const RawEvent* rawEvent);
+
+protected:
+ virtual void configureAxes();
+
+private:
+ struct Accumulator {
+ enum {
+ FIELD_ABS_MT_POSITION_X = 1,
+ FIELD_ABS_MT_POSITION_Y = 2,
+ FIELD_ABS_MT_TOUCH_MAJOR = 4,
+ FIELD_ABS_MT_TOUCH_MINOR = 8,
+ FIELD_ABS_MT_WIDTH_MAJOR = 16,
+ FIELD_ABS_MT_WIDTH_MINOR = 32,
+ FIELD_ABS_MT_ORIENTATION = 64,
+ FIELD_ABS_MT_TRACKING_ID = 128
+ };
+
+ uint32_t pointerCount;
+ struct Pointer {
+ uint32_t fields;
+
+ int32_t absMTPositionX;
+ int32_t absMTPositionY;
+ int32_t absMTTouchMajor;
+ int32_t absMTTouchMinor;
+ int32_t absMTWidthMajor;
+ int32_t absMTWidthMinor;
+ int32_t absMTOrientation;
+ int32_t absMTTrackingId;
+
+ inline void clear() {
+ fields = 0;
+ }
+ } pointers[MAX_POINTERS + 1]; // + 1 to remove the need for extra range checks
+
+ inline void clear() {
+ pointerCount = 0;
+ pointers[0].clear();
+ }
+
+ inline bool isDirty() {
+ return pointerCount != 0;
+ }
+ } mAccumulator;
+
+ void initialize();
+
+ void sync(nsecs_t when);
+};
+
} // namespace android
#endif // _UI_INPUT_READER_H