summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPrashant Malani <pmalani@google.com>2015-12-08 01:27:17 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2015-12-08 01:27:17 +0000
commit68fca5a1763203164a19a9aa983895242a671387 (patch)
tree97aa3c86b0b2b7fa31f3215a6295a5d411bc92a7
parent8c3e55f4149deda3ec7c7a67fda81216d5f9af25 (diff)
parentac72bbf4e46d6689070df09a25db2960a9036eb2 (diff)
downloadframeworks_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.h9
-rw-r--r--services/inputflinger/EventHub.cpp9
-rw-r--r--services/inputflinger/EventHub.h3
-rw-r--r--services/inputflinger/InputReader.cpp91
-rw-r--r--services/inputflinger/InputReader.h20
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);