InputReader: Add getter for an InputDevice's phys location

Bug: 443074681
Bug: 443736238
Test: atest libinputflinger_tests
Flag: EXEMPT bug fix
Change-Id: I97fe38ae251bc686561924e1a3f888bcae9da391
diff --git a/services/inputflinger/include/InputReaderBase.h b/services/inputflinger/include/InputReaderBase.h
index 47a1782..948a704 100644
--- a/services/inputflinger/include/InputReaderBase.h
+++ b/services/inputflinger/include/InputReaderBase.h
@@ -367,6 +367,8 @@
 
     /* Get the Bluetooth address of an input device, if known. */
     virtual std::optional<std::string> getBluetoothAddress(DeviceId deviceId) const = 0;
+    /* Get the physical location path ("phys" ID) for an input device, if it is available. */
+    virtual std::optional<std::string> getPhysicalLocationPath(DeviceId deviceId) const = 0;
 
     /* Gets the sysfs root path for this device. Returns an empty path if there is none. */
     virtual std::filesystem::path getSysfsRootPath(DeviceId deviceId) const = 0;
diff --git a/services/inputflinger/reader/InputReader.cpp b/services/inputflinger/reader/InputReader.cpp
index 4eaee31..fc13c06 100644
--- a/services/inputflinger/reader/InputReader.cpp
+++ b/services/inputflinger/reader/InputReader.cpp
@@ -903,6 +903,16 @@
     return std::nullopt;
 }
 
+std::optional<std::string> InputReader::getPhysicalLocationPath(DeviceId deviceId) const {
+    std::scoped_lock _l(mLock);
+
+    InputDevice* device = findInputDeviceLocked(deviceId);
+    if (device) {
+        return device->getLocation();
+    }
+    return std::nullopt;
+}
+
 bool InputReader::canDispatchToDisplay(DeviceId deviceId, ui::LogicalDisplayId displayId) {
     std::scoped_lock _l(mLock);
 
diff --git a/services/inputflinger/reader/include/InputReader.h b/services/inputflinger/reader/include/InputReader.h
index cc824ea..c96e2dc 100644
--- a/services/inputflinger/reader/include/InputReader.h
+++ b/services/inputflinger/reader/include/InputReader.h
@@ -129,6 +129,8 @@
 
     std::optional<std::string> getBluetoothAddress(DeviceId deviceId) const override;
 
+    std::optional<std::string> getPhysicalLocationPath(DeviceId deviceId) const override;
+
     std::filesystem::path getSysfsRootPath(DeviceId deviceId) const override;
 
     void sysfsNodeChanged(const std::string& sysfsNodePath) override;
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index 10e5113..ee27f14 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -3148,6 +3148,12 @@
     ASSERT_EQ(DEVICE_BLUETOOTH_ADDRESS, *address);
 }
 
+TEST_F(InputDeviceTest, GetPhysicalLocationPath) {
+    const auto& phys = mReader->getPhysicalLocationPath(DEVICE_ID);
+    ASSERT_TRUE(phys);
+    ASSERT_EQ(DEVICE_LOCATION, *phys);
+}
+
 TEST_F(InputDeviceTest, KernelBufferOverflowResetsMappers) {
     mFakePolicy->clearViewports();
     FakeInputMapper& mapper =
diff --git a/services/inputflinger/tests/fuzzers/InputReaderFuzzer.cpp b/services/inputflinger/tests/fuzzers/InputReaderFuzzer.cpp
index 48f20da..c3d79dd 100644
--- a/services/inputflinger/tests/fuzzers/InputReaderFuzzer.cpp
+++ b/services/inputflinger/tests/fuzzers/InputReaderFuzzer.cpp
@@ -166,6 +166,10 @@
         return reader->getBluetoothAddress(deviceId);
     }
 
+    std::optional<std::string> getPhysicalLocationPath(DeviceId deviceId) const {
+        return reader->getPhysicalLocationPath(deviceId);
+    }
+
     std::filesystem::path getSysfsRootPath(DeviceId deviceId) const {
         return reader->getSysfsRootPath(deviceId);
     }
@@ -302,6 +306,7 @@
                                          std::chrono::microseconds(fdp->ConsumeIntegral<size_t>()));
                 },
                 [&]() -> void { reader->getBluetoothAddress(fdp->ConsumeIntegral<int32_t>()); },
+                [&]() -> void { reader->getPhysicalLocationPath(fdp->ConsumeIntegral<int32_t>()); },
                 [&]() -> void { reader->getSysfsRootPath(fdp->ConsumeIntegral<int32_t>()); },
         })();
     }