From 4cb65600d76de933733283f08ea6bc98b3a9ce44 Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Thu, 2 Sep 2021 15:15:19 +0800
Subject: [PATCH] fix can not distinguish hdd issue

---
 .../src/LoadInfo/ThreadPool.cpp               | 123 +-----------------
 .../src/UsbDetect/DetectJob.cpp               |  72 ----------
 .../src/UsbDetect/DetectJob.h                 |  59 ---------
 .../src/UsbDetect/DetectThread.cpp            | 102 ++++++++++++++-
 .../src/UsbDetect/DetectThread.h              |  18 ++-
 .../src/UsbDetect/MonitorUsb.cpp              |   6 +-
 .../src/DeviceManager/DeviceBluetooth.cpp     |   2 +-
 deepin-devicemanager/src/LoadInfo/CmdTool.cpp | 110 +++++++++++++---
 deepin-devicemanager/src/LoadInfo/CmdTool.h   |  28 ++++
 .../src/ThreadPool/ReadFilePool.cpp           |  10 +-
 10 files changed, 248 insertions(+), 282 deletions(-)
 delete mode 100644 deepin-devicemanager-server/src/UsbDetect/DetectJob.cpp
 delete mode 100644 deepin-devicemanager-server/src/UsbDetect/DetectJob.h

