inputflinger: Initial support for rotary encoders.
This change introduces support for rotary encoder input devices. We also define a new input source (namely, AINPUT_SOURCE_ROTARY_ENCODER) and a new axis of input (namely, AXIS_SCROLL), since the rotary encoder motion doesn't necessarily tie to a horizontal or vertical scroll motion. A ROTARY_ENCODER input device class is also introduced, corresponding to the new input source. A new input source can be defined as producing rotary encoder motion events, if its corresponding .idc file contains the following declaration: device.type = rotaryEncoder Bug: 18707397 Change-Id: I8ccd540908311d1ff44fdfeba81b691895413641 Signed-off-by: Prashant Malani <pmalani@google.com>
This commit is contained in:
parent
4baa69ddd2
commit
ac72bbf4e4
@ -643,6 +643,13 @@ enum {
|
|||||||
* against the surface.
|
* against the surface.
|
||||||
*/
|
*/
|
||||||
AMOTION_EVENT_AXIS_TILT = 25,
|
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.
|
* Axis constant: Generic 1 axis of a motion event.
|
||||||
* The interpretation of a generic axis is device-specific.
|
* The interpretation of a generic axis is device-specific.
|
||||||
@ -817,6 +824,8 @@ enum {
|
|||||||
AINPUT_SOURCE_TOUCH_NAVIGATION = 0x00200000 | AINPUT_SOURCE_CLASS_NONE,
|
AINPUT_SOURCE_TOUCH_NAVIGATION = 0x00200000 | AINPUT_SOURCE_CLASS_NONE,
|
||||||
/** joystick */
|
/** joystick */
|
||||||
AINPUT_SOURCE_JOYSTICK = 0x01000000 | AINPUT_SOURCE_CLASS_JOYSTICK,
|
AINPUT_SOURCE_JOYSTICK = 0x01000000 | AINPUT_SOURCE_CLASS_JOYSTICK,
|
||||||
|
/** rotary encoder */
|
||||||
|
AINPUT_SOURCE_ROTARY_ENCODER = 0x00400000 | AINPUT_SOURCE_CLASS_NONE,
|
||||||
|
|
||||||
/** any */
|
/** any */
|
||||||
AINPUT_SOURCE_ANY = 0xffffff00,
|
AINPUT_SOURCE_ANY = 0xffffff00,
|
||||||
|
@ -1177,6 +1177,15 @@ status_t EventHub::openDeviceLocked(const char *devicePath) {
|
|||||||
device->classes |= INPUT_DEVICE_CLASS_CURSOR;
|
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.
|
// See if this is a touch pad.
|
||||||
// Is this a new modern multi-touch driver?
|
// Is this a new modern multi-touch driver?
|
||||||
if (test_bit(ABS_MT_POSITION_X, device->absBitmask)
|
if (test_bit(ABS_MT_POSITION_X, device->absBitmask)
|
||||||
|
@ -137,6 +137,9 @@ enum {
|
|||||||
/* The input device is an external stylus (has data we want to fuse with touch data). */
|
/* The input device is an external stylus (has data we want to fuse with touch data). */
|
||||||
INPUT_DEVICE_CLASS_EXTERNAL_STYLUS = 0x00000800,
|
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). */
|
/* The input device is virtual (not a real device, not part of UI configuration). */
|
||||||
INPUT_DEVICE_CLASS_VIRTUAL = 0x40000000,
|
INPUT_DEVICE_CLASS_VIRTUAL = 0x40000000,
|
||||||
|
|
||||||
|
@ -450,6 +450,11 @@ InputDevice* InputReader::createDeviceLocked(int32_t deviceId, int32_t controlle
|
|||||||
device->addMapper(new SwitchInputMapper(device));
|
device->addMapper(new SwitchInputMapper(device));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Scroll wheel-like devices.
|
||||||
|
if (classes & INPUT_DEVICE_CLASS_ROTARY_ENCODER) {
|
||||||
|
device->addMapper(new RotaryEncoderInputMapper(device));
|
||||||
|
}
|
||||||
|
|
||||||
// Vibrator-like devices.
|
// Vibrator-like devices.
|
||||||
if (classes & INPUT_DEVICE_CLASS_VIBRATOR) {
|
if (classes & INPUT_DEVICE_CLASS_VIBRATOR) {
|
||||||
device->addMapper(new VibratorInputMapper(device));
|
device->addMapper(new VibratorInputMapper(device));
|
||||||
@ -2718,6 +2723,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 ---
|
// --- TouchInputMapper ---
|
||||||
|
|
||||||
|
@ -1232,6 +1232,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 {
|
class TouchInputMapper : public InputMapper {
|
||||||
public:
|
public:
|
||||||
TouchInputMapper(InputDevice* device);
|
TouchInputMapper(InputDevice* device);
|
||||||
|
Loading…
Reference in New Issue
Block a user