Determine the bluetooth address of an input device from its uniqueId

Since the Android Bluetooth stack sets a Bluetooth HID device's unique
ID as the Bluetooth address, attempt to parse the address from an input
device's uniqueId when connected over the Bluetooth bus.

DD: go/inputdevice-battery-notifications

Bug: 243005009
Test: manual, check dumpsys output
Change-Id: I710868f2b202e6cebf8b6a3853a6a5c79f3bc671
diff --git a/include/input/InputDevice.h b/include/input/InputDevice.h
index ac9c5a5..e911734 100644
--- a/include/input/InputDevice.h
+++ b/include/input/InputDevice.h
@@ -58,6 +58,9 @@
     // reuse values that are not associated with an input anymore.
     uint16_t nonce;
 
+    // The bluetooth address of the device, if known.
+    std::optional<std::string> bluetoothAddress;
+
     /**
      * Return InputDeviceIdentifier.name that has been adjusted as follows:
      *     - all characters besides alphanumerics, dash,
diff --git a/include/input/PrintTools.h b/include/input/PrintTools.h
index 55f730b..e24344b 100644
--- a/include/input/PrintTools.h
+++ b/include/input/PrintTools.h
@@ -24,16 +24,20 @@
 namespace android {
 
 template <typename T>
-std::string constToString(const T& v) {
+inline std::string constToString(const T& v) {
     return std::to_string(v);
 }
 
+inline std::string constToString(const std::string& s) {
+    return s;
+}
+
 /**
  * Convert an optional type to string.
  */
 template <typename T>
-std::string toString(const std::optional<T>& optional,
-                     std::string (*toString)(const T&) = constToString) {
+inline std::string toString(const std::optional<T>& optional,
+                            std::string (*toString)(const T&) = constToString) {
     return optional ? toString(*optional) : "<not set>";
 }
 
diff --git a/services/inputflinger/reader/EventHub.cpp b/services/inputflinger/reader/EventHub.cpp
index b97c466..18d03f8 100644
--- a/services/inputflinger/reader/EventHub.cpp
+++ b/services/inputflinger/reader/EventHub.cpp
@@ -43,6 +43,7 @@
 #include <ftl/enum.h>
 #include <input/KeyCharacterMap.h>
 #include <input/KeyLayoutMap.h>
+#include <input/PrintTools.h>
 #include <input/VirtualKeyMap.h>
 #include <openssl/sha.h>
 #include <statslog.h>
@@ -134,10 +135,6 @@
                                                                   {"green", LightColor::GREEN},
                                                                   {"blue", LightColor::BLUE}};
 
-static inline const char* toString(bool value) {
-    return value ? "true" : "false";
-}
-
 static std::string sha1(const std::string& in) {
     SHA_CTX ctx;
     SHA1_Init(&ctx);
@@ -2128,6 +2125,17 @@
         identifier.uniqueId = buffer;
     }
 
+    // Attempt to get the bluetooth address of an input device from the uniqueId.
+    if (identifier.bus == BUS_BLUETOOTH &&
+        std::regex_match(identifier.uniqueId,
+                         std::regex("^[A-Fa-f0-9]{2}(?::[A-Fa-f0-9]{2}){5}$"))) {
+        identifier.bluetoothAddress = identifier.uniqueId;
+        // The Bluetooth stack requires alphabetic characters to be uppercase in a valid address.
+        for (auto& c : *identifier.bluetoothAddress) {
+            c = ::toupper(c);
+        }
+    }
+
     // Fill in the descriptor.
     assignDescriptorLocked(identifier);
 
@@ -2625,9 +2633,10 @@
             dump += StringPrintf(INDENT3 "ControllerNumber: %d\n", device->controllerNumber);
             dump += StringPrintf(INDENT3 "UniqueId: %s\n", device->identifier.uniqueId.c_str());
             dump += StringPrintf(INDENT3 "Identifier: bus=0x%04x, vendor=0x%04x, "
-                                         "product=0x%04x, version=0x%04x\n",
+                                         "product=0x%04x, version=0x%04x, bluetoothAddress=%s\n",
                                  device->identifier.bus, device->identifier.vendor,
-                                 device->identifier.product, device->identifier.version);
+                                 device->identifier.product, device->identifier.version,
+                                 toString(device->identifier.bluetoothAddress).c_str());
             dump += StringPrintf(INDENT3 "KeyLayoutFile: %s\n",
                                  device->keyMap.keyLayoutFile.c_str());
             dump += StringPrintf(INDENT3 "KeyCharacterMapFile: %s\n",