diff --git a/deepin-devicemanager-server/src/LoadInfo/ThreadPool.cpp b/deepin-devicemanager-server/src/LoadInfo/ThreadPool.cpp
index 73680f8..370482d 100644
--- a/deepin-devicemanager-server/src/LoadInfo/ThreadPool.cpp
+++ b/deepin-devicemanager-server/src/LoadInfo/ThreadPool.cpp
@@ -45,21 +45,6 @@ void ThreadPool::updateDeviceFile()
 
 void ThreadPool::initCmd()
 {
-    // According to Huawei's requirements , Modify the way of judging klu and panguv
-    // 获取华为KLU、PanguV信息
-    Cmd cmdDbus;
-    cmdDbus.cmd = QString("%1 %2%3").arg("gdbus introspect -y -d com.deepin.system.SystemInfo -o /com/deepin/system/SystemInfo -p >").arg(PATH).arg("gdbus.txt");
-    cmdDbus.file = "gdbus.txt";
-    cmdDbus.canNotReplace = false;
-    m_ListCmd.append(cmdDbus);
-
-    // 获取架构信息
-    Cmd cmdUname;
-    cmdUname.cmd = QString("%1 %2%3").arg("uname -m > ").arg(PATH).arg("uname_m.txt");
-    cmdUname.file = "uname_m.txt";
-    cmdUname.canNotReplace = false;
-    m_ListCmd.append(cmdUname);
-
     // 添加lshw命令
     Cmd cmdLshw;
     cmdLshw.cmd = QString("%1 %2%3").arg("lshw > ").arg(PATH).arg("lshw.txt");
@@ -124,70 +109,6 @@ void ThreadPool::initCmd()
     cmdDmi17.canNotReplace = true;
     m_ListCmd.append(cmdDmi17);
 
-    // 添加hwinfo --sound命令
-    Cmd cmdHwinfoSound;
-    cmdHwinfoSound.cmd = QString("%1 %2%3").arg("hwinfo --sound > ").arg(PATH).arg("hwinfo_sound.txt");
-    cmdHwinfoSound.file = "hwinfo_sound.txt";
-    cmdHwinfoSound.canNotReplace = false;
-    m_ListCmd.append(cmdHwinfoSound);
-    m_ListUpdate.append(cmdHwinfoSound);
-
-    // 添加hwinfo --usb命令
-    Cmd cmdHwinfoUsb;
-    cmdHwinfoUsb.cmd = QString("%1 %2%3").arg("hwinfo --usb > ").arg(PATH).arg("hwinfo_usb.txt");
-    cmdHwinfoUsb.file = "hwinfo_usb.txt";
-    cmdHwinfoUsb.canNotReplace = false;
-    m_ListCmd.append(cmdHwinfoUsb);
-    m_ListUpdate.append(cmdHwinfoUsb);
-
-    // 添加hwinfo --network命令
-    Cmd cmdHwinfoNetwork;
-    cmdHwinfoNetwork.cmd = QString("%1 %2%3").arg("hwinfo --network > ").arg(PATH).arg("hwinfo_network.txt");
-    cmdHwinfoNetwork.file = "hwinfo_network.txt";
-    cmdHwinfoNetwork.canNotReplace = false;
-    m_ListCmd.append(cmdHwinfoNetwork);
-    m_ListUpdate.append(cmdHwinfoNetwork);
-
-    // 添加hwinfo --keyboard命令
-    Cmd cmdHwinfoKeyboard;
-    cmdHwinfoKeyboard.cmd = QString("%1 %2%3").arg("hwinfo --keyboard > ").arg(PATH).arg("hwinfo_keyboard.txt");
-    cmdHwinfoKeyboard.file = "hwinfo_keyboard.txt";
-    cmdHwinfoKeyboard.canNotReplace = false;
-    m_ListCmd.append(cmdHwinfoKeyboard);
-    m_ListUpdate.append(cmdHwinfoKeyboard);
-
-    // 添加hwinfo --network命令
-    Cmd cmdHwinfoCdrom;
-    cmdHwinfoCdrom.cmd = QString("%1 %2%3").arg("hwinfo --cdrom > ").arg(PATH).arg("hwinfo_cdrom.txt");
-    cmdHwinfoCdrom.file = "hwinfo_cdrom.txt";
-    cmdHwinfoCdrom.canNotReplace = false;
-    m_ListCmd.append(cmdHwinfoCdrom);
-    m_ListUpdate.append(cmdHwinfoCdrom);
-
-    // 添加hwinfo --disk命令
-    Cmd cmdHwinfoDisk;
-    cmdHwinfoDisk.cmd = QString("%1 %2%3").arg("hwinfo --disk > ").arg(PATH).arg("hwinfo_disk.txt");
-    cmdHwinfoDisk.file = "hwinfo_disk.txt";
-    cmdHwinfoDisk.canNotReplace = false;
-    m_ListCmd.append(cmdHwinfoDisk);
-    m_ListUpdate.append(cmdHwinfoDisk);
-
-    // 添加hwinfo --display命令
-    Cmd cmdHwinfoDisplay;
-    cmdHwinfoDisplay.cmd = QString("%1 %2%3").arg("hwinfo --display > ").arg(PATH).arg("hwinfo_display.txt");
-    cmdHwinfoDisplay.file = "hwinfo_display.txt";
-    cmdHwinfoDisplay.canNotReplace = true;
-    m_ListCmd.append(cmdHwinfoDisplay);
-    m_ListUpdate.append(cmdHwinfoDisplay);
-
-    // 添加hwinfo --mouse命令
-    Cmd cmdHwinfoMouse;
-    cmdHwinfoMouse.cmd = QString("%1 %2%3").arg("hwinfo --mouse > ").arg(PATH).arg("hwinfo_mouse.txt");
-    cmdHwinfoMouse.file = "hwinfo_mouse.txt";
-    cmdHwinfoMouse.canNotReplace = false;
-    m_ListCmd.append(cmdHwinfoMouse);
-    m_ListUpdate.append(cmdHwinfoMouse);
-
     // 添加hwinfo --power命令
     Cmd cmdUpower;
     cmdUpower.cmd = QString("%1 %2%3").arg("upower --dump > ").arg(PATH).arg("upower_dump.txt");
@@ -268,42 +189,10 @@ void ThreadPool::initCmd()
     cmdLsMod.canNotReplace = true;
     m_ListCmd.append(cmdLsMod);
 
-    //    if (info.contains("klu")) {
-    //        Cmd cmdGpuinfo;
-    //        cmdGpuinfo.cmd = "gpuinfo";
-    //        cmdGpuinfo.file = "gpuinfo.txt";
-    //        cmdGpuinfo.canNotReplace = true;
-    //        m_ListCmd.append(cmdGpuinfo);
-
-    //        Cmd cmdBootdevice;
-    //        cmdBootdevice.cmd = "cat /proc/bootdevice/product_name";
-    //        cmdBootdevice.file = "bootdevice.txt";
-    //        cmdBootdevice.canNotReplace = false;
-    //        m_ListCmd.append(cmdBootdevice);
-
-    //    } else if (info.contains("panguV")) {
-    //        Cmd cmdGpuinfo;
-    //        cmdGpuinfo.cmd = "gpuinfo";
-    //        cmdGpuinfo.file = "gpuinfo.txt";
-    //        cmdGpuinfo.canNotReplace = true;
-    //        m_ListCmd.append(cmdGpuinfo);
-
-    //        Cmd cmdBootdevice;
-    //        cmdBootdevice.cmd = "cat /proc/bootdevice/product_name";
-    //        cmdBootdevice.file = "bootdevice.txt";
-    //        cmdBootdevice.canNotReplace = false;
-    //        m_ListCmd.append(cmdBootdevice);
-
-    //        Cmd cmdEdidHdmi;
-    //        cmdEdidHdmi.cmd = "hexdump /sys/devices/platform/hisi-drm/drm/card0/card0-HDMI-A-1/edid";
-    //        cmdEdidHdmi.file = "EDID_HDMI.txt";
-    //        cmdEdidHdmi.canNotReplace = false;
-    //        m_ListCmd.append(cmdEdidHdmi);
-
-    //        Cmd cmdEdidVGA;
-    //        cmdEdidVGA.cmd = "hexdump /sys/devices/platform/hisi-drm/drm/card0/card0-VGA-1/edid";
-    //        cmdEdidVGA.file = "EDID_VGA.txt";
-    //        cmdEdidVGA.canNotReplace = false;
-    //        m_ListCmd.append(cmdEdidVGA);
-    //    }
+    Cmd cmdHwinfo;
+    cmdHwinfo.cmd = QString("%1 %2%3").arg("hwinfo --sound --network --keyboard --cdrom --disk --display --mouse --usb > ").arg(PATH).arg("hwinfo.txt");
+    cmdHwinfo.file = "hwinfo.txt";
+    cmdHwinfo.canNotReplace = false;
+    m_ListCmd.append(cmdHwinfo);
+    m_ListUpdate.append(cmdHwinfo);
 }
