From 9143a169e5c930649f2f60f8435d15cd5eb823be Mon Sep 17 00:00:00 2001 From: zhanghongyuan Date: Tue, 29 Jul 2025 11:20:42 +0800 Subject: [PATCH] fix: Update input device Bus interface display Corrected I2C protocol touchpad showing as PS/2 interface in Device Manager, and updated input device interface detection rules. Log: Fix incorrect Bus interface display for I2C devices Bug: https://pms.uniontech.com/bug-view-326531.html Task: https://pms.uniontech.com/task-view-379781.html Change-Id: Id30e6e792ce8757de50a53e68fec6af69d490644 --- .../src/DeviceManager/DeviceInput.cpp | 98 ++++++++++++++++++- .../src/DeviceManager/DeviceInput.h | 23 +++++ 2 files changed, 120 insertions(+), 1 deletion(-) diff --git a/deepin-devicemanager/src/DeviceManager/DeviceInput.cpp b/deepin-devicemanager/src/DeviceManager/DeviceInput.cpp index 3c04e15b..245b467a 100644 --- a/deepin-devicemanager/src/DeviceManager/DeviceInput.cpp +++ b/deepin-devicemanager/src/DeviceManager/DeviceInput.cpp @@ -56,6 +56,7 @@ bool DeviceInput::setInfoFromlshw(const QMap &mapInfo) if (m_Driver.isEmpty() && "PS/2" == m_Interface) { m_CanUninstall = false; } + getMouseInfoFromBusDevice(); // 获取其他设备信息 getOtherMapInfo(mapInfo); @@ -146,6 +147,7 @@ void DeviceInput::setInfoFromHwinfo(const QMap &mapInfo) // 由bluetoothctl paired-devices设置设备接口 setInfoFromBluetoothctl(); + getMouseInfoFromBusDevice(); // 获取其他设备信息 getOtherMapInfo(mapInfo); } @@ -261,6 +263,100 @@ QString DeviceInput::eventStrFromDeviceFiles(const QString &dfs) return ""; } +InputDeviceBusInfo DeviceInput::getDetailBusInfo(const QString &busId) +{ + InputDeviceBusInfo info; + info.busId = busId; + + // 根据 Bus ID 查找对应的接口类型信息-只会使用 interfaceType,其他内容预留维护参考 + static QMap busInfoMap = { + {"0000", {"0000", "UINPUT", "虚拟设备", "用于软件模拟输入"}}, + {"0001", {"0001", "PCI", "特殊输入卡", "通过 PCI/PCIe 总线连接的设备"}}, + {"0002", {"0002", "ISA", "古老 ISA 设备", "已淘汰的 ISA 接口设备"}}, + {"0003", {"0003", "USB", "USB鼠标/键盘/手柄", "最常见的外设接口,设备路径含 usb"}}, + {"0004", {"0004", "HIL", "HP-HIL终端设备", "历史遗留系统 (HP-HIL)"}}, + {"0005", {"0005", "BLUETOOTH", "蓝牙鼠标/键盘", "设备名称含 bluetooth,需 rfkill 管理"}}, + {"0006", {"0006", "VIRTUAL", "VMware/QEMU虚拟输入", "虚拟机中的输入设备"}}, + {"0007", {"0007", "SERIAL)", "串口鼠标", "设备节点为 /dev/ttyS*"}}, + {"0008", {"0008", "HOST", "内置键盘/触摸板", "通过主板直接连接的设备"}}, + {"0009", {"0009", "Game Port", "游戏手柄", "15针 D-Sub 接口"}}, + {"0010", {"0010", "PARALLEL", "老式输入设备", "/dev/parport*"}}, + {"0011", {"0011", "PS/2", "PS/2鼠标/键盘", "圆形 6-pin 接口,设备节点为 /dev/psaux"}}, + {"0012", {"0012", "RADIO", "无线接收器", "专用 2.4G 设备 (如罗技 Unifying)"}}, + {"0013", {"0013", "J1939", "车载工业设备", "CAN 总线扩展"}}, + {"0018", {"0018", "I2C", "高端触摸板/触控笔", "设备名称含 i2c,需 i2c-tools 调试"}}, + {"0019", {"0019", "SPI", "嵌入式触控屏", "通过 SPI 总线通信"}}, + {"001a", {"001A", "ILLUMINANCE", "环境光传感器", "部分笔记本的自动亮度调节"}}, + {"001b", {"001B", "GDIX", "Surface Dial", "微软 Surface Dial 特殊旋转输入设备"}}, + {"001c", {"001C", "WACOM", "数位板/绘图屏", "设备名含 wacom"}}, + {"001d", {"001D", "UCSI", "USB Type-C输入", "新式笔记本的 USB-C 扩展设备"}} + }; + + // 查找匹配的 Bus ID (不区分大小写) + QString lowerBusId = busId.toLower(); + if (busInfoMap.contains(lowerBusId)) { + return busInfoMap.value(lowerBusId); + } + + // 如果没有找到匹配的,返回未知类型 + info.interfaceType = "Unknown"; + info.typicalDevices = "UnKnown Device"; + info.description = QString("Unrecognized Bus ID: %1").arg(busId); + + return info; +} + +void DeviceInput::getMouseInfoFromBusDevice() +{ + QProcess process; + process.start("cat", QStringList() << "/proc/bus/input/devices"); + process.waitForFinished(10000); + QString rawContent = process.readAllStandardOutput(); + + QMap nameToBusMap; + + if (rawContent.isEmpty()) { + return ; + } + + QStringList deviceBlocks = rawContent.split("\n\n", QString::SkipEmptyParts); + + for (const QString &block : deviceBlocks) { + QString bus, name; + QStringList lines = block.split("\n", QString::SkipEmptyParts); + + for (const QString &line : lines) { + QString trimmedLine = line.trimmed(); + + // 提取 Bus 信息 (I: Bus=0019 ...) + if (trimmedLine.startsWith("I:") && trimmedLine.contains("Bus=")) { + QRegExp busRegex("Bus=([0-9a-fA-F]+)"); + if (busRegex.indexIn(trimmedLine) != -1) { + bus = busRegex.cap(1); + } + } + + // 提取 Name 信息 (N: Name="Sleep Button") + if (trimmedLine.startsWith("N:") && trimmedLine.contains("Name=")) { + QRegExp nameRegex("Name=\"([^\"]+)\""); + if (nameRegex.indexIn(trimmedLine) != -1) { + name = nameRegex.cap(1); + } + } + } + + // 如果同时找到了 name 和 bus,则添加到映射中 + if (!name.isEmpty() && !bus.isEmpty()) { + nameToBusMap.insert(name, bus); + } + } + + if (nameToBusMap.contains(m_Name)) { + QString busID = nameToBusMap.value(m_Name); + m_Interface = getDetailBusInfo(busID).interfaceType; + } +} + QString DeviceInput::getBusInfo() const { return m_SysPath; @@ -291,7 +387,7 @@ bool DeviceInput::available() if (driver().isEmpty()) { m_Available = false; } - if ("PS/2" == m_Interface || "Bluetooth" == m_Interface) { + if ("PS/2" == m_Interface || "Bluetooth" == m_Interface || "I2C" == m_Interface) { m_Available = true; } return m_forcedDisplay ? m_forcedDisplay : m_Available; diff --git a/deepin-devicemanager/src/DeviceManager/DeviceInput.h b/deepin-devicemanager/src/DeviceManager/DeviceInput.h index 2320df7c..35e776f9 100644 --- a/deepin-devicemanager/src/DeviceManager/DeviceInput.h +++ b/deepin-devicemanager/src/DeviceManager/DeviceInput.h @@ -8,6 +8,17 @@ #include "DeviceInfo.h" +/** + * @brief The InputDeviceBusInfo class + * 描述InputDevice设备的Bus信息 + */ +struct InputDeviceBusInfo { + QString busId; + QString interfaceType; + QString typicalDevices; + QString description; +}; + /** * @brief The DeviceInput class * 用来描述输入设备的类 @@ -171,6 +182,18 @@ class DeviceInput : public DeviceBaseInfo */ QString eventStrFromDeviceFiles(const QString &dfs); + /** + * @brief getDetailBusInfo + * @param busId Bus ID类别号 + * @return + */ + InputDeviceBusInfo getDetailBusInfo(const QString &busId); + + /** + * @brief getMouseInfoFromBusDevice + * 实时从/proc/bus/input/devices获取设备接口信息 + */ + void getMouseInfoFromBusDevice(); private: QString m_Model; //