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

Commit b12a749f authored by Michael Crimando's avatar Michael Crimando Committed by Antonio Kantek
Browse files

Bind an input device via descriptor



These changes solve a problem for systems that have multiple displays
as well as 2 or more input devices with the exact same name. (e.g. 2
Xbox Series X controllers will report the exact same device name).

Currently the default behavior for overall Android is that input
device inputs go towards the last screen that the user touched.
On systems where a single computer is used for displaying content to
multiple people, this can be a problem. A user may be trying to play a
game with a controller on screen 1, while a second user tries to
browse the internet on screen 2. If the user on screen 2 touches the
screen, it'll keep sending the controller input events to screen 2
instead of the game on screen 1.

To fix this, the system can use a function to bind controllers to a
display. The system can just find an input device by device name
and make sure all inputs from that controller go to the correct
display. That ensures that no matter what, the controller inputs go to
the desired game on screen 1.

Now consider a single system with 2 screens and 2 different users
trying to play controller games. User A will want their controller
inputs to go to screen 1 and User B will want their controller inputs
to go to screen 2. This is possible with the current functionality.
That is, unless the controllers have the exact same device name. In
that case the controllers can only be locked to one screen or another.

Device names are not unique. However, descriptors are unique per
device. This would allow the system to uniquely identify each input
device and bind them to the correct screen.

Descriptors also cover certain scenarios. Such as a keyboard with a
track pad built into it. It'll be 2 different input devices with 2
different device names but the same descriptor.

Test: Built and run on hardware
Test: atest InputTests
Bug: 324075859
Signed-off-by: default avatarMichael Crimando <mcriman1@ford.com>
Change-Id: I27a7268eedc6be9f5423b4b8ca40b8b9728fe18c
parent 9c7dcd3e
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -135,5 +135,11 @@ flag {
  description: "Enable prediction pruning based on jerk thresholds."
  bug: "266747654"
  is_fixed_read_only: true
}

flag {
  name: "device_associations"
  namespace: "input"
  description: "Binds InputDevice name and InputDevice description against display unique id."
  bug: "324075859"
}
+6 −2
Original line number Diff line number Diff line
@@ -111,9 +111,13 @@ 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 physical port locations and display unique ids.
    // The associations between input device ports and display unique ids.
    // Used to determine which DisplayViewport should be tied to which InputDevice.
    std::unordered_map<std::string, std::string> uniqueIdAssociations;
    std::unordered_map<std::string, std::string> uniqueIdAssociationsByPort;

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

    // The associations between input device ports device types.
    // This is used to determine which device type and source should be tied to which InputDevice.