diff --git a/deepin-devicemanager-server/src/UsbDetect/DetectJob.cpp b/deepin-devicemanager-server/src/UsbDetect/DetectJob.cpp
deleted file mode 100644
index cac00e8..0000000
--- a/deepin-devicemanager-server/src/UsbDetect/DetectJob.cpp
+++ /dev/null
@@ -1,72 +0,0 @@
-#include "DetectJob.h"
-
-#include <unistd.h>
-#include <QDateTime>
-#include <QDebug>
-
-#include <arpa/inet.h>
-#include <netinet/in.h>
-#include <linux/netlink.h>
-
-DetectJob::DetectJob(QObject *parent)
-    : QObject(parent)
-    , m_LaskTime(QDateTime::currentMSecsSinceEpoch())
-    , m_Elapse(10000)
-{
-
-}
-
-void DetectJob::working()
-{
-    int sockfd;
-    struct sockaddr_nl sa;
-    char buf[4096];
-    struct iovec iov;
-    struct msghdr msg;
-    //    int i;
-    memset(buf, 0, sizeof(buf));
-    memset(&sa, 0, sizeof(sa));
-    sa.nl_family = AF_NETLINK;
-    sa.nl_groups = NETLINK_KOBJECT_UEVENT;
-    sa.nl_pid = 0;//getpid(); both is ok
-    memset(&msg, 0, sizeof(msg));
-    iov.iov_base = static_cast<void *>(buf);
-    iov.iov_len = sizeof(buf);
-    msg.msg_name = static_cast<void *>(&sa);
-    msg.msg_namelen = sizeof(sa);
-    msg.msg_iov = &iov;
-    msg.msg_iovlen = 1;
-
-    sockfd = socket(AF_NETLINK/*PF_NETLINK*/, SOCK_RAW, NETLINK_KOBJECT_UEVENT);
-    if (sockfd == -1)
-        printf("socket creating failed:%s\n", strerror(errno));
-    if (bind(sockfd, reinterpret_cast<struct sockaddr *>(&sa), sizeof(sa)) == -1)
-        printf("bind error:%s\n", strerror(errno));
-
-    while (true) {
-        // len未使用到，但是，这句话不可删除，否则影响USB插拔时，/tmp/device-info的自动属性
-        int len = int(recvmsg(sockfd, &msg, 0)); //MSG_WAITALL
-        int midLen = -1;
-        QString Buf(buf);
-        if (Buf.startsWith("add@/devices/pci")) {
-            midLen = 36;
-        } else if (Buf.startsWith("remove@/devices/pci")) {
-            midLen = 39;
-        }
-
-        // 过滤部分信息
-        if (midLen == -1) {
-            continue;
-        }
-
-        emit usbChanged();
-
-        memset(buf, 0, sizeof(buf));
-        usleep(m_Elapse);
-    }
-}
-
-void DetectJob::setUSleepElapse(unsigned int elapse)
-{
-    m_Elapse = elapse;
-}
diff --git a/deepin-devicemanager-server/src/UsbDetect/DetectJob.h b/deepin-devicemanager-server/src/UsbDetect/DetectJob.h
deleted file mode 100644
index dc14958..0000000
--- a/deepin-devicemanager-server/src/UsbDetect/DetectJob.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
-* Copyright (C) 2019 ~ 2020 Uniontech Software Technology Co.,Ltd.
-*
-* Author:     Jun.Liu <liujuna@uniontech.com>
-*
-* Maintainer: XiaoMei.Ji <jixiaomei@uniontech.com>
-* Maintainer: Jun.Liu <liujuna@uniontech.com>
-*
-* This program is free software: you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation, either version 3 of the License, or
-* any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef DETECTJOB_H
-#define DETECTJOB_H
-
-#include <QObject>
-
-/**
- * @brief The DetectJob class
- */
-class DetectJob : public QObject
-{
-    Q_OBJECT
-public:
-    explicit DetectJob(QObject *parent = nullptr);
-
-    /**
-     * @brief working : main job
-     */
-    [[noreturn]]void working();
-
-    /**
-     * @brief setUSleepElapse : 设置while循环sleep时间
-     * @param elapse
-     */
-    void setUSleepElapse(unsigned int elapse);
-
-signals:
-    /**
-     * @brief usbChanged
-     */
-    void usbChanged();
-
-private:
-    qint64          m_LaskTime;           //<! last update time
-    unsigned int    m_Elapse;             //<! while循环中的sleep时间
-};
-
-#endif // DETECTJOB_H
diff --git a/deepin-devicemanager-server/src/UsbDetect/DetectThread.cpp b/deepin-devicemanager-server/src/UsbDetect/DetectThread.cpp
index 43ee67b..3c69336 100644
--- a/deepin-devicemanager-server/src/UsbDetect/DetectThread.cpp
+++ b/deepin-devicemanager-server/src/UsbDetect/DetectThread.cpp
@@ -1,12 +1,21 @@
 #include "DetectThread.h"
 #include "MonitorUsb.h"
 
