Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1ba71cce authored by Christine Franks's avatar Christine Franks
Browse files

Add dynamic display id associations for keyboards

Bug: 184615313
Test: atest -a inputflinger_tests and atest -a libinput_tests
Change-Id: I96eb6af186e001ff37d90db2436c7d60a269d4bf
parent 8514c8e0
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -198,6 +198,10 @@ struct InputReaderConfiguration {
    // Used to determine which DisplayViewport should be tied to which InputDevice.
    std::unordered_map<std::string, uint8_t> portAssociations;

    // The associations between input device names and display unique ids.
    // Used to determine which DisplayViewport should be tied to which InputDevice.
    std::unordered_map<std::string, std::string> uniqueIdAssociations;

    // The suggested display ID to show the cursor.
    int32_t defaultPointerDisplayId;

+24 −1
Original line number Diff line number Diff line
@@ -103,6 +103,12 @@ void InputDevice::dump(std::string& dump, const std::string& eventHubDevStr) {
    } else {
        dump += "<none>\n";
    }
    dump += StringPrintf(INDENT2 "AssociatedDisplayUniqueId: ");
    if (mAssociatedDisplayUniqueId) {
        dump += StringPrintf("%s\n", mAssociatedDisplayUniqueId->c_str());
    } else {
        dump += "<none>\n";
    }
    dump += StringPrintf(INDENT2 "HasMic:     %s\n", toString(mHasMic));
    dump += StringPrintf(INDENT2 "Sources: 0x%08x\n", deviceInfo.getSources());
    dump += StringPrintf(INDENT2 "KeyboardType: %d\n", deviceInfo.getKeyboardType());
@@ -293,8 +299,9 @@ void InputDevice::configure(nsecs_t when, const InputReaderConfiguration* config
        }

        if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
            // In most situations, no port will be specified.
            // In most situations, no port or name will be specified.
            mAssociatedDisplayPort = std::nullopt;
            mAssociatedDisplayUniqueId = std::nullopt;
            mAssociatedViewport = std::nullopt;
            // Find the display port that corresponds to the current input port.
            const std::string& inputPort = mIdentifier.location;
@@ -305,6 +312,13 @@ void InputDevice::configure(nsecs_t when, const InputReaderConfiguration* config
                    mAssociatedDisplayPort = std::make_optional(displayPort->second);
                }
            }
            const std::string& inputDeviceName = mIdentifier.name;
            const std::unordered_map<std::string, std::string>& names =
                    config->uniqueIdAssociations;
            const auto& displayUniqueId = names.find(inputDeviceName);
            if (displayUniqueId != names.end()) {
                mAssociatedDisplayUniqueId = displayUniqueId->second;
            }

            // If the device was explicitly disabled by the user, it would be present in the
            // "disabledDevices" list. If it is associated with a specific display, and it was not
@@ -319,6 +333,15 @@ void InputDevice::configure(nsecs_t when, const InputReaderConfiguration* config
                          getName().c_str(), *mAssociatedDisplayPort);
                    enabled = false;
                }
            } else if (mAssociatedDisplayUniqueId != std::nullopt) {
                mAssociatedViewport =
                        config->getDisplayViewportByUniqueId(*mAssociatedDisplayUniqueId);
                if (!mAssociatedViewport) {
                    ALOGW("Input device %s should be associated with display %s but the "
                          "corresponding viewport cannot be found",
                          inputDeviceName.c_str(), mAssociatedDisplayUniqueId->c_str());
                    enabled = false;
                }
            }

            if (changes) {
+1 −0
Original line number Diff line number Diff line
@@ -169,6 +169,7 @@ private:
    uint32_t mSources;
    bool mIsExternal;
    std::optional<uint8_t> mAssociatedDisplayPort;
    std::optional<std::string> mAssociatedDisplayUniqueId;
    std::optional<DisplayViewport> mAssociatedViewport;
    bool mHasMic;
    bool mDropUntilNextSync;
+1 −3
Original line number Diff line number Diff line
@@ -132,9 +132,7 @@ void KeyboardInputMapper::dump(std::string& dump) {

std::optional<DisplayViewport> KeyboardInputMapper::findViewport(
        nsecs_t when, const InputReaderConfiguration* config) {
    const std::optional<uint8_t> displayPort = getDeviceContext().getAssociatedDisplayPort();
    if (displayPort) {
        // Find the viewport that contains the same port
    if (getDeviceContext().getAssociatedViewport()) {
        return getDeviceContext().getAssociatedViewport();
    }

+40 −2
Original line number Diff line number Diff line
@@ -269,6 +269,11 @@ public:
        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 @@ TEST_F(InputDeviceTest, Configure_AssignsDisplayPort) {
    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 @@ TEST_F(MultiTouchInputMapperTest, Configure_EnabledForAssociatedDisplay) {
    ASSERT_EQ(SECONDARY_DISPLAY_ID, args.displayId);
}



TEST_F(MultiTouchInputMapperTest, Process_ShouldHandleSingleTouch) {
    addConfigurationProperty("touch.deviceType", "touchScreen");
    prepareDisplay(DISPLAY_ORIENTATION_0);