+49 −15
Original line number Diff line number Diff line
@@ -77,11 +77,11 @@ std::list<NotifyArgs> InputDevice::updateEnableState(nsecs_t when,

        // If a device is associated with a specific display but there is no
        // associated DisplayViewport, don't enable the device.
        if (enable && (mAssociatedDisplayPort || mAssociatedDisplayUniqueId) &&
        if (enable && (mAssociatedDisplayPort || mAssociatedDisplayUniqueIdByPort) &&
            !mAssociatedViewport) {
            const std::string desc = mAssociatedDisplayPort
                    ? "port " + std::to_string(*mAssociatedDisplayPort)
                    : "uniqueId " + *mAssociatedDisplayUniqueId;
                    : "uniqueId " + *mAssociatedDisplayUniqueIdByPort;
            ALOGW("Cannot enable input device %s because it is associated "
                  "with %s, but the corresponding viewport is not found",
                  getName().c_str(), desc.c_str());
@@ -124,9 +124,15 @@ 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());
    dump += StringPrintf(INDENT2 "AssociatedDisplayUniqueIdByPort: ");
    if (mAssociatedDisplayUniqueIdByPort) {
        dump += StringPrintf("%s\n", mAssociatedDisplayUniqueIdByPort->c_str());
    } else {
        dump += "<none>\n";
    }
    dump += StringPrintf(INDENT2 "AssociatedDisplayUniqueIdByDescriptor: ");
    if (mAssociatedDisplayUniqueIdByDescriptor) {
        dump += StringPrintf("%s\n", mAssociatedDisplayUniqueIdByDescriptor->c_str());
    } else {
        dump += "<none>\n";
    }
@@ -269,8 +275,28 @@ std::list<NotifyArgs> InputDevice::configureInternal(nsecs_t when,

            // In most situations, no port or name will be specified.
            mAssociatedDisplayPort = std::nullopt;
            mAssociatedDisplayUniqueId = std::nullopt;
            mAssociatedDisplayUniqueIdByPort = std::nullopt;
            mAssociatedViewport = std::nullopt;
            // Find the display port that corresponds to the current input device descriptor
            const std::string& inputDeviceDescriptor = mIdentifier.descriptor;
            if (!inputDeviceDescriptor.empty()) {
                const std::unordered_map<std::string, uint8_t>& ports =
                        readerConfig.portAssociations;
                const auto& displayPort = ports.find(inputDeviceDescriptor);
                if (displayPort != ports.end()) {
                    mAssociatedDisplayPort = std::make_optional(displayPort->second);
                } else {
                    const std::unordered_map<std::string, std::string>&
                            displayUniqueIdsByDescriptor =
                                    readerConfig.uniqueIdAssociationsByDescriptor;
                    const auto& displayUniqueIdByDescriptor =
                            displayUniqueIdsByDescriptor.find(inputDeviceDescriptor);
                    if (displayUniqueIdByDescriptor != displayUniqueIdsByDescriptor.end()) {
                        mAssociatedDisplayUniqueIdByDescriptor =
                                displayUniqueIdByDescriptor->second;
                    }
                }
            }
            // Find the display port that corresponds to the current input port.
            const std::string& inputPort = mIdentifier.location;
            if (!inputPort.empty()) {
@@ -280,11 +306,11 @@ std::list<NotifyArgs> InputDevice::configureInternal(nsecs_t when,
                if (displayPort != ports.end()) {
                    mAssociatedDisplayPort = std::make_optional(displayPort->second);
                } else {
                    const std::unordered_map<std::string, std::string>& displayUniqueIds =
                            readerConfig.uniqueIdAssociations;
                    const auto& displayUniqueId = displayUniqueIds.find(inputPort);
                    if (displayUniqueId != displayUniqueIds.end()) {
                        mAssociatedDisplayUniqueId = displayUniqueId->second;
                    const std::unordered_map<std::string, std::string>& displayUniqueIdsByPort =
                            readerConfig.uniqueIdAssociationsByPort;
                    const auto& displayUniqueIdByPort = displayUniqueIdsByPort.find(inputPort);
                    if (displayUniqueIdByPort != displayUniqueIdsByPort.end()) {
                        mAssociatedDisplayUniqueIdByPort = displayUniqueIdByPort->second;
                    }
                }
            }
@@ -299,13 +325,21 @@ std::list<NotifyArgs> InputDevice::configureInternal(nsecs_t when,
                          "but the corresponding viewport is not found.",
                          getName().c_str(), *mAssociatedDisplayPort);
                }
            } else if (mAssociatedDisplayUniqueId != std::nullopt) {
                mAssociatedViewport =
                        readerConfig.getDisplayViewportByUniqueId(*mAssociatedDisplayUniqueId);
            } else if (mAssociatedDisplayUniqueIdByDescriptor != std::nullopt) {
                mAssociatedViewport = readerConfig.getDisplayViewportByUniqueId(
                        *mAssociatedDisplayUniqueIdByDescriptor);
                if (!mAssociatedViewport) {
                    ALOGW("Input device %s should be associated with display %s but the "
                          "corresponding viewport cannot be found",
                          getName().c_str(), mAssociatedDisplayUniqueIdByDescriptor->c_str());
                }
            } else if (mAssociatedDisplayUniqueIdByPort != std::nullopt) {
                mAssociatedViewport = readerConfig.getDisplayViewportByUniqueId(
                        *mAssociatedDisplayUniqueIdByPort);
                if (!mAssociatedViewport) {
                    ALOGW("Input device %s should be associated with display %s but the "
                          "corresponding viewport cannot be found",
                          getName().c_str(), mAssociatedDisplayUniqueId->c_str());
                          getName().c_str(), mAssociatedDisplayUniqueIdByPort->c_str());
                }
            }

+12 −5
Original line number Diff line number Diff line
@@ -63,8 +63,11 @@ public:
    inline std::optional<uint8_t> getAssociatedDisplayPort() const {
        return mAssociatedDisplayPort;
    }
    inline std::optional<std::string> getAssociatedDisplayUniqueId() const {
        return mAssociatedDisplayUniqueId;
    inline std::optional<std::string> getAssociatedDisplayUniqueIdByPort() const {
        return mAssociatedDisplayUniqueIdByPort;
    }
    inline std::optional<std::string> getAssociatedDisplayUniqueIdByDescriptor() const {
        return mAssociatedDisplayUniqueIdByDescriptor;
    }
    inline std::optional<std::string> getDeviceTypeAssociation() const {
        return mAssociatedDeviceType;
@@ -194,7 +197,8 @@ private:
    bool mIsWaking;
    bool mIsExternal;
    std::optional<uint8_t> mAssociatedDisplayPort;
    std::optional<std::string> mAssociatedDisplayUniqueId;
    std::optional<std::string> mAssociatedDisplayUniqueIdByPort;
    std::optional<std::string> mAssociatedDisplayUniqueIdByDescriptor;
    std::optional<std::string> mAssociatedDeviceType;
    std::optional<DisplayViewport> mAssociatedViewport;
    bool mHasMic;
@@ -449,8 +453,11 @@ public:
    inline std::optional<uint8_t> getAssociatedDisplayPort() const {
        return mDevice.getAssociatedDisplayPort();
    }
    inline std::optional<std::string> getAssociatedDisplayUniqueId() const {
        return mDevice.getAssociatedDisplayUniqueId();
    inline std::optional<std::string> getAssociatedDisplayUniqueIdByPort() const {
        return mDevice.getAssociatedDisplayUniqueIdByPort();
    }
    inline std::optional<std::string> getAssociatedDisplayUniqueIdByDescriptor() const {
        return mDevice.getAssociatedDisplayUniqueIdByDescriptor();
    }
    inline std::optional<std::string> getDeviceTypeAssociation() const {
        return mDevice.getDeviceTypeAssociation();
+9 −3
Original line number Diff line number Diff line
@@ -536,9 +536,15 @@ std::optional<DisplayViewport> TouchInputMapper::findViewport() {
            return getDeviceContext().getAssociatedViewport();
        }

        const std::optional<std::string> associatedDisplayUniqueId =
                getDeviceContext().getAssociatedDisplayUniqueId();
        if (associatedDisplayUniqueId) {
        const std::optional<std::string> associatedDisplayUniqueIdByDescriptor =
                getDeviceContext().getAssociatedDisplayUniqueIdByDescriptor();
        if (associatedDisplayUniqueIdByDescriptor) {
            return getDeviceContext().getAssociatedViewport();
        }

        const std::optional<std::string> associatedDisplayUniqueIdByPort =
                getDeviceContext().getAssociatedDisplayUniqueIdByPort();
        if (associatedDisplayUniqueIdByPort) {
            return getDeviceContext().getAssociatedViewport();
        }

Loading