+#include "QDebug"
+#include <QProcess>
+
+#define LEAST_NUM 10
+
 DetectThread::DetectThread(QObject *parent)
     : QThread(parent)
     , mp_MonitorUsb(new MonitorUsb())
 {
     // 连接槽函数
-    connect(mp_MonitorUsb, SIGNAL(usbChanged()), this, SIGNAL(usbChanged()), Qt::QueuedConnection);
+    connect(mp_MonitorUsb, SIGNAL(usbChanged()), this, SLOT(slotUsbChanged()), Qt::QueuedConnection);
+
+    QMap<QString,QMap<QString,QString>> usbInfo;
+    curHwinfoUsbInfo(usbInfo);
+    updateMemUsbInfo(usbInfo);
 }
 
 void DetectThread::run()
@@ -15,3 +24,94 @@ void DetectThread::run()
         mp_MonitorUsb->monitor();
     }
 }
+
+void DetectThread::slotUsbChanged()
+{
+    // 当监听到新的usb时，内核需要加载usb信息，而上层应用需要在内核处理之后获取信息
+    // 为了确保缓存信息之前，内核已经处理完毕，先判断内核是否处理完信息，且判断时间不能多于10s
+    qint64 begin = QDateTime::currentMSecsSinceEpoch();
+    qint64 end = begin;
+    while ((end - begin) <= 10000) {
+        if(isUsbDevicesChanged())
+            break;
+        sleep(1);
+        end = QDateTime::currentMSecsSinceEpoch();
+    }
+    qInfo() << " 此次判断插拔是否完成的时间为 ************ " << QDateTime::currentMSecsSinceEpoch() - begin;
+    emit usbChanged();
+}
+
+bool DetectThread::isUsbDevicesChanged()
+{
+    QMap<QString,QMap<QString,QString>> curUsbInfo;
+    curHwinfoUsbInfo(curUsbInfo);
+
+    // 拔出的时候，如果当前的usb设备个数小于m_MapUsbInfo的个数则返回true
+    if(curUsbInfo.size() < m_MapUsbInfo.size()){
+        updateMemUsbInfo(curUsbInfo);
+        return true;
+    }
+
+    // 数量一样或curUsbInfo的大小大于m_MapUsbInfo的大小，则一个一个的比较
+    // 如果curUsbInfo里面的在m_MapUsbInfo里面找不到则说明内核信息还没有处理完
+    foreach(const QString& key,curUsbInfo.keys()){
+        if(m_MapUsbInfo.find(key) != m_MapUsbInfo.end())
+            continue;
+        if(curUsbInfo[key]["Hardware Class"] == "disk"
+                && curUsbInfo[key].find("Capacity") == curUsbInfo[key].end())
+            continue;
+        updateMemUsbInfo(curUsbInfo);
+        return true;
+    }
+    return false;
+}
+
+void DetectThread::updateMemUsbInfo(const QMap<QString,QMap<QString,QString>>& usbInfo)
+{
+    m_MapUsbInfo.clear();
+    m_MapUsbInfo = usbInfo;
+}
+
+void DetectThread::curHwinfoUsbInfo(QMap<QString,QMap<QString,QString>>& usbInfo)
+{
+    QProcess process;
+    process.start("hwinfo --usb");
+    process.waitForFinished(-1);
+    QString info = process.readAllStandardOutput();
+
+    QStringList items = info.split("\n\n");
+    foreach(const QString& item,items){
+        QMap<QString,QString> mapItem;
+        if(!getMapInfo(item,mapItem))
+            continue;
+        usbInfo.insert(mapItem["SysFS BusID"],mapItem);
+    }
+}
+
+bool DetectThread::getMapInfo(const QString& item,QMap<QString,QString>& mapInfo)
+{
+    QStringList lines = item.split("\n");
+    // 行数太少则为无用信息
+    if(lines.size() <= LEAST_NUM){
+        return false;
+    }
+
+    foreach(const QString& line,lines){
+        QStringList words = line.split(": ");
+        if(words.size() != 2)
+            continue;
+        mapInfo.insert(words[0].trimmed(),words[1].trimmed());
+    }
+
+    // hub为usb接口，可以直接过滤
+    if(mapInfo["Hardware Class"] == "hub"){
+        return false;
+    }
+
+    // 没有总线信息的设备可以过滤
+    if(mapInfo.find("SysFS BusID") == mapInfo.end()){
+        return false;
+    }
+
+    return true;
+}
diff --git a/deepin-devicemanager-server/src/UsbDetect/DetectThread.h b/deepin-devicemanager-server/src/UsbDetect/DetectThread.h
index b5fe5a9..f5f5b7c 100644
--- a/deepin-devicemanager-server/src/UsbDetect/DetectThread.h
+++ b/deepin-devicemanager-server/src/UsbDetect/DetectThread.h
@@ -23,6 +23,8 @@
 #define DETECTTHREAD_H
 
 #include <QThread>
