diff options
author | Jeff Brown <jeffbrown@google.com> | 2011-08-31 12:56:34 -0700 |
---|---|---|
committer | Jeff Brown <jeffbrown@google.com> | 2011-08-31 12:56:34 -0700 |
commit | 9ee285afe740ff13d176c9d8430979dfd9575a23 (patch) | |
tree | c63a5a7d49029e1b677ccd7dbe3f7527e5420221 /services/input | |
parent | cc4f7db698f88b633a286d8ab1105b28a474cd09 (diff) | |
download | frameworks_base-9ee285afe740ff13d176c9d8430979dfd9575a23.zip frameworks_base-9ee285afe740ff13d176c9d8430979dfd9575a23.tar.gz frameworks_base-9ee285afe740ff13d176c9d8430979dfd9575a23.tar.bz2 |
Support composite touch / joystick devices better.
This change enables the joystick input mapper to handle any axes
that are not claimed by the touch input mapper, which makes
auxiliary controls such as wheels / knobs accessible.
Change-Id: I01ee7f342ac91acfcb4ccb6676fd52b3d5bf31a0
Diffstat (limited to 'services/input')
-rw-r--r-- | services/input/EventHub.cpp | 48 | ||||
-rw-r--r-- | services/input/EventHub.h | 6 | ||||
-rw-r--r-- | services/input/InputReader.cpp | 14 | ||||
-rw-r--r-- | services/input/InputReader.h | 6 | ||||
-rw-r--r-- | services/input/tests/InputReader_test.cpp | 16 |
5 files changed, 74 insertions, 16 deletions
diff --git a/services/input/EventHub.cpp b/services/input/EventHub.cpp index 1d7cc19..157a997 100644 --- a/services/input/EventHub.cpp +++ b/services/input/EventHub.cpp @@ -78,6 +78,40 @@ static inline const char* toString(bool value) { return value ? "true" : "false"; } +// --- Global Functions --- + +uint32_t getAbsAxisUsage(int32_t axis, uint32_t deviceClasses) { + // Touch devices get dibs on touch-related axes. + if (deviceClasses & INPUT_DEVICE_CLASS_TOUCH) { + switch (axis) { + case ABS_X: + case ABS_Y: + case ABS_PRESSURE: + case ABS_TOOL_WIDTH: + case ABS_DISTANCE: + case ABS_TILT_X: + case ABS_TILT_Y: + case ABS_MT_SLOT: + case ABS_MT_TOUCH_MAJOR: + case ABS_MT_TOUCH_MINOR: + case ABS_MT_WIDTH_MAJOR: + case ABS_MT_WIDTH_MINOR: + case ABS_MT_ORIENTATION: + case ABS_MT_POSITION_X: + case ABS_MT_POSITION_Y: + case ABS_MT_TOOL_TYPE: + case ABS_MT_BLOB_ID: + case ABS_MT_TRACKING_ID: + case ABS_MT_PRESSURE: + case ABS_MT_DISTANCE: + return INPUT_DEVICE_CLASS_TOUCH; + } + } + + // Joystick devices get the rest. + return deviceClasses & INPUT_DEVICE_CLASS_JOYSTICK; +} + // --- EventHub::Device --- EventHub::Device::Device(int fd, int32_t id, const String8& path, @@ -936,13 +970,17 @@ status_t EventHub::openDeviceLocked(const char *devicePath) { } // See if this device is a joystick. - // Ignore touchscreens because they use the same absolute axes for other purposes. // Assumes that joysticks always have gamepad buttons in order to distinguish them // from other devices such as accelerometers that also have absolute axes. - if (haveGamepadButtons - && !(device->classes & INPUT_DEVICE_CLASS_TOUCH) - && containsNonZeroByte(device->absBitmask, 0, sizeof_bit_array(ABS_MAX + 1))) { - device->classes |= INPUT_DEVICE_CLASS_JOYSTICK; + if (haveGamepadButtons) { + uint32_t assumedClasses = device->classes | INPUT_DEVICE_CLASS_JOYSTICK; + for (int i = 0; i <= ABS_MAX; i++) { + if (test_bit(i, device->absBitmask) + && (getAbsAxisUsage(i, assumedClasses) & INPUT_DEVICE_CLASS_JOYSTICK)) { + device->classes = assumedClasses; + break; + } + } } // Check whether this device has switches. diff --git a/services/input/EventHub.h b/services/input/EventHub.h index fae5d4f..d37549a 100644 --- a/services/input/EventHub.h +++ b/services/input/EventHub.h @@ -112,6 +112,12 @@ enum { }; /* + * Gets the class that owns an axis, in cases where multiple classes might claim + * the same axis for different purposes. + */ +extern uint32_t getAbsAxisUsage(int32_t axis, uint32_t deviceClasses); + +/* * Grand Central Station for events. * * The event hub aggregates input events received across all known input diff --git a/services/input/InputReader.cpp b/services/input/InputReader.cpp index e39712e..88c19a4 100644 --- a/services/input/InputReader.cpp +++ b/services/input/InputReader.cpp @@ -390,7 +390,7 @@ void InputReader::removeDeviceLocked(nsecs_t when, int32_t deviceId) { InputDevice* InputReader::createDeviceLocked(int32_t deviceId, const String8& name, uint32_t classes) { - InputDevice* device = new InputDevice(&mContext, deviceId, name); + InputDevice* device = new InputDevice(&mContext, deviceId, name, classes); // External devices. if (classes & INPUT_DEVICE_CLASS_EXTERNAL) { @@ -842,9 +842,10 @@ bool InputReaderThread::threadLoop() { // --- InputDevice --- -InputDevice::InputDevice(InputReaderContext* context, int32_t id, const String8& name) : - mContext(context), mId(id), mName(name), mSources(0), - mIsExternal(false), mDropUntilNextSync(false) { +InputDevice::InputDevice(InputReaderContext* context, int32_t id, const String8& name, + uint32_t classes) : + mContext(context), mId(id), mName(name), mClasses(classes), + mSources(0), mIsExternal(false), mDropUntilNextSync(false) { } InputDevice::~InputDevice() { @@ -5759,6 +5760,11 @@ void JoystickInputMapper::configure(nsecs_t when, if (!changes) { // first time only // Collect all axes. for (int32_t abs = 0; abs <= ABS_MAX; abs++) { + if (!(getAbsAxisUsage(abs, getDevice()->getClasses()) + & INPUT_DEVICE_CLASS_JOYSTICK)) { + continue; // axis must be claimed by a different device + } + RawAbsoluteAxisInfo rawAxisInfo; getAbsoluteAxisInfo(abs, &rawAxisInfo); if (rawAxisInfo.valid) { diff --git a/services/input/InputReader.h b/services/input/InputReader.h index cd3ea37..a122c97 100644 --- a/services/input/InputReader.h +++ b/services/input/InputReader.h @@ -430,12 +430,13 @@ private: /* Represents the state of a single input device. */ class InputDevice { public: - InputDevice(InputReaderContext* context, int32_t id, const String8& name); + InputDevice(InputReaderContext* context, int32_t id, const String8& name, uint32_t classes); ~InputDevice(); inline InputReaderContext* getContext() { return mContext; } inline int32_t getId() { return mId; } inline const String8& getName() { return mName; } + inline uint32_t getClasses() { return mClasses; } inline uint32_t getSources() { return mSources; } inline bool isExternal() { return mIsExternal; } @@ -483,10 +484,11 @@ public: private: InputReaderContext* mContext; int32_t mId; + String8 mName; + uint32_t mClasses; Vector<InputMapper*> mMappers; - String8 mName; uint32_t mSources; bool mIsExternal; bool mDropUntilNextSync; diff --git a/services/input/tests/InputReader_test.cpp b/services/input/tests/InputReader_test.cpp index 32f948b..a086208 100644 --- a/services/input/tests/InputReader_test.cpp +++ b/services/input/tests/InputReader_test.cpp @@ -852,8 +852,8 @@ public: mNextDevice = device; } - InputDevice* newDevice(int32_t deviceId, const String8& name) { - return new InputDevice(&mContext, deviceId, name); + InputDevice* newDevice(int32_t deviceId, const String8& name, uint32_t classes) { + return new InputDevice(&mContext, deviceId, name, classes); } protected: @@ -912,7 +912,7 @@ protected: FakeInputMapper* addDeviceWithFakeInputMapper(int32_t deviceId, const String8& name, uint32_t classes, uint32_t sources, const PropertyMap* configuration) { - InputDevice* device = mReader->newDevice(deviceId, name); + InputDevice* device = mReader->newDevice(deviceId, name, classes); FakeInputMapper* mapper = new FakeInputMapper(device, sources); device->addMapper(mapper); mReader->setNextDevice(device); @@ -1211,6 +1211,7 @@ class InputDeviceTest : public testing::Test { protected: static const char* DEVICE_NAME; static const int32_t DEVICE_ID; + static const uint32_t DEVICE_CLASSES; sp<FakeEventHub> mFakeEventHub; sp<FakeInputReaderPolicy> mFakePolicy; @@ -1226,7 +1227,7 @@ protected: mFakeContext = new FakeInputReaderContext(mFakeEventHub, mFakePolicy, mFakeListener); mFakeEventHub->addDevice(DEVICE_ID, String8(DEVICE_NAME), 0); - mDevice = new InputDevice(mFakeContext, DEVICE_ID, String8(DEVICE_NAME)); + mDevice = new InputDevice(mFakeContext, DEVICE_ID, String8(DEVICE_NAME), DEVICE_CLASSES); } virtual void TearDown() { @@ -1241,10 +1242,13 @@ protected: const char* InputDeviceTest::DEVICE_NAME = "device"; const int32_t InputDeviceTest::DEVICE_ID = 1; +const uint32_t InputDeviceTest::DEVICE_CLASSES = INPUT_DEVICE_CLASS_KEYBOARD + | INPUT_DEVICE_CLASS_TOUCH | INPUT_DEVICE_CLASS_JOYSTICK; TEST_F(InputDeviceTest, ImmutableProperties) { ASSERT_EQ(DEVICE_ID, mDevice->getId()); ASSERT_STREQ(DEVICE_NAME, mDevice->getName()); + ASSERT_EQ(DEVICE_CLASSES, mDevice->getClasses()); } TEST_F(InputDeviceTest, WhenNoMappersAreRegistered_DeviceIsIgnored) { @@ -1390,6 +1394,7 @@ class InputMapperTest : public testing::Test { protected: static const char* DEVICE_NAME; static const int32_t DEVICE_ID; + static const uint32_t DEVICE_CLASSES; sp<FakeEventHub> mFakeEventHub; sp<FakeInputReaderPolicy> mFakePolicy; @@ -1402,7 +1407,7 @@ protected: mFakePolicy = new FakeInputReaderPolicy(); mFakeListener = new FakeInputListener(); mFakeContext = new FakeInputReaderContext(mFakeEventHub, mFakePolicy, mFakeListener); - mDevice = new InputDevice(mFakeContext, DEVICE_ID, String8(DEVICE_NAME)); + mDevice = new InputDevice(mFakeContext, DEVICE_ID, String8(DEVICE_NAME), DEVICE_CLASSES); mFakeEventHub->addDevice(DEVICE_ID, String8(DEVICE_NAME), 0); } @@ -1483,6 +1488,7 @@ protected: const char* InputMapperTest::DEVICE_NAME = "device"; const int32_t InputMapperTest::DEVICE_ID = 1; +const uint32_t InputMapperTest::DEVICE_CLASSES = 0; // not needed for current tests // --- SwitchInputMapperTest --- |