Add dynamic display id associations for keyboards

Bug: 184615313
Test: atest -a inputflinger_tests and atest -a libinput_tests
Change-Id: I96eb6af186e001ff37d90db2436c7d60a269d4bf
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index 0e721e9..5eaca71 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -269,6 +269,11 @@
         mConfig.portAssociations.insert({inputPort, displayPort});
     }
 
+    void addInputUniqueIdAssociation(const std::string& inputUniqueId,
+                                     const std::string& displayUniqueId) {
+        mConfig.uniqueIdAssociations.insert({inputUniqueId, displayUniqueId});
+    }
+
     void addDisabledDevice(int32_t deviceId) { mConfig.disabledDevices.insert(deviceId); }
 
     void removeDisabledDevice(int32_t deviceId) { mConfig.disabledDevices.erase(deviceId); }
@@ -2621,6 +2626,41 @@
     ASSERT_FALSE(mDevice->isEnabled());
 }
 
+TEST_F(InputDeviceTest, Configure_AssignsDisplayUniqueId) {
+    // Device should be enabled by default.
+    mFakePolicy->clearViewports();
+    mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, AINPUT_SOURCE_KEYBOARD);
+    mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), 0);
+    ASSERT_TRUE(mDevice->isEnabled());
+
+    // Device should be disabled because it is associated with a specific display, but the
+    // corresponding display is not found.
+    const std::string DISPLAY_UNIQUE_ID = "displayUniqueId";
+    mFakePolicy->addInputUniqueIdAssociation(DEVICE_NAME, DISPLAY_UNIQUE_ID);
+    mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
+                       InputReaderConfiguration::CHANGE_DISPLAY_INFO);
+    ASSERT_FALSE(mDevice->isEnabled());
+
+    // Device should be enabled when a display is found.
+    mFakePolicy->addDisplayViewport(SECONDARY_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
+                                    DISPLAY_ORIENTATION_0, /* isActive= */ true, DISPLAY_UNIQUE_ID,
+                                    NO_PORT, ViewportType::INTERNAL);
+    mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
+                       InputReaderConfiguration::CHANGE_DISPLAY_INFO);
+    ASSERT_TRUE(mDevice->isEnabled());
+
+    // Device should be disabled after set disable.
+    mFakePolicy->addDisabledDevice(mDevice->getId());
+    mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
+                       InputReaderConfiguration::CHANGE_ENABLED_STATE);
+    ASSERT_FALSE(mDevice->isEnabled());
+
+    // Device should still be disabled even found the associated display.
+    mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
+                       InputReaderConfiguration::CHANGE_DISPLAY_INFO);
+    ASSERT_FALSE(mDevice->isEnabled());
+}
+
 // --- InputMapperTest ---
 
 class InputMapperTest : public testing::Test {
@@ -7853,8 +7893,6 @@
     ASSERT_EQ(SECONDARY_DISPLAY_ID, args.displayId);
 }
 
-
-
 TEST_F(MultiTouchInputMapperTest, Process_ShouldHandleSingleTouch) {
     addConfigurationProperty("touch.deviceType", "touchScreen");
     prepareDisplay(DISPLAY_ORIENTATION_0);