+#include <QMap>
+#include <QDateTime>
 
 class MonitorUsb;
 
@@ -46,8 +48,22 @@ signals:
      */
     void usbChanged();
 
+private slots:
+    /**
+     * @brief slotUsbChanged usb发生变化时的曹函数处理
+     */
+    void slotUsbChanged();
+
+private:
+    // 判断hwinfo --usb信息是否发生变化
+    bool isUsbDevicesChanged();
+    void updateMemUsbInfo(const QMap<QString,QMap<QString,QString>>& usbInfo);
+    void curHwinfoUsbInfo(QMap<QString,QMap<QString,QString>>& usbInfo);
+    bool getMapInfo(const QString& item,QMap<QString,QString>& mapInfo);
+
 private:
-    MonitorUsb   *mp_MonitorUsb;          //<! udev检测任务
+    MonitorUsb   *mp_MonitorUsb;                      //<! udev检测任务
+    QMap<QString,QMap<QString,QString>> m_MapUsbInfo; //<! usb信息
 };
 
 #endif // DETECTTHREAD_H
diff --git a/deepin-devicemanager-server/src/UsbDetect/MonitorUsb.cpp b/deepin-devicemanager-server/src/UsbDetect/MonitorUsb.cpp
index 115c9c1..68a8145 100644
--- a/deepin-devicemanager-server/src/UsbDetect/MonitorUsb.cpp
+++ b/deepin-devicemanager-server/src/UsbDetect/MonitorUsb.cpp
@@ -1,5 +1,8 @@
 #include "MonitorUsb.h"
+
 #include "QDebug"
