Support multiple EventHub devices per InputDevice

Some physical devices contain more functions than can be addressed by
a single Linux evdev device. Examples of such devices are the Sony
DualShock 4 and Wacom Tablets, which appear as multiple evdev devices
sharing the same value for the EVIOCGUNIQ ioctl. As more instances of
such devices hit the market, apps need a way of figuring out which
InputDevices are part of the same physical device.

Per conversation with the android input team, a solution proposed to
this problem is to merge multiple EventHub devices (which have a 1:1
relation with evdev) into a single android InputDevice.

Changes:

Decouple the EventHub device id ("eventHubId") from the InputDevice
device id ("deviceId"). This requires InputDeviceContext to track the
the EventHub devices it represents. Most logic changes are inside
InputDeviceContext, so there are minimal changes to InputMappers.

Added enum value END_RESERVED_ID to represent the first available
id that can be assigned to a normal InputDevice. The android
framework assumes specific values for the virtual keyboard and
built-in hardware keyboard, so for these two cases, the "deviceId"
must match the "eventHubId."

Added "EVENTHUB_ID" constants to tests and changed where applicable.

Cherry-picked from pa/1475694.

Bug: 38511270
Test: atest inputflinger_tests libinput_tests
Change-Id: I89df085fadc1c09bc999599ac5db35c9277c4a2a
diff --git a/services/inputflinger/reader/include/InputReader.h b/services/inputflinger/reader/include/InputReader.h
index 4f5d2ea..31d82f1 100644
--- a/services/inputflinger/reader/include/InputReader.h
+++ b/services/inputflinger/reader/include/InputReader.h
@@ -84,10 +84,8 @@
 
 protected:
     // These members are protected so they can be instrumented by test cases.
-    virtual std::shared_ptr<InputDevice> createDeviceLocked(int32_t deviceId,
-                                                            int32_t controllerNumber,
-                                                            const InputDeviceIdentifier& identifier,
-                                                            uint32_t classes);
+    virtual std::shared_ptr<InputDevice> createDeviceLocked(
+            int32_t deviceId, const InputDeviceIdentifier& identifier);
 
     // With each iteration of the loop, InputReader reads and processes one incoming message from
     // the EventHub.
@@ -139,14 +137,16 @@
     static const int EVENT_BUFFER_SIZE = 256;
     RawEvent mEventBuffer[EVENT_BUFFER_SIZE];
 
-    std::unordered_map<int32_t /*deviceId*/, std::shared_ptr<InputDevice>> mDevices;
+    // An input device can represent a collection of EventHub devices. This map provides a way
+    // to lookup the input device instance from the EventHub device id.
+    std::unordered_map<int32_t /*eventHubId*/, std::shared_ptr<InputDevice>> mDevices;
 
     // low-level input event decoding and device management
     void processEventsLocked(const RawEvent* rawEvents, size_t count);
 
-    void addDeviceLocked(nsecs_t when, int32_t deviceId);
-    void removeDeviceLocked(nsecs_t when, int32_t deviceId);
-    void processEventsForDeviceLocked(int32_t deviceId, const RawEvent* rawEvents, size_t count);
+    void addDeviceLocked(nsecs_t when, int32_t eventHubId);
+    void removeDeviceLocked(nsecs_t when, int32_t eventHubId);
+    void processEventsForDeviceLocked(int32_t eventHubId, const RawEvent* rawEvents, size_t count);
     void timeoutExpiredLocked(nsecs_t when);
 
     void handleConfigurationChangedLocked(nsecs_t when);
@@ -164,6 +164,9 @@
     int32_t mGeneration;
     int32_t bumpGenerationLocked();
 
+    int32_t mNextInputDeviceId;
+    int32_t nextInputDeviceIdLocked();
+
     void getInputDevicesLocked(std::vector<InputDeviceInfo>& outInputDevices);
 
     nsecs_t mDisableVirtualKeysTimeout;
@@ -182,6 +185,9 @@
                            GetStateFunc getStateFunc);
     bool markSupportedKeyCodesLocked(int32_t deviceId, uint32_t sourceMask, size_t numCodes,
                                      const int32_t* keyCodes, uint8_t* outFlags);
+
+    // find an InputDevice from an InputDevice id
+    InputDevice* findInputDevice(int32_t deviceId);
 };
 
 } // namespace android