Add controller numbers for gamepads / joysticks

Change-Id: I30ac9add6a2473a5ebd83a022c571545e61d1136
diff --git a/api/current.txt b/api/current.txt
index 0ec8d85..9cbb4fa 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -25597,6 +25597,7 @@
 
   public final class InputDevice implements android.os.Parcelable {
     method public int describeContents();
+    method public int getControllerNumber();
     method public java.lang.String getDescriptor();
     method public static android.view.InputDevice getDevice(int);
     method public static int[] getDeviceIds();
diff --git a/core/java/android/view/InputDevice.java b/core/java/android/view/InputDevice.java
index 34fa73d..debf4ee 100644
--- a/core/java/android/view/InputDevice.java
+++ b/core/java/android/view/InputDevice.java
@@ -44,6 +44,7 @@
 public final class InputDevice implements Parcelable {
     private final int mId;
     private final int mGeneration;
+    private final int mControllerNumber;
     private final String mName;
     private final String mDescriptor;
     private final boolean mIsExternal;
@@ -342,12 +343,12 @@
     };
 
     // Called by native code.
-    private InputDevice(int id, int generation, String name, String descriptor,
-            boolean isExternal, int sources,
-            int keyboardType, KeyCharacterMap keyCharacterMap,
-            boolean hasVibrator, boolean hasButtonUnderPad) {
+    private InputDevice(int id, int generation, int controllerNumber, String name,
+            String descriptor, boolean isExternal, int sources, int keyboardType,
+            KeyCharacterMap keyCharacterMap, boolean hasVibrator, boolean hasButtonUnderPad) {
         mId = id;
         mGeneration = generation;
+        mControllerNumber = controllerNumber;
         mName = name;
         mDescriptor = descriptor;
         mIsExternal = isExternal;
@@ -361,6 +362,7 @@
     private InputDevice(Parcel in) {
         mId = in.readInt();
         mGeneration = in.readInt();
+        mControllerNumber = in.readInt();
         mName = in.readString();
         mDescriptor = in.readString();
         mIsExternal = in.readInt() != 0;
@@ -414,6 +416,20 @@
     }
 
     /**
+     * The controller number for a given input device.
+     * <p>
+     * Each game controller or joystick is given a unique controller number when initially
+     * configured by the system. The number is not stable and may be changed by the system at any
+     * point.  All controller numbers will be non-negative. A game controller or joystick will be
+     * given a unique number indexed from one; everything else will be assigned a controller number
+     * of 0.
+     * </p>
+     */
+    public int getControllerNumber() {
+        return mControllerNumber;
+    }
+
+    /**
      * Gets a generation number for this input device.
      * The generation number is incremented whenever the device is reconfigured and its
      * properties may have changed.
@@ -739,6 +755,7 @@
     public void writeToParcel(Parcel out, int flags) {
         out.writeInt(mId);
         out.writeInt(mGeneration);
+        out.writeInt(mControllerNumber);
         out.writeString(mName);
         out.writeString(mDescriptor);
         out.writeInt(mIsExternal ? 1 : 0);
diff --git a/core/jni/android_view_InputDevice.cpp b/core/jni/android_view_InputDevice.cpp
index e5e3db0..5c8e010 100644
--- a/core/jni/android_view_InputDevice.cpp
+++ b/core/jni/android_view_InputDevice.cpp
@@ -55,8 +55,8 @@
 
     ScopedLocalRef<jobject> inputDeviceObj(env, env->NewObject(gInputDeviceClassInfo.clazz,
             gInputDeviceClassInfo.ctor, deviceInfo.getId(), deviceInfo.getGeneration(),
-            nameObj.get(), descriptorObj.get(), deviceInfo.isExternal(),
-            deviceInfo.getSources(), deviceInfo.getKeyboardType(),
+             deviceInfo.getControllerNumber(), nameObj.get(), descriptorObj.get(),
+            deviceInfo.isExternal(), deviceInfo.getSources(), deviceInfo.getKeyboardType(),
             kcmObj.get(), deviceInfo.hasVibrator(), deviceInfo.hasButtonUnderPad()));
 
     const Vector<InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
@@ -86,8 +86,9 @@
     FIND_CLASS(gInputDeviceClassInfo.clazz, "android/view/InputDevice");
     gInputDeviceClassInfo.clazz = jclass(env->NewGlobalRef(gInputDeviceClassInfo.clazz));
 
-    GET_METHOD_ID(gInputDeviceClassInfo.ctor, gInputDeviceClassInfo.clazz, "<init>",
-            "(IILjava/lang/String;Ljava/lang/String;ZIILandroid/view/KeyCharacterMap;ZZ)V");
+    GET_METHOD_ID(gInputDeviceClassInfo.ctor, gInputDeviceClassInfo.clazz,
+            "<init>",
+            "(IIILjava/lang/String;Ljava/lang/String;ZIILandroid/view/KeyCharacterMap;ZZ)V");
 
     GET_METHOD_ID(gInputDeviceClassInfo.addMotionRange, gInputDeviceClassInfo.clazz,
             "addMotionRange", "(IIFFFFF)V");
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