+
+
 MonitorUsb::MonitorUsb()
     : m_Udev(nullptr)
 {
@@ -51,9 +54,6 @@ void MonitorUsb::monitor()
         // 只有add和remove事件才会更新缓存信息
         strcpy(buf, udev_device_get_action(dev));
         if (0 == strcmp("add", buf) || 0 == strcmp("remove", buf)) {
-            // 当监听到新的usb时，内核需要加载usb信息，而上层应用需要在内核处理之后获取信息
-            // 一般情况udev都会在内核处理完成后加载，但是usb2.0的会在正在加载的时候获取，需要等一段时间
-            sleep(1);
             emit usbChanged();
         }
 
diff --git a/deepin-devicemanager/src/DeviceManager/DeviceBluetooth.cpp b/deepin-devicemanager/src/DeviceManager/DeviceBluetooth.cpp
index d4c937e..04f77cf 100644
--- a/deepin-devicemanager/src/DeviceManager/DeviceBluetooth.cpp
+++ b/deepin-devicemanager/src/DeviceManager/DeviceBluetooth.cpp
@@ -46,7 +46,7 @@ bool DeviceBluetooth::setInfoFromHwinfo(const QMap<QString, QString> &mapInfo)
     if (vendor.size() < 1)
         return false;
 
-    if (!m_Vendor.contains(vendor[0]))
+    if (!m_Vendor.isEmpty() && !m_Vendor.contains(vendor[0]))
         return false;
 
     // 获取设备基本信息
diff --git a/deepin-devicemanager/src/LoadInfo/CmdTool.cpp b/deepin-devicemanager/src/LoadInfo/CmdTool.cpp
index 1dbceca..c9b6d7a 100644
--- a/deepin-devicemanager/src/LoadInfo/CmdTool.cpp
+++ b/deepin-devicemanager/src/LoadInfo/CmdTool.cpp
@@ -28,7 +28,64 @@ void CmdTool::addMapInfo(const QString &key, const QMap<QString, QString> &mapIn
         lstMap.append(mapInfo);
         m_cmdInfo.insert(key, lstMap);
     }
+}
+
+void CmdTool::addMouseKeyboardInfoMapInfo(const QString &key, const QMap<QString, QString> &mapInfo)
+{
+    if (containsInfoInTheMap("Linux Foundation", mapInfo) // 在服务器版本中发现，hwinfo --mouse 和 hwinfo --keyboard获取的信息里面有多余的无用信息，需要过滤
+            || containsInfoInTheMap("Elite Remote Control Driver", mapInfo) // 在笔记本中发现了一个多余信息，做特殊处理 Elite Remote Control Driver
+            || containsInfoInTheMap("serial console", mapInfo) // 鲲鹏台式机子上发现一条多余信息  Model: "serial console"
+            || containsInfoInTheMap("Wacom", mapInfo)) { // 数位板信息被显示成了mouse信息,这里需要做特殊处理(搞不懂数位板为什么不能显示成鼠标)
+        return;
+    }
+    addMapInfo(key, mapInfo);
+}
+
+void CmdTool::addUsbMapInfo(const QString &key, const QMap<QString, QString> &mapInfo)
+{
+    QList<QMap<QString, QString>>::iterator it = m_cmdInfo["hwinfo_usb"].begin();
+    // 有的是有同一个设备有两段信息，我们只需要一个
+    // 比如 SysFS BusID: 1-3:1.2   和  SysFS BusID: 1-3:1.0 这个是同一个设备
+    // 我们只需要一个
+    for (; it != m_cmdInfo["hwinfo_usb"].end(); ++it) {
+        QString curBus = (*it)["SysFS BusID"];
+        QString newBus = mapInfo["SysFS BusID"];
+        curBus.replace(QRegExp("\\.[0-9]{1,2}$"), "");
+        newBus.replace(QRegExp("\\.[0-9]{1,2}$"), "");
+        if (curBus == newBus) {
+            return;
+        }
+    }
+
+    // 这个是用来过滤，没有接入任何设备的usb接口
+    if (mapInfo["Model"].contains("Linux Foundation"))
+        return;
+
+    if (mapInfo["Hardware Class"].contains("hub", Qt::CaseInsensitive))
+        return;
 
+    // 打印机几信息不从hwinfo --usb里面获取，需要过滤
+    if (containsInfoInTheMap("Printer", mapInfo) || containsInfoInTheMap("LaserJet", mapInfo))
+        return;
+
+    // 提前过滤掉键盘鼠标
+    if (containsInfoInTheMap("mouse", mapInfo) || containsInfoInTheMap("keyboard", mapInfo))
+        return;
+
+    // 这里特殊处理数位板信息，通过hwinfo --mouse可以获取到数位板信息，但是根据需求数位板应该在其它设备里面(虽然这很不合理)
+    // 所以这里需要做特殊处理 即 item 里面包含了 Wacom 的 就说明是数位板设备，那就应该添加到其它设备里面
+    if (containsInfoInTheMap("Wacom", mapInfo))
+        return;
+    addMapInfo(key, mapInfo);
+}
+
+bool CmdTool::containsInfoInTheMap(const QString &info, const QMap<QString, QString> &mapInfo)
+{
+    foreach (const QString &key, mapInfo.keys()) {
+        if (mapInfo[key].contains(info, Qt::CaseInsensitive))
+            return true;
+    }
+    return false;
 }
 
 void CmdTool::getMapInfo(QMap<QString, QString> &mapInfo, cups_dest_t *src)
