diff options
author | Prashant Malani <pmalani@google.com> | 2015-12-08 01:27:17 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2015-12-08 01:27:17 +0000 |
commit | 68fca5a1763203164a19a9aa983895242a671387 (patch) | |
tree | 97aa3c86b0b2b7fa31f3215a6295a5d411bc92a7 | |
parent | 8c3e55f4149deda3ec7c7a67fda81216d5f9af25 (diff) | |
parent | ac72bbf4e46d6689070df09a25db2960a9036eb2 (diff) | |
download | frameworks_native-68fca5a1763203164a19a9aa983895242a671387.zip frameworks_native-68fca5a1763203164a19a9aa983895242a671387.tar.gz frameworks_native-68fca5a1763203164a19a9aa983895242a671387.tar.bz2 |
Merge "inputflinger: Initial support for rotary encoders." into cw-e-dev
-rw-r--r-- | include/android/input.h | 9 | ||||
-rw-r--r-- | services/inputflinger/EventHub.cpp | 9 | ||||
-rw-r--r-- | services/inputflinger/EventHub.h | 3 | ||||
-rw-r--r-- | services/inputflinger/InputReader.cpp | 91 | ||||
-rw-r--r-- | services/inputflinger/InputReader.h | 20 |
5 files changed, 132 insertions, 0 deletions
diff --git a/include/android/input.h b/include/android/input.h index 5ab4e29..5eeb7fc 100644 --- a/include/android/input.h +++ b/include/android/input.h @@ -644,6 +644,13 @@ enum { */ AMOTION_EVENT_AXIS_TILT = 25, /** + * Axis constant: Generic scroll axis of a motion event. + * + * - This is used for scroll axis motion events that can't be classified as strictly + * vertical or horizontal. The movement of a rotating scroller is an example of this. + */ + AMOTION_EVENT_AXIS_SCROLL = 26, + /** * Axis constant: Generic 1 axis of a motion event. * The interpretation of a generic axis is device-specific. */ @@ -817,6 +824,8 @@ enum { AINPUT_SOURCE_TOUCH_NAVIGATION = 0x00200000 | AINPUT_SOURCE_CLASS_NONE, /** joystick */ AINPUT_SOURCE_JOYSTICK = 0x01000000 | AINPUT_SOURCE_CLASS_JOYSTICK, + /** rotary encoder */ + AINPUT_SOURCE_ROTARY_ENCODER = 0x00400000 | AINPUT_SOURCE_CLASS_NONE, /** any */ AINPUT_SOURCE_ANY = 0xffffff00, diff --git a/services/inputflinger/EventHub.cpp b/services/inputflinger/EventHub.cpp index 5859606..2a53dec 100644 --- a/services/inputflinger/EventHub.cpp +++ b/services/inputflinger/EventHub.cpp @@ -1191,6 +1191,15 @@ status_t EventHub::openDeviceLocked(const char *devicePath) { device->classes |= INPUT_DEVICE_CLASS_CURSOR; } + // See if this is a rotary encoder type device. + String8 deviceType = String8(); + if (device->configuration && + device->configuration->tryGetProperty(String8("device.type"), deviceType)) { + if (!deviceType.compare(String8("rotaryEncoder"))) { + device->classes |= INPUT_DEVICE_CLASS_ROTARY_ENCODER; + } + } + // See if this is a touch pad. // Is this a new modern multi-touch driver? if (test_bit(ABS_MT_POSITION_X, device->absBitmask) diff --git a/services/inputflinger/EventHub.h b/services/inputflinger/EventHub.h index 0f94c77..6869253 100644 --- a/services/inputflinger/EventHub.h +++ b/services/inputflinger/EventHub.h @@ -137,6 +137,9 @@ enum { /* The input device is an external stylus (has data we want to fuse with touch data). */ INPUT_DEVICE_CLASS_EXTERNAL_STYLUS = 0x00000800, + /* The input device has a rotary encoder */ + INPUT_DEVICE_CLASS_ROTARY_ENCODER = 0x00001000, + /* The input device is virtual (not a real device, not part of UI configuration). */ INPUT_DEVICE_CLASS_VIRTUAL = 0x40000000, diff --git a/services/inputflinger/InputReader.cpp b/services/inputflinger/InputReader.cpp index b2cbfe8..3ba38b5 100644 --- a/services/inputflinger/InputReader.cpp +++ b/services/inputflinger/InputReader.cpp @@ -450,6 +450,11 @@ InputDevice* InputReader::createDeviceLocked(int32_t deviceId, int32_t controlle device->addMapper(new SwitchInputMapper(device)); } + // Scroll wheel-like devices. + if (classes & INPUT_DEVICE_CLASS_ROTARY_ENCODER) { + device->addMapper(new RotaryEncoderInputMapper(device)); + } + // Vibrator-like devices. if (classes & INPUT_DEVICE_CLASS_VIBRATOR) { device->addMapper(new VibratorInputMapper(device)); @@ -2728,6 +2733,92 @@ void CursorInputMapper::fadePointer() { } } +// --- RotaryEncoderInputMapper --- + +RotaryEncoderInputMapper::RotaryEncoderInputMapper(InputDevice* device) : + InputMapper(device) { + mSource = AINPUT_SOURCE_ROTARY_ENCODER; +} + +RotaryEncoderInputMapper::~RotaryEncoderInputMapper() { +} + +uint32_t RotaryEncoderInputMapper::getSources() { + return mSource; +} + +void RotaryEncoderInputMapper::populateDeviceInfo(InputDeviceInfo* info) { + InputMapper::populateDeviceInfo(info); + + if (mRotaryEncoderScrollAccumulator.haveRelativeVWheel()) { + info->addMotionRange(AMOTION_EVENT_AXIS_SCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f); + } +} + +void RotaryEncoderInputMapper::dump(String8& dump) { + dump.append(INDENT2 "Rotary Encoder Input Mapper:\n"); + dump.appendFormat(INDENT3 "HaveWheel: %s\n", + toString(mRotaryEncoderScrollAccumulator.haveRelativeVWheel())); +} + +void RotaryEncoderInputMapper::configure(nsecs_t when, + const InputReaderConfiguration* config, uint32_t changes) { + InputMapper::configure(when, config, changes); + if (!changes) { + mRotaryEncoderScrollAccumulator.configure(getDevice()); + } +} + +void RotaryEncoderInputMapper::reset(nsecs_t when) { + mRotaryEncoderScrollAccumulator.reset(getDevice()); + + InputMapper::reset(when); +} + +void RotaryEncoderInputMapper::process(const RawEvent* rawEvent) { + mRotaryEncoderScrollAccumulator.process(rawEvent); + + if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) { + sync(rawEvent->when); + } +} + +void RotaryEncoderInputMapper::sync(nsecs_t when) { + PointerCoords pointerCoords; + pointerCoords.clear(); + + PointerProperties pointerProperties; + pointerProperties.clear(); + pointerProperties.id = 0; + pointerProperties.toolType = AMOTION_EVENT_TOOL_TYPE_UNKNOWN; + + float scroll = mRotaryEncoderScrollAccumulator.getRelativeVWheel(); + bool scrolled = scroll != 0; + + // This is not a pointer, so it's not associated with a display. + int32_t displayId = ADISPLAY_ID_NONE; + + // Moving the rotary encoder should wake the device (if specified). + uint32_t policyFlags = 0; + if (scrolled && getDevice()->isExternal()) { + policyFlags |= POLICY_FLAG_WAKE; + } + + // Send motion event. + if (scrolled) { + int32_t metaState = mContext->getGlobalMetaState(); + pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_SCROLL, scroll); + + NotifyMotionArgs scrollArgs(when, getDeviceId(), mSource, policyFlags, + AMOTION_EVENT_ACTION_SCROLL, 0, 0, metaState, 0, + AMOTION_EVENT_EDGE_FLAG_NONE, + displayId, 1, &pointerProperties, &pointerCoords, + 0, 0, 0); + getListener()->notifyMotion(&scrollArgs); + } + + mRotaryEncoderScrollAccumulator.finishSync(); +} // --- TouchInputMapper --- diff --git a/services/inputflinger/InputReader.h b/services/inputflinger/InputReader.h index 30c84b1..3e931fe 100644 --- a/services/inputflinger/InputReader.h +++ b/services/inputflinger/InputReader.h @@ -1231,6 +1231,26 @@ private: }; +class RotaryEncoderInputMapper : public InputMapper { +public: + RotaryEncoderInputMapper(InputDevice* device); + virtual ~RotaryEncoderInputMapper(); + + virtual uint32_t getSources(); + virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo); + virtual void dump(String8& dump); + virtual void configure(nsecs_t when, const InputReaderConfiguration* config, uint32_t changes); + virtual void reset(nsecs_t when); + virtual void process(const RawEvent* rawEvent); + +private: + CursorScrollAccumulator mRotaryEncoderScrollAccumulator; + + int32_t mSource; + + void sync(nsecs_t when); +}; + class TouchInputMapper : public InputMapper { public: TouchInputMapper(InputDevice* device); |