Add controller numbers for gamepads / joysticks
Change-Id: I30ac9add6a2473a5ebd83a022c571545e61d1136
diff --git a/services/input/EventHub.cpp b/services/input/EventHub.cpp
index fab091f..4d70d5f 100644
--- a/services/input/EventHub.cpp
+++ b/services/input/EventHub.cpp
@@ -162,7 +162,7 @@
next(NULL),
fd(fd), id(id), path(path), identifier(identifier),
classes(0), configuration(NULL), virtualKeyMap(NULL),
- ffEffectPlaying(false), ffEffectId(-1),
+ ffEffectPlaying(false), ffEffectId(-1), controllerNumber(0),
timestampOverrideSec(0), timestampOverrideUsec(0) {
memset(keyBitmask, 0, sizeof(keyBitmask));
memset(absBitmask, 0, sizeof(absBitmask));
@@ -195,7 +195,7 @@
const int EventHub::EPOLL_MAX_EVENTS;
EventHub::EventHub(void) :
- mBuiltInKeyboardId(NO_BUILT_IN_KEYBOARD), mNextDeviceId(1),
+ mBuiltInKeyboardId(NO_BUILT_IN_KEYBOARD), mNextDeviceId(1), mControllerNumbers(),
mOpeningDevices(0), mClosingDevices(0),
mNeedToSendFinishedDeviceScan(false),
mNeedToReopenDevices(false), mNeedToScanDevices(true),
@@ -269,6 +269,13 @@
return device->classes;
}
+int32_t EventHub::getDeviceControllerNumber(int32_t deviceId) const {
+ AutoMutex _l(mLock);
+ Device* device = getDeviceLocked(deviceId);
+ if (device == NULL) return 0;
+ return device->controllerNumber;
+}
+
void EventHub::getConfiguration(int32_t deviceId, PropertyMap* outConfiguration) const {
AutoMutex _l(mLock);
Device* device = getDeviceLocked(deviceId);
@@ -1230,6 +1237,10 @@
device->classes |= INPUT_DEVICE_CLASS_EXTERNAL;
}
+ if (device->classes & (INPUT_DEVICE_CLASS_JOYSTICK | INPUT_DEVICE_CLASS_GAMEPAD)) {
+ device->controllerNumber = getNextControllerNumberLocked(device);
+ }
+
// Register with epoll.
struct epoll_event eventItem;
memset(&eventItem, 0, sizeof(eventItem));
@@ -1341,6 +1352,27 @@
return device->identifier.bus == BUS_USB || device->identifier.bus == BUS_BLUETOOTH;
}
+int32_t EventHub::getNextControllerNumberLocked(Device* device) {
+ if (mControllerNumbers.isFull()) {
+ ALOGI("Maximum number of controllers reached, assigning controller number 0 to device %s",
+ device->identifier.name.string());
+ return 0;
+ }
+ // Since the controller number 0 is reserved for non-controllers, translate all numbers up by
+ // one
+ return static_cast<int32_t>(mControllerNumbers.markFirstUnmarkedBit() + 1);
+}
+
+void EventHub::releaseControllerNumberLocked(Device* device) {
+ int32_t num = device->controllerNumber;
+ device->controllerNumber= 0;
+ if (num == 0) {
+ return;
+ }
+ mControllerNumbers.clearBit(static_cast<uint32_t>(num - 1));
+}
+
+
bool EventHub::hasKeycodeLocked(Device* device, int keycode) const {
if (!device->keyMap.haveKeyLayout() || !device->keyBitmask) {
return false;
@@ -1392,6 +1424,8 @@
}
}
+ releaseControllerNumberLocked(device);
+
mDevices.removeItem(device->id);
device->close();
@@ -1521,6 +1555,7 @@
dump.appendFormat(INDENT3 "Path: %s\n", device->path.string());
dump.appendFormat(INDENT3 "Descriptor: %s\n", device->identifier.descriptor.string());
dump.appendFormat(INDENT3 "Location: %s\n", device->identifier.location.string());
+ dump.appendFormat(INDENT3 "ControllerNumber: %d\n", device->controllerNumber);
dump.appendFormat(INDENT3 "UniqueId: %s\n", device->identifier.uniqueId.string());
dump.appendFormat(INDENT3 "Identifier: bus=0x%04x, vendor=0x%04x, "
"product=0x%04x, version=0x%04x\n",
diff --git a/services/input/EventHub.h b/services/input/EventHub.h
index daa1bea..ae28f01 100644
--- a/services/input/EventHub.h
+++ b/services/input/EventHub.h
@@ -33,6 +33,7 @@
#include <utils/PropertyMap.h>
#include <utils/Vector.h>
#include <utils/KeyedVector.h>
+#include <utils/BitSet.h>
#include <linux/input.h>
#include <sys/epoll.h>
@@ -179,6 +180,8 @@
virtual InputDeviceIdentifier getDeviceIdentifier(int32_t deviceId) const = 0;
+ virtual int32_t getDeviceControllerNumber(int32_t deviceId) const = 0;
+
virtual void getConfiguration(int32_t deviceId, PropertyMap* outConfiguration) const = 0;
virtual status_t getAbsoluteAxisInfo(int32_t deviceId, int axis,
@@ -263,6 +266,8 @@
virtual InputDeviceIdentifier getDeviceIdentifier(int32_t deviceId) const;
+ virtual int32_t getDeviceControllerNumber(int32_t deviceId) const;
+
virtual void getConfiguration(int32_t deviceId, PropertyMap* outConfiguration) const;
virtual status_t getAbsoluteAxisInfo(int32_t deviceId, int axis,
@@ -343,6 +348,8 @@
bool ffEffectPlaying;
int16_t ffEffectId; // initially -1
+ int32_t controllerNumber;
+
int32_t timestampOverrideSec;
int32_t timestampOverrideUsec;
@@ -384,6 +391,9 @@
bool isExternalDeviceLocked(Device* device);
+ int32_t getNextControllerNumberLocked(Device* device);
+ void releaseControllerNumberLocked(Device* device);
+
// Protect all internal state.
mutable Mutex mLock;
@@ -398,6 +408,8 @@
int32_t mNextDeviceId;
+ BitSet32 mControllerNumbers;
+
KeyedVector<int32_t, Device*> mDevices;
Device *mOpeningDevices;
diff --git a/services/input/InputReader.cpp b/services/input/InputReader.cpp
index 07731fc..feed31c 100644
--- a/services/input/InputReader.cpp
+++ b/services/input/InputReader.cpp
@@ -354,8 +354,9 @@
InputDeviceIdentifier identifier = mEventHub->getDeviceIdentifier(deviceId);
uint32_t classes = mEventHub->getDeviceClasses(deviceId);
+ int32_t controllerNumber = mEventHub->getDeviceControllerNumber(deviceId);
- InputDevice* device = createDeviceLocked(deviceId, identifier, classes);
+ InputDevice* device = createDeviceLocked(deviceId, controllerNumber, identifier, classes);
device->configure(when, &mConfig, 0);
device->reset(when);
@@ -395,10 +396,10 @@
delete device;
}
-InputDevice* InputReader::createDeviceLocked(int32_t deviceId,
+InputDevice* InputReader::createDeviceLocked(int32_t deviceId, int32_t controllerNumber,
const InputDeviceIdentifier& identifier, uint32_t classes) {
InputDevice* device = new InputDevice(&mContext, deviceId, bumpGenerationLocked(),
- identifier, classes);
+ controllerNumber, identifier, classes);
// External devices.
if (classes & INPUT_DEVICE_CLASS_EXTERNAL) {
@@ -843,8 +844,8 @@
// --- InputDevice ---
InputDevice::InputDevice(InputReaderContext* context, int32_t id, int32_t generation,
- const InputDeviceIdentifier& identifier, uint32_t classes) :
- mContext(context), mId(id), mGeneration(generation),
+ int32_t controllerNumber, const InputDeviceIdentifier& identifier, uint32_t classes) :
+ mContext(context), mId(id), mGeneration(generation), mControllerNumber(controllerNumber),
mIdentifier(identifier), mClasses(classes),
mSources(0), mIsExternal(false), mDropUntilNextSync(false) {
}
@@ -995,7 +996,8 @@
}
void InputDevice::getDeviceInfo(InputDeviceInfo* outDeviceInfo) {
- outDeviceInfo->initialize(mId, mGeneration, mIdentifier, mAlias, mIsExternal);
+ outDeviceInfo->initialize(mId, mGeneration, mControllerNumber, mIdentifier, mAlias,
+ mIsExternal);
size_t numMappers = mMappers.size();
for (size_t i = 0; i < numMappers; i++) {
diff --git a/services/input/InputReader.h b/services/input/InputReader.h
index 3ed426f..98daaf5 100644
--- a/services/input/InputReader.h
+++ b/services/input/InputReader.h
@@ -409,7 +409,7 @@
protected:
// These members are protected so they can be instrumented by test cases.
- virtual InputDevice* createDeviceLocked(int32_t deviceId,
+ virtual InputDevice* createDeviceLocked(int32_t deviceId, int32_t controllerNumber,
const InputDeviceIdentifier& identifier, uint32_t classes);
class ContextImpl : public InputReaderContext {
@@ -507,16 +507,17 @@
/* Represents the state of a single input device. */
class InputDevice {
public:
- InputDevice(InputReaderContext* context, int32_t id, int32_t generation,
- const InputDeviceIdentifier& identifier, uint32_t classes);
+ InputDevice(InputReaderContext* context, int32_t id, int32_t generation, int32_t
+ controllerNumber, const InputDeviceIdentifier& identifier, uint32_t classes);
~InputDevice();
inline InputReaderContext* getContext() { return mContext; }
- inline int32_t getId() { return mId; }
- inline int32_t getGeneration() { return mGeneration; }
- inline const String8& getName() { return mIdentifier.name; }
- inline uint32_t getClasses() { return mClasses; }
- inline uint32_t getSources() { return mSources; }
+ inline int32_t getId() const { return mId; }
+ inline int32_t getControllerNumber() const { return mControllerNumber; }
+ inline int32_t getGeneration() const { return mGeneration; }
+ inline const String8& getName() const { return mIdentifier.name; }
+ inline uint32_t getClasses() const { return mClasses; }
+ inline uint32_t getSources() const { return mSources; }
inline bool isExternal() { return mIsExternal; }
inline void setExternal(bool external) { mIsExternal = external; }
@@ -573,6 +574,7 @@
private:
InputReaderContext* mContext;
int32_t mId;
+ int32_t mControllerNumber;
int32_t mGeneration;
InputDeviceIdentifier mIdentifier;
String8 mAlias;
diff --git a/services/input/tests/InputReader_test.cpp b/services/input/tests/InputReader_test.cpp
index 14065d2..f068732 100644
--- a/services/input/tests/InputReader_test.cpp
+++ b/services/input/tests/InputReader_test.cpp
@@ -472,6 +472,10 @@
return device ? device->identifier : InputDeviceIdentifier();
}
+ virtual int32_t getDeviceControllerNumber(int32_t deviceId) const {
+ return 0;
+ }
+
virtual void getConfiguration(int32_t deviceId, PropertyMap* outConfiguration) const {
Device* device = getDevice(deviceId);
if (device) {
@@ -928,22 +932,24 @@
mNextDevice = device;
}
- InputDevice* newDevice(int32_t deviceId, const String8& name, uint32_t classes) {
+ InputDevice* newDevice(int32_t deviceId, int32_t controllerNumber, const String8& name,
+ uint32_t classes) {
InputDeviceIdentifier identifier;
identifier.name = name;
int32_t generation = deviceId + 1;
- return new InputDevice(&mContext, deviceId, generation, identifier, classes);
+ return new InputDevice(&mContext, deviceId, generation, controllerNumber, identifier,
+ classes);
}
protected:
- virtual InputDevice* createDeviceLocked(int32_t deviceId,
+ virtual InputDevice* createDeviceLocked(int32_t deviceId, int32_t controllerNumber,
const InputDeviceIdentifier& identifier, uint32_t classes) {
if (mNextDevice) {
InputDevice* device = mNextDevice;
mNextDevice = NULL;
return device;
}
- return InputReader::createDeviceLocked(deviceId, identifier, classes);
+ return InputReader::createDeviceLocked(deviceId, controllerNumber, identifier, classes);
}
friend class InputReaderTest;
@@ -988,10 +994,10 @@
mFakeEventHub->assertQueueIsEmpty();
}
- FakeInputMapper* addDeviceWithFakeInputMapper(int32_t deviceId,
+ FakeInputMapper* addDeviceWithFakeInputMapper(int32_t deviceId, int32_t controllerNumber,
const String8& name, uint32_t classes, uint32_t sources,
const PropertyMap* configuration) {
- InputDevice* device = mReader->newDevice(deviceId, name, classes);
+ InputDevice* device = mReader->newDevice(deviceId, controllerNumber, name, classes);
FakeInputMapper* mapper = new FakeInputMapper(device, sources);
device->addMapper(mapper);
mReader->setNextDevice(device);
@@ -1028,7 +1034,7 @@
TEST_F(InputReaderTest, GetKeyCodeState_ForwardsRequestsToMappers) {
FakeInputMapper* mapper = NULL;
- ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, String8("fake"),
+ ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, 0, String8("fake"),
INPUT_DEVICE_CLASS_KEYBOARD, AINPUT_SOURCE_KEYBOARD, NULL));
mapper->setKeyCodeState(AKEYCODE_A, AKEY_STATE_DOWN);
@@ -1055,7 +1061,7 @@
TEST_F(InputReaderTest, GetScanCodeState_ForwardsRequestsToMappers) {
FakeInputMapper* mapper = NULL;
- ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, String8("fake"),
+ ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, 0, String8("fake"),
INPUT_DEVICE_CLASS_KEYBOARD, AINPUT_SOURCE_KEYBOARD, NULL));
mapper->setScanCodeState(KEY_A, AKEY_STATE_DOWN);
@@ -1082,7 +1088,7 @@
TEST_F(InputReaderTest, GetSwitchState_ForwardsRequestsToMappers) {
FakeInputMapper* mapper = NULL;
- ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, String8("fake"),
+ ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, 0, String8("fake"),
INPUT_DEVICE_CLASS_KEYBOARD, AINPUT_SOURCE_KEYBOARD, NULL));
mapper->setSwitchState(SW_LID, AKEY_STATE_DOWN);
@@ -1109,7 +1115,7 @@
TEST_F(InputReaderTest, MarkSupportedKeyCodes_ForwardsRequestsToMappers) {
FakeInputMapper* mapper = NULL;
- ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, String8("fake"),
+ ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, 0, String8("fake"),
INPUT_DEVICE_CLASS_KEYBOARD, AINPUT_SOURCE_KEYBOARD, NULL));
mapper->addSupportedKeyCode(AKEYCODE_A);
mapper->addSupportedKeyCode(AKEYCODE_B);
@@ -1153,7 +1159,7 @@
TEST_F(InputReaderTest, LoopOnce_ForwardsRawEventsToMappers) {
FakeInputMapper* mapper = NULL;
- ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, String8("fake"),
+ ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, 0, String8("fake"),
INPUT_DEVICE_CLASS_KEYBOARD, AINPUT_SOURCE_KEYBOARD, NULL));
mFakeEventHub->enqueueEvent(0, 1, EV_KEY, KEY_A, 1);
@@ -1177,6 +1183,7 @@
static const char* DEVICE_NAME;
static const int32_t DEVICE_ID;
static const int32_t DEVICE_GENERATION;
+ static const int32_t DEVICE_CONTROLLER_NUMBER;
static const uint32_t DEVICE_CLASSES;
sp<FakeEventHub> mFakeEventHub;
@@ -1196,7 +1203,7 @@
InputDeviceIdentifier identifier;
identifier.name = DEVICE_NAME;
mDevice = new InputDevice(mFakeContext, DEVICE_ID, DEVICE_GENERATION,
- identifier, DEVICE_CLASSES);
+ DEVICE_CONTROLLER_NUMBER, identifier, DEVICE_CLASSES);
}
virtual void TearDown() {
@@ -1212,6 +1219,7 @@
const char* InputDeviceTest::DEVICE_NAME = "device";
const int32_t InputDeviceTest::DEVICE_ID = 1;
const int32_t InputDeviceTest::DEVICE_GENERATION = 2;
+const int32_t InputDeviceTest::DEVICE_CONTROLLER_NUMBER = 0;
const uint32_t InputDeviceTest::DEVICE_CLASSES = INPUT_DEVICE_CLASS_KEYBOARD
| INPUT_DEVICE_CLASS_TOUCH | INPUT_DEVICE_CLASS_JOYSTICK;
@@ -1365,6 +1373,7 @@
static const char* DEVICE_NAME;
static const int32_t DEVICE_ID;
static const int32_t DEVICE_GENERATION;
+ static const int32_t DEVICE_CONTROLLER_NUMBER;
static const uint32_t DEVICE_CLASSES;
sp<FakeEventHub> mFakeEventHub;
@@ -1381,7 +1390,7 @@
InputDeviceIdentifier identifier;
identifier.name = DEVICE_NAME;
mDevice = new InputDevice(mFakeContext, DEVICE_ID, DEVICE_GENERATION,
- identifier, DEVICE_CLASSES);
+ DEVICE_CONTROLLER_NUMBER, identifier, DEVICE_CLASSES);
mFakeEventHub->addDevice(DEVICE_ID, String8(DEVICE_NAME), 0);
}
@@ -1461,6 +1470,7 @@
const char* InputMapperTest::DEVICE_NAME = "device";
const int32_t InputMapperTest::DEVICE_ID = 1;
const int32_t InputMapperTest::DEVICE_GENERATION = 2;
+const int32_t InputMapperTest::DEVICE_CONTROLLER_NUMBER = 0;
const uint32_t InputMapperTest::DEVICE_CLASSES = 0; // not needed for current tests