@@ -399,7 +456,6 @@ void CmdTool::loadPrinterInfo()
         QMap<QString, QString> mapInfo;
         dest = dests + i;
         getMapInfo(mapInfo, dest);
-
         // 这里为了和打印机管理保持一致，做出限制
         if (mapInfo.size() > 10)
             addMapInfo("printer", mapInfo);
@@ -409,34 +465,50 @@ void CmdTool::loadPrinterInfo()
 
 void CmdTool::loadHwinfoInfo(const QString &key, const QString &debugfile)
 {
-    // 获取文件信息
+    // 显示屏信息从前台直接获取
     QString deviceInfo;
-    if (key == "hwinfo_monitor")
+    if (key == "hwinfo_monitor") {
         getDeviceInfoFromCmd(deviceInfo, "hwinfo --monitor");
-    else
+        QStringList items = deviceInfo.split("\n\n");
+        foreach (const QString &item, items) {
+            if (item.isEmpty())
+                continue;
+            QMap<QString, QString> mapInfo;
+            getMapInfoFromHwinfo(item, mapInfo);
+            addMapInfo(key, mapInfo);
+        }
+    } else { // 处理其它信息 mouse sound keyboard usb display cdrom disk
         getDeviceInfo(deviceInfo, debugfile);
+        getMulHwinfoInfo(deviceInfo);
+    }
+}
 
-    QStringList items = deviceInfo.split("\n\n");
+void CmdTool::getMulHwinfoInfo(const QString &info)
+{
+    QStringList items = info.split("\n\n");
     foreach (const QString &item, items) {
         if (item.isEmpty())
             continue;
-
         QMap<QString, QString> mapInfo;
         getMapInfoFromHwinfo(item, mapInfo);
-
-        // hwinfo --usb 里面有很多的无用信息，需要特殊处理
-        if (key == "hwinfo_usb") {
-            loadHwinfoUsbInfo(item, mapInfo);
-        } else if (key == "hwinfo_mouse" || key == "hwinfo_keyboard") {
-            if (!item.contains("Linux Foundation") && // 在服务器版本中发现，hwinfo --mouse 和 hwinfo --keyboard获取的信息里面有多余的无用信息，需要过滤
-                    !item.contains("Elite Remote Control Driver") && // 在笔记本中发现了一个多余信息，做特殊处理 Elite Remote Control Driver
-                    !item.contains("Model: \"serial console\"") && // 鲲鹏台式机子上发现一条多余信息  Model: "serial console"
-                    !item.contains("Wacom", Qt::CaseInsensitive)) { // 数位板信息被显示成了mouse信息,这里需要做特殊处理(搞不懂数位板为什么不能显示成鼠标)
-
-                addMapInfo(key, mapInfo);
-            }
+        if (mapInfo["Hardware Class"] == "sound") {
+            addMapInfo("hwinfo_sound", mapInfo);
+        } else if (mapInfo["Hardware Class"] == "network interface") {
+            addMapInfo("hwinfo_network", mapInfo);
+        } else if (mapInfo["Hardware Class"] == "keyboard") {
+            addMouseKeyboardInfoMapInfo("hwinfo_keyboard", mapInfo);
+        } else if (mapInfo["Hardware Class"] == "mouse") {
+            addMouseKeyboardInfoMapInfo("hwinfo_mouse", mapInfo);
+        } else if (mapInfo["Hardware Class"] == "cdrom") {
+            addMapInfo("hwinfo_cdrom", mapInfo);
+        } else if (mapInfo["Hardware Class"] == "disk") {
+            addMapInfo("hwinfo_disk", mapInfo);
+        } else if (mapInfo["Hardware Class"] == "graphics card") {
+            if (mapInfo["Device"].contains("Graphics Processing Unit"))
+                continue;
+            addMapInfo("hwinfo_display", mapInfo);
         } else {
-            addMapInfo(key, mapInfo);
+            addUsbMapInfo("hwinfo_usb", mapInfo);
         }
     }
 }
diff --git a/deepin-devicemanager/src/LoadInfo/CmdTool.h b/deepin-devicemanager/src/LoadInfo/CmdTool.h
index c707762..ff9286f 100644
--- a/deepin-devicemanager/src/LoadInfo/CmdTool.h
+++ b/deepin-devicemanager/src/LoadInfo/CmdTool.h
@@ -139,6 +139,12 @@ private:
      */
     void loadHwinfoInfo(const QString &key, const QString &debugfile);
 
+    /**
+     * @brief getMulHwinfoInfo : 解析 hwinfo --sound --network --keyboard --cdrom --disk --display --mouse --usb
+     * @param mapLstMap
+     */
+    void getMulHwinfoInfo(const QString &info);
+
     /**
      * @brief loadHwinfoUsbInfo
      * @param item
@@ -319,6 +325,28 @@ private:
      */
     void addMapInfo(const QString &key, const QMap<QString, QString> &mapInfo);
 
+    /**
+     * @brief addMouseKeyboardInfoMapInfo : 添加map信息
+     * @param key : 与命令对应的关键字
+     * @param mapInfo : 解析得到的设备信息map
+     */
+    void addMouseKeyboardInfoMapInfo(const QString &key, const QMap<QString, QString> &mapInfo);
+
+    /**
+     * @brief addUsbMapInfo
+     * @param key
+     * @param mapInfo
+     */
+    void addUsbMapInfo(const QString &key, const QMap<QString, QString> &mapInfo);
+
+    /**
+     * @brief containsInfoInTheMap 判断一个map里面有一个str
+     * @param info
+     * @param mapInfo
+     * @return
+     */
+    bool containsInfoInTheMap(const QString &info, const QMap<QString, QString> &mapInfo);
+
     /**
      * @brief getMapInfo:解析打印机cups第三方库获取的信息
      * @param mapInfo:解析得到的map信息
diff --git a/deepin-devicemanager/src/ThreadPool/ReadFilePool.cpp b/deepin-devicemanager/src/ThreadPool/ReadFilePool.cpp
index 135d471..b9da564 100644
--- a/deepin-devicemanager/src/ThreadPool/ReadFilePool.cpp
+++ b/deepin-devicemanager/src/ThreadPool/ReadFilePool.cpp
@@ -85,15 +85,7 @@ void ReadFilePool::initCmd()
     m_CmdList.append({"dr_config", "dr_config.txt", ""});
 
     m_CmdList.append({ "hwinfo_monitor",       "hwinfo_monitor.txt",     tr("Loading CD-ROM Info...")});
-    m_CmdList.append({ "hwinfo_sound",         "hwinfo_sound.txt",       ""});
-    m_CmdList.append({ "hwinfo_usb",           "hwinfo_usb.txt",         ""});
-    m_CmdList.append({ "hwinfo_network",       "hwinfo_network.txt",     ""});
-    m_CmdList.append({ "hwinfo_keyboard",      "hwinfo_keyboard.txt",    tr("Loading Bluetooth Device Info...")});
-    m_CmdList.append({ "hwinfo_cdrom",         "hwinfo_cdrom.txt",       tr("Loading Image Devices Info...")});
-    // 注意：这里一定要用 sudo hwinfo --disk,因为很多机器只有加上sudo 才能获取硬盘的大小
-    m_CmdList.append({ "hwinfo_disk",          "hwinfo_disk.txt",        tr("Loading Keyboard Info...")});
-    m_CmdList.append({ "hwinfo_display",       "hwinfo_display.txt",     ""});
-    m_CmdList.append({ "hwinfo_mouse",         "hwinfo_mouse.txt",       ""});
+    m_CmdList.append({ "hwinfo",         "hwinfo.txt",       ""});
 
 
     m_CmdList.append({ "upower",               "upower_dump.txt",        ""});
-- 
2.27.0

