Skip to content

Conversation

@add-uos
Copy link
Contributor

@add-uos add-uos commented Nov 28, 2025

extend toml and uniform some model arm code

Log: extend toml

Bug: https://pms.uniontech.com/task-view-368603.html

Summary by Sourcery

Extend and generalize TOML-based hardware configuration handling while unifying several ARM / vendor-specific code paths and improving device parsing and presentation.

New Features:

  • Support loading additional OEM TOML configuration from /usr/share and selecting TOML files via configurable name.
  • Introduce flexible tomlmatchkey-based matching and tomlconfigdemanding modes (add/adjust/delete) to control how TOML entries modify devices.
  • Add specialized disk size normalization for certain vendors and interfaces (UFS and USB).

Bug Fixes:

  • Normalize network device discovery using lshw only when interfaces are valid, ensuring WLAN/other NICs are correctly recognized and filtered.
  • Fix DeviceBaseInfo key lookup bug in readDeviceInfoKeyValue and avoid treating translated 'Unknown' as a valid value.
  • Ensure UFS interface and media type handling are consistent and correct for storage devices.
  • Remove fragile board-vendor-specific overrides for CPU, monitor, power, keyboard, memory, and camera devices that could misreport hardware details.
  • Guard polkit authorization behind a compile-time switch to avoid failures when polkit is disabled.

Enhancements:

  • Refactor Wi‑Fi derived Bluetooth and network handling to read and reuse /sys/hisys/wal/wifi_devices_info directly from hardware generator, removing intermediate DeviceManager wiring.
  • Unify translation handling by routing many user-facing strings through translateStr instead of QObject::tr and updating zh_CN translations accordingly.
  • Simplify disk info collection by centralizing smartctl parsing in DeviceGenerator and removing duplicate logic from HWGenerator.
  • Always create a default internal LCD monitor entry instead of limiting it to specific board vendors.
  • Improve monitor sizing and various device table labels by using shared translation helpers.
  • Relax matching constraints in DeviceNetwork so lshw information is applied more broadly to network devices.

Documentation:

  • Extend OEM TOML sample/guide to document tomlmatchkey usage and inline-table matching syntax.

extend toml and uniform some model arm code

Log:  extend toml

Bug: https://pms.uniontech.com/task-view-368603.html
@deepin-ci-robot
Copy link

deepin pr auto review

我来对这次代码变更进行审查。这是一个较大的变更,涉及多个文件的修改,主要集中在设备管理和配置方面。我将从代码质量、性能和安全性几个方面进行分析。

  1. 代码质量改进:
  • 翻译处理优化:

    • tr() 函数调用统一替换为 translateStr(),这表明翻译处理被集中管理,有利于维护和国际化。
    • 示例: tr("Unavailable") 改为 translateStr("Unavailable")
  • 配置管理增强:

    • 新增了 tomlmatchkeytomlconfigdemanding 配置项,提供了更灵活的设备匹配和配置管理机制。
    • 添加了 TomlFilesName 配置项,允许动态指定 TOML 配置文件。
  • 代码清理:

    • 删除了一些未使用的函数,如 setInfoFromWifiInfo() 等,减少了代码冗余。
    • 移除了特定于某些机型的硬编码处理,提高了代码的通用性。
  1. 性能改进:
  • 设备匹配优化:

    • 新增的 tomlSetBytomlmatchkey() 函数提供了更精确的设备匹配机制,可以减少不必要的设备遍历。
    • 在网络设备生成时增加了 hasWlan 标志,避免重复处理无线设备。
  • 文件读取优化:

    • TOML 文件读取增加了缓存机制,避免重复读取。
  1. 安全性改进:
  • 权限控制:

    • 对 TOML 文件访问增加了权限检查。
    • 配置项 TomlFilesName 的访问权限设置为 "private",提高了安全性。
  • 输入验证:

    • 增加了对 MAC 地址格式的验证。
    • 对 TOML 配置项的解析增加了更多的错误检查。
  1. 其他改进:
  • 代码结构优化:

    • 将一些通用功能移至 Common 类中集中管理。
    • 减少了特定机型的硬编码处理,提高了代码的可维护性。
  • 错误处理增强:

    • 增加了更多的错误检查和日志记录。
    • 对文件操作增加了更多的异常处理。

建议改进的地方:

  1. 错误处理:

    • 建议在 tomlSetBytomlmatchkey() 函数中增加更详细的错误日志,方便调试。
    • 在文件操作中应该增加更多的错误处理逻辑。
  2. 代码注释:

    • 新增的配置项 tomlmatchkeytomlconfigdemanding 需要更详细的使用说明。
    • 复杂的设备匹配逻辑需要更多的注释说明。
  3. 单元测试:

    • 建议为新增的设备匹配逻辑添加单元测试。
    • TOML 配置解析功能应该有对应的测试用例。
  4. 性能监控:

    • 建议在关键路径上添加性能监控点,特别是在设备匹配和文件读取部分。
  5. 安全性:

    • 建议对 TOML 配置文件的内容进行更严格的验证。
    • 文件路径处理应该增加更多的安全检查。

总的来说,这次变更提高了代码的可维护性和灵活性,但还需要在错误处理和测试方面进一步完善。建议在后续版本中持续改进这些方面。

@sourcery-ai
Copy link

sourcery-ai bot commented Nov 28, 2025

Reviewer's Guide

Refactors TOML-driven device customization and ARM board special handling across the device manager: introduces a generic tomlmatchkey-based matching mechanism, reworks Wi-Fi/Bluetooth/network/disk/monitor generation for special vendors, centralizes translation via translateStr, and tightens storage / network enumeration and sizing logic while adding configuration-driven TOML file selection.

Sequence diagram for TOML file discovery and application

sequenceDiagram
    autonumber
    participant UserSession
    participant MainWindow
    participant Common
    participant CmdTool
    participant DeviceManager

    UserSession->>MainWindow: startApplication()
    MainWindow->>MainWindow: initWindowTitle()
    MainWindow->>Common: tomlFilesNameSet(tomlNameFromDConfig)

    UserSession->>CmdTool: loadDmidecodeInfo(key="dmidecode1")
    CmdTool->>CmdTool: loadOemTomlFileName(mapInfo)
    CmdTool->>CmdTool: parseOemTomlInfo(defaultTomlName)
    alt customTomlName configured
        CmdTool->>Common: tomlFilesNameGet()
        CmdTool->>CmdTool: parseOemTomlInfo(customTomlName)
    end

    loop forEach DeviceType
        CmdTool->>DeviceManager: tomlDeviceSet(deviceType)
        DeviceManager->>DeviceManager: load tomlMapLst for deviceType
        loop forEach tomlEntry in tomlMapLst
            DeviceManager->>DeviceManager: tomlSetBytomlmatchkey(deviceType, device, tomlmatchkey, tomlconfigdemanding)
            alt tomlconfigdemanding == "adjust"
                alt tomlmatchkey matches device
                    DeviceManager->>DeviceManager: tomlDeviceMapSet(deviceType, device, tomlEntry)
                end
            else tomlconfigdemanding == "delete"
                alt tomlmatchkey matches device
                    DeviceManager->>DeviceManager: tomlDeviceMapSet(deviceType, device, tomlEntry)
                    DeviceManager->>DeviceManager: tomlDeviceDel(deviceType, device)
                end
            else tomlconfigdemanding == "add"
                alt no device matched
                    DeviceManager->>DeviceManager: createDevice(deviceType)
                    DeviceManager->>DeviceManager: tomlDeviceMapSet(deviceType, newDevice, tomlEntry)
                    DeviceManager->>DeviceManager: tomlDeviceAdd(deviceType, newDevice)
                end
            else default matching
                alt not matched by tomlmatchkey
                    DeviceManager->>DeviceManager: findByModalias(deviceType, device, modalias)
                    DeviceManager->>DeviceManager: findByVIDPID(deviceType, device, vid, pid)
                    DeviceManager->>DeviceManager: findByVendorName(deviceType, device, vendor, name)
                end
                alt matched and not yet fixed
                    DeviceManager->>DeviceManager: tomlDeviceMapSet(deviceType, device, tomlEntry)
                    alt tomlDeviceMapSet returns TOML_Del
                        DeviceManager->>DeviceManager: tomlDeviceDel(deviceType, device)
                    end
                end
            end
        end
    end
Loading

Sequence diagram for updated network device generation

sequenceDiagram
    autonumber
    participant HWGenerator
    participant DeviceGenerator
    participant DeviceManager
    participant CmdTool as CmdInfoProvider
    participant DeviceNetwork

    HWGenerator->>DeviceGenerator: generatorNetworkDevice()
    activate DeviceGenerator

    Note over DeviceGenerator: New logic builds list solely from lshw/hwinfo

    DeviceGenerator->>DeviceManager: cmdInfo("lshw_network")
    DeviceManager-->>DeviceGenerator: QList~QMap~ for lshw

    loop forEach lshwEntry
        alt has serial and logical name
            DeviceGenerator->>DeviceGenerator: validate logicalName and macAddress
            alt logicalName contains wlan and hasWlan is true
                DeviceGenerator->>DeviceGenerator: skip entry (only 1 wlan)
            else invalid MAC format or all zeros/ffs
                DeviceGenerator->>DeviceGenerator: skip entry
            else sysfs path exists in /sys/class/net
                DeviceGenerator->>DeviceNetwork: new DeviceNetwork()
                DeviceGenerator->>DeviceNetwork: setInfoFromLshw(lshwEntry)
                DeviceGenerator->>DeviceGenerator: append to lstDevice
                alt logicalName contains wlan
                    DeviceGenerator->>DeviceGenerator: set hasWlan = true
                end
            end
        else
            DeviceGenerator->>DeviceGenerator: skip entry
        end
    end

    DeviceGenerator->>DeviceManager: cmdInfo("hwinfo_network")
    DeviceManager-->>DeviceGenerator: QList~QMap~ for hwinfo

    loop forEach hwinfoEntry
        alt contains HW Address and Device File
            DeviceGenerator->>DeviceGenerator: find matching DeviceNetwork in lstDevice
            alt hwinfoEntry has unique_id
                DeviceGenerator->>DeviceNetwork: setEnableValue(false)
            else match by HW Address or Device File
                DeviceGenerator->>DeviceNetwork: setInfoFromHwinfo(hwinfoEntry)
            else no match
                DeviceGenerator->>DeviceNetwork: setCanUninstall(false)
                DeviceGenerator->>DeviceNetwork: setForcedDisplay(true)
            end
        else
            DeviceGenerator->>DeviceGenerator: skip entry
        end
    end

    loop forEach device in lstDevice
        DeviceGenerator->>DeviceManager: addNetworkDevice(device)
    end

    deactivate DeviceGenerator
Loading

Class diagram for updated TOML matching and device generation logic

classDiagram
    direction TB

    class DeviceManager {
        +tomlDeviceSet(deviceType)
        +tomlDeviceReadKeyValue(deviceType, device, key) QString
        +tomlDeviceMapSet(deviceType, device, mapInfo) TomlFixMethod
        +tomlDeviceDel(deviceType, device)
        +tomlDeviceAdd(deviceType, device)
        +tomlSetBytomlmatchkey(deviceType, device, tomltomlmatchkey, tomltomlconfigdemanding) bool
        +findByModalias(deviceType, device, modalias) bool
        +findByVIDPID(deviceType, device, vid, pid) bool
        +findByVendorName(deviceType, device, vendor, name) bool
        -m_ListDeviceBluetooth
        -m_ListDeviceNetwork
    }

    class DeviceGenerator {
        +generatorNetworkDevice()
        +generatorAudioDevice()
        +getDiskInfoFromSmartCtl()
    }

    class HWGenerator {
        +generatorCpuDevice()
        +generatorAudioDevice()
        +generatorBluetoothDevice()
        +generatorNetworkDevice()
        +generatorDiskDevice()
        +generatorMonitorDevice()
        +generatorPowerDevice()
        +generatorKeyboardDevice()
        +generatorMemoryDevice()
        +generatorCameraDevice()
    }

    class DeviceStorage {
        -m_SizeBytes : quint64
        -m_Size : QString
        -m_Interface : QString
        -m_MediaType : QString
        +unitConvertByDecimal()
        +checkDiskSize()
        +loadBaseDeviceInfo()
        +loadOtherDeviceInfo()
        +loadTableData()
        +getInfoFromsmartctl(mapInfo)
    }

    class DeviceNetwork {
        +setInfoFromLshw(mapInfo) void
        +setInfoFromHwinfo(mapInfo) bool
        +setIsWireless(sysfs) void
        +loadTableData() void
        -m_Name : QString
        -m_Model : QString
        -m_Vendor : QString
        -m_IsWireless : bool
        -m_TableData : QStringList
    }

    class DeviceBluetooth {
        +setInfoFromTomlOneByOne(mapInfo) TomlFixMethod
        +loadTableData() void
        -m_Name : QString
        -m_Model : QString
        -m_Vendor : QString
        -m_TableData : QStringList
    }

    class DeviceBaseInfo {
        +getTableData() const QStringList&
        +readDeviceInfoKeyValue(key) const QString
        +isValueValid(value) bool
        +getDriverVersion() const QString
        +getOtherAttribs() const QList~QPair~QString,QString~~
        #loadTableData() void
        #addBaseDeviceInfo(key, value) void
        #addOtherDeviceInfo(key, value) void
    }

    class DeviceMonitor {
        +parseMonitorSize(sizeDescription, inch) QString
        +caculateScreenSize() void
        -m_Width : int
        -m_Height : int
        -m_ScreenSize : QString
    }

    class CmdTool {
        +parseOemTomlInfo(filename) bool
        +loadDmidecodeInfo(key, debugfile) void
    }

    class Common {
        +boardVendorType() QString
        +specialVendorType() QString
        +specialHString() QString
        +tomlFilesNameGet() QString
        +tomlFilesNameSet(name) void
        +executeClientCmd(cmd, args, workPath, msecsWaiting, useEnv) QByteArray
    }

    class MainWindow {
        +initWindowTitle() void
    }

    DeviceGenerator <|-- HWGenerator
    DeviceBaseInfo <|-- DeviceStorage
    DeviceBaseInfo <|-- DeviceNetwork
    DeviceBaseInfo <|-- DeviceBluetooth
    DeviceBaseInfo <|-- DeviceMonitor

    DeviceManager o--> DeviceBaseInfo
    DeviceManager o--> DeviceNetwork
    DeviceManager o--> DeviceBluetooth
    DeviceManager o--> DeviceStorage

    CmdTool ..> DeviceManager : uses tomlDeviceSet
    CmdTool ..> Common : uses tomlFilesNameGet
    MainWindow ..> Common : uses tomlFilesNameSet
    HWGenerator ..> DeviceManager : uses tomlDeviceMapSet
    DeviceGenerator ..> DeviceManager : uses cmdInfo, setStorageInfoFromSmartctl
    DeviceStorage ..> Common : uses specialVendorType
    DeviceNetwork ..> Common : uses translateStr, boardVendorType
    DeviceBluetooth ..> Common : uses translateStr
    DeviceMonitor ..> Common : uses translateStr
    DeviceManager ..> Common : uses specialHString
Loading

File-Level Changes

Change Details Files
Introduce tomlmatchkey-based TOML matching and configdemanding modes (adjust/delete/add) in DeviceManager and extend TOML parsing and configuration sourcing.
  • Add DeviceManager::tomlSetBytomlmatchkey to parse tomlmatchkey inline-table style strings and compare against DeviceBaseInfo fields
  • Extend DeviceManager::tomlDeviceSet to use tomlmatchkey and tomlconfigdemanding (adjust/delete/add) before falling back to modalias/VIDPID/vendor-name matching, and to handle pure-add entries explicitly
  • Add Common::tomlFilesNameSet/Get plus DConfig loading in MainWindow to allow runtime TOML filename override
  • Extend CmdTool::parseOemTomlInfo to read TOML from /usr/share/deepin-devicemanager and support inline-table lines when parsing
  • Update CmdTool::loadDmidecodeInfo to optionally load an extra TOML file based on Common::tomlFilesNameGet
  • Update TOML guideline sample to document tomlmatchkey usage
deepin-devicemanager/src/DeviceManager/DeviceManager.cpp
deepin-devicemanager/src/DeviceManager/DeviceManager.h
deepin-devicemanager/src/GenerateDevice/CmdTool.cpp
deepin-devicemanager/src/commonfunction.cpp
deepin-devicemanager/src/commonfunction.h
deepin-devicemanager/src/Page/MainWindow.cpp
deepin-devicemanager/assets/oeminfo_sampleAnduseGuideLine_zh_CN.toml
Rework Wi-Fi/Bluetooth/network generation to read from /sys/hisys/wal/wifi_devices_info directly in HWGenerator and simplify DeviceNetwork/DeviceBluetooth integration.
  • Add readFileSysWifi helper in HWGenerator to parse wifi_devices_info into a list of maps
  • Change HWGenerator::generatorBluetoothDevice to use readFileSysWifi, construct a tempMap (with Chip Type normalization and Vendor/Type/Name), and only apply TOML overrides when Bus is UART
  • Change HWGenerator::generatorNetworkDevice to use readFileSysWifi and directly map Wi-Fi info into DT_Network wireless devices based on logical name containing wlan
  • Remove HWGenerator::getBluetoothInfoFromCatWifiInfo and getNetworkInfoFromCatWifiInfo and their header declarations
  • Remove DeviceManager::setBluetoothInfoFromWifiInfo/setNetworkInfoFromWifiInfo and corresponding DeviceBluetooth/DeviceNetwork::setInfoFromWifiInfo, in favor of direct HWGenerator mapping
deepin-devicemanager/src/GenerateDevice/HWGenerator.cpp
deepin-devicemanager/src/GenerateDevice/HWGenerator.h
deepin-devicemanager/src/DeviceManager/DeviceManager.cpp
deepin-devicemanager/src/DeviceManager/DeviceManager.h
deepin-devicemanager/src/DeviceManager/DeviceBluetooth.cpp
deepin-devicemanager/src/DeviceManager/DeviceBluetooth.h
deepin-devicemanager/src/DeviceManager/DeviceNetwork.cpp
deepin-devicemanager/src/DeviceManager/DeviceNetwork.h
Adjust hardware-specific handling for storage, monitor, power, input, camera, keyboard, and memory devices, making some special rules unconditional or board-type-gated elsewhere.
  • Remove KLVV-specific CPU and camera masking logic in HWGenerator and always apply camera vendor masking for a specific Image vendor ID
  • Move DeviceManager::checkDiskSize call to the end of HWGenerator::generatorDiskDevice and simplify/extend UFS interface version detection to always set Interface UFS 3.1 and lower-case interface for specific versions
  • Replace DeviceStorage::unitConvertByDecimal UFS size rounding with a new DeviceStorage::checkDiskSize that applies tuned size buckets for UFS and USB only on a specific vendor type
  • Make default monitor (LCD 14" 2160x1440 eDP) generation unconditional in HWGenerator::generatorMonitorDevice
  • Remove DevicePower TOML overrides in HWGenerator, plus keyboard and memory vendor-specific masking, and simplify DevicePower so daemon info is applied only when m_Name matches translateStr("battery")
deepin-devicemanager/src/GenerateDevice/HWGenerator.cpp
deepin-devicemanager/src/GenerateDevice/HWGenerator.h
deepin-devicemanager/src/DeviceManager/DeviceStorage.cpp
deepin-devicemanager/src/DeviceManager/DevicePower.cpp
Tighten network device enumeration logic to rely on lshw/hwinfo, validate MACs, and set more accurate flags.
  • Refactor DeviceGenerator::generatorNetworkDevice to stop scanning /sys/class/net directly and instead create DeviceNetwork instances from lshw records with valid MACs and existing sysfs entries, enforcing one wlan, and then enrich from hwinfo/hwinfo-DB results
  • Adjust hwinfo enrichment logic to disable devices when a DB-backed unique_id entry matches, otherwise apply hwinfo data or mark devices as non-uninstallable/forced-display when mismatched
  • Drop vendor-type gating logic in DeviceNetwork::setInfoFromLshw so lshw info is always accepted if matchToLshw passes
deepin-devicemanager/src/GenerateDevice/DeviceGenerator.cpp
deepin-devicemanager/src/DeviceManager/DeviceNetwork.cpp
Standardize translation handling via translateStr instead of QObject::tr for labels, numbers, and status tags across devices, and update translation metadata.
  • Switch DeviceCpu to use translateStr for "Processor" and "Core(s)" and for all spelled-out core-count strings in getTrNumber
  • Change DeviceStorage, DeviceNetwork, DeviceBluetooth, DeviceAudio, DeviceCdrom, DeviceImage, DeviceInput, DeviceOthers, DevicePrint, DeviceMonitor, DevicePower, DeviceBios, and DeviceGpu to rely on translateStr for labels like SSD/HDD/Unknown, "Unavailable", "Disable", "inch", "battery", and table header keys instead of QObject::tr
  • Modify DevicePrint to store "printer-make-and-model" literal key instead of a translated one for otherAttribs
  • Adjust DeviceBaseInfo::getTableData, isValueValid, and readDeviceInfoKeyValue to use translateStr-aware logic and fix a key-comparison bug
  • Update zh_CN TS file to add translations for new strings like "Frequency"/"Max Frequency" and to move numeric word translations from DeviceCpu.cpp to DeviceInfo.cpp line references
  • Remove redundant "Memory" translation entries in TS now that the context moved
deepin-devicemanager/src/DeviceManager/DeviceCpu.cpp
deepin-devicemanager/src/DeviceManager/DeviceStorage.cpp
deepin-devicemanager/src/DeviceManager/DeviceNetwork.cpp
deepin-devicemanager/src/DeviceManager/DeviceBluetooth.cpp
deepin-devicemanager/src/DeviceManager/DeviceAudio.cpp
deepin-devicemanager/src/DeviceManager/DeviceCdrom.cpp
deepin-devicemanager/src/DeviceManager/DeviceImage.cpp
deepin-devicemanager/src/DeviceManager/DeviceInput.cpp
deepin-devicemanager/src/DeviceManager/DeviceOthers.cpp
deepin-devicemanager/src/DeviceManager/DevicePrint.cpp
deepin-devicemanager/src/DeviceManager/DeviceMonitor.cpp
deepin-devicemanager/src/DeviceManager/DevicePower.cpp
deepin-devicemanager/src/DeviceManager/DeviceBios.cpp
deepin-devicemanager/src/DeviceManager/DeviceGpu.cpp
deepin-devicemanager/src/DeviceManager/DeviceInfo.cpp
deepin-devicemanager/translations/deepin-devicemanager_zh_CN.ts
Clean up storage and smartctl handling and centralize smartctl-to-storage mapping in DeviceGenerator.
  • Remove HWGenerator::getDiskInfoFromSmartCtl and DeviceStorage::UFS-specific size bucketing and HW_SSD rotation-rate hack; rely on DeviceGenerator::getDiskInfoFromSmartCtl calling DeviceManager::setStorageInfoFromSmartctl for recognized disks only
  • Simplify DeviceStorage media type handling: store raw values (SSD/HDD/Unknown) and translate only at presentation time; normalize cases where rotation rate indicates SSD
  • Ensure DeviceStorage uses translateStr for Media Type in base info / table data
deepin-devicemanager/src/GenerateDevice/HWGenerator.cpp
deepin-devicemanager/src/GenerateDevice/DeviceGenerator.cpp
deepin-devicemanager/src/DeviceManager/DeviceStorage.cpp
Polkit usage made optional at build time and minor misc fixes.
  • Wrap polkit Authority::checkAuthorizationSync usage in main.cpp with DISABLE_POLKIT guard to allow building without polkit
  • Tweak spacing/formatting and some Qt 5/6 conditionals, and fix a logic bug in DeviceBaseInfo::readDeviceInfoKeyValue (was comparing key == key)
  • Minor cleanup in HWGenerator (spacing, log messages) and JSON asset touched (likely metadata)
deepin-devicemanager/src/main.cpp
deepin-devicemanager/src/DeviceManager/DeviceInfo.cpp
deepin-devicemanager/src/GenerateDevice/HWGenerator.cpp
deepin-devicemanager/assets/org.deepin.devicemanager.json

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey there - I've reviewed your changes and found some issues that need to be addressed.

  • In DeviceGenerator::generatorNetworkDevice, the initial construction of lstDevice from /sys/class/net was removed but the new lshw-based creation of DeviceNetwork objects is still nested inside a loop over lstDevice, which starts empty, so no devices will ever be created from lshw; consider moving the new DeviceNetwork() creation logic outside the for (itDevice = lstDevice.begin(); ... ) loop or restructuring to iterate lshw entries directly when building the list.
  • DeviceBaseInfo::getTableData now sets trKey = item instead of calling translateStr(item), which effectively disables translations of table entries; if this was not intentional, restore the translateStr call or otherwise ensure localized strings are still returned.
  • DeviceManager::tomlSetBytomlmatchkey takes a tomltomlconfigdemanding parameter that is never used and always returns true/false solely based on matching key/value pairs; either remove the unused parameter or make the function responsible only for matching and keep the policy logic (add/adjust/delete) clearly separated in tomlDeviceSet to avoid confusion.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In DeviceGenerator::generatorNetworkDevice, the initial construction of lstDevice from /sys/class/net was removed but the new lshw-based creation of DeviceNetwork objects is still nested inside a loop over lstDevice, which starts empty, so no devices will ever be created from lshw; consider moving the `new DeviceNetwork()` creation logic outside the `for (itDevice = lstDevice.begin(); ... )` loop or restructuring to iterate lshw entries directly when building the list.
- DeviceBaseInfo::getTableData now sets `trKey = item` instead of calling translateStr(item), which effectively disables translations of table entries; if this was not intentional, restore the translateStr call or otherwise ensure localized strings are still returned.
- DeviceManager::tomlSetBytomlmatchkey takes a tomltomlconfigdemanding parameter that is never used and always returns true/false solely based on matching key/value pairs; either remove the unused parameter or make the function responsible only for matching and keep the policy logic (add/adjust/delete) clearly separated in tomlDeviceSet to avoid confusion.

## Individual Comments

### Comment 1
<location> `deepin-devicemanager/src/GenerateDevice/DeviceGenerator.cpp:303-309` </location>
<code_context>
-    }
-
     // 设置从lshw中获取的信息
     const QList<QMap<QString, QString>> &lstLshw = DeviceManager::instance()->cmdInfo("lshw_network");
     for (QList<QMap<QString, QString> >::const_iterator it = lstLshw.begin(); it != lstLshw.end(); ++it) {
-        if ((*it).find("serial") == (*it).end() && (*it).find("logical name") == (*it).end())
+        if ((*it).find("serial") == (*it).end() || (*it).find("logical name") == (*it).end())
             continue;

-        const QString &serialNumberLshw =  (*it)["serial"];
         const QString &logicalNameLshw =  (*it)["logical name"];
         for (QList<DeviceNetwork *>::iterator itDevice = lstDevice.begin(); itDevice != lstDevice.end(); ++itDevice) {
-            const QString &serialNumberLst =  (*itDevice)->hwAddress();
-            const QString &logicalNameLst =  (*itDevice)->logicalName();
</code_context>

<issue_to_address>
**issue (bug_risk):** Network devices are never created because the lshw loop iterates an always-empty lstDevice.

Previously `lstDevice` was pre-populated (e.g. from `/sys/class/net`) and lshw/hwinfo only enriched existing entries. In the new code that enumeration is gone, and device creation happens only inside the `for (itDevice = lstDevice.begin(); ...)` loop. Because `lstDevice` is empty, the loop body (including `new DeviceNetwork()` and `lstDevice.append(device)`) never runs, so no network devices are added to `DeviceManager`. Please either restore an initial population of `lstDevice` or create `DeviceNetwork` objects directly while processing each valid lshw entry, without wrapping that logic in the `for (itDevice ...)` loop.
</issue_to_address>

### Comment 2
<location> `deepin-devicemanager/src/DeviceManager/DeviceInfo.cpp:138` </location>
<code_context>
     loadTableData();
     m_TableDataTr.clear();
     for (const auto &item : m_TableData) {
-        QString trKey = translateStr(item);
-        if(trKey.isEmpty())
+        QString trKey = item;
+        if (trKey.isEmpty())
             m_TableDataTr.append(item);
</code_context>

<issue_to_address>
**issue (bug_risk):** Table data is no longer passed through translateStr, effectively disabling translations in getTableData.

With `trKey` now initialized to `item`, `trKey.isEmpty()` is almost never true, so `translateStr` is no longer called and translatable entries stay unlocalized. If you still intend to use the centralized translation mechanism, `trKey` should be assigned from `translateStr(item)` (or similar logic that calls `translateStr` before falling back to `item`).
</issue_to_address>

### Comment 3
<location> `deepin-devicemanager/src/GenerateDevice/HWGenerator.cpp:152-161` </location>
<code_context>
     getBluetoothInfoFromLshw();
-    getBluetoothInfoFromCatWifiInfo();
+
+    QList<QMap<QString, QString> >  lstWifiInfo = readFileSysWifi();
+    if (lstWifiInfo.size() == 0) {
+        return;
+    }
+    QList<QMap<QString, QString> >::const_iterator it = lstWifiInfo.begin();
+    QMap<QString, QString> tempMap;
+    for (; it != lstWifiInfo.end(); ++it) {
+        if ((*it).size() < 3) {
+            continue;
+        }
+
+        foreach (const QString &key, (*it).keys()) {
+            tempMap.insert(key, (*it)[key]);
+        }
</code_context>

<issue_to_address>
**suggestion (bug_risk):** tempMap is reused across wifi-info iterations in generatorBluetoothDevice, which can unintentionally mix entries.

Because `tempMap` is declared outside the `for (; it != lstWifiInfo.end(); ++it)` loop and never cleared, each wifi entry writes into the same map. Keys from earlier entries can remain and pollute later ones, leading to incorrect data being associated with devices. To avoid this, either declare `QMap<QString, QString> tempMap;` inside the loop or call `tempMap.clear()` at the start of each iteration.

Suggested implementation:

```cpp
    QList<QMap<QString, QString> >  lstWifiInfo = readFileSysWifi();
    if (lstWifiInfo.size() == 0) {
        return;
    }
    QList<QMap<QString, QString> >::const_iterator it = lstWifiInfo.begin();
    for (; it != lstWifiInfo.end(); ++it) {
        if ((*it).size() < 3) {
            continue;
        }

        QMap<QString, QString> tempMap;
        foreach (const QString &key, (*it).keys()) {
            tempMap.insert(key, (*it)[key]);
        }

```

If `tempMap` is referenced outside the `for` loop (after its closing brace), its scope will need to be adjusted. In that case, ensure that whatever data structure receives `tempMap` per wifi entry (e.g. a list or device constructor) is updated *inside* the loop before `tempMap` goes out of scope, instead of relying on a single reused map after the loop.
</issue_to_address>

### Comment 4
<location> `deepin-devicemanager/src/DeviceManager/DeviceManager.cpp:601` </location>
<code_context>
     return QString("");
 }

+bool DeviceManager::tomlSetBytomlmatchkey(DeviceType deviceType, DeviceBaseInfo *device, const QString &tomltomlmatchkey, const QString &tomltomlconfigdemanding)
+{
+    Q_UNUSED(deviceType)
</code_context>

<issue_to_address>
**issue (complexity):** Consider refactoring the new TOML matching and mode logic by splitting parsing/matching into small helpers and centralizing mode handling to simplify control flow and remove unused parameters.

You can reduce the new complexity without changing behavior by separating parsing/matching and isolating the mode handling. The current implementation mixes concerns and carries unused parameters.

### 1. Split `tomlSetBytomlmatchkey` into parser + matcher, and remove unused params

Right now `tomlSetBytomlmatchkey`:

- Takes `deviceType` and `tomltomlconfigdemanding` but never uses them.
- Parses the string and matches in the same function.

Extract the parsing logic and make `tomlSetBytomlmatchkey` a thin wrapper, or call the matcher directly from `tomlDeviceSet`:

```cpp
// keep as small helpers
static QMap<QString, QString> parseTomlMatchKey(const QString &tomlmatchkey)
{
    QMap<QString, QString> itemMap;
    const QStringList keyValues = tomlmatchkey.split(",");

    for (const QString &keyValue : keyValues) {
        const QStringList wordlst = keyValue.split("=");
        if (wordlst.size() != 2)
            continue;

        QString key = wordlst[0].remove('"').trimmed();

        QString valuetmp = wordlst[1];
        QString value;
        if (valuetmp.contains("#")) {
            value = valuetmp.split("#").first().remove('"').trimmed();
        } else {
            value = valuetmp.remove('"').trimmed();
        }

        if (!key.isEmpty() && !value.isEmpty())
            itemMap.insert(key, value);
    }

    return itemMap;
}

static bool matchesTomlMatchKey(DeviceBaseInfo *device,
                                const QMap<QString, QString> &itemMap)
{
    if (itemMap.isEmpty())
        return false;

    for (auto it = itemMap.constBegin(); it != itemMap.constEnd(); ++it) {
        const QString deviceVal = device->readDeviceInfoKeyValue(it.key());
        if (deviceVal.compare(it.value(), Qt::CaseInsensitive) != 0)
            return false;
    }
    return true;
}
```

Then simplify `tomlSetBytomlmatchkey` (or remove it entirely and use the helpers directly):

```cpp
bool DeviceManager::tomlSetBytomlmatchkey(DeviceBaseInfo *device,
                                          const QString &tomltomlmatchkey)
{
    const auto conditions = parseTomlMatchKey(tomltomlmatchkey);
    return matchesTomlMatchKey(device, conditions);
}
```

And update the call site:

```cpp
bool isSameOne = false;
if (!tomltomlmatchkey.isEmpty())
    isSameOne = tomlSetBytomlmatchkey(device, tomltomlmatchkey);
```

This removes unused parameters and makes both parsing and matching testable in isolation.

### 2. Make mode handling explicit and separate from matching

The nested logic inside `tomlDeviceSet` mixes:

- matching (`tomlSetBytomlmatchkey + findBy*`)
- mode behavior (`adjust/delete/add/default`)
- bookkeeping (`fixSameOne`)

You can push most of the mode-specific behavior into a small helper, so the main loop reads more linearly and the flags are used in fewer places:

```cpp
enum class TomlConfigMode { Default, Adjust, Delete, Add };

static TomlConfigMode toTomlConfigMode(const QString &modeStr)
{
    if (modeStr == "adjust") return TomlConfigMode::Adjust;
    if (modeStr == "delete") return TomlConfigMode::Delete;
    if (modeStr == "add")    return TomlConfigMode::Add;
    return TomlConfigMode::Default;
}

bool DeviceManager::applyTomlRule(DeviceType deviceType,
                                  DeviceBaseInfo *device,
                                  const QMap<QString, QString> &tomlMap,
                                  TomlConfigMode mode,
                                  bool &fixSameOne)
{
    // assumes caller has already determined "isSameOne"
    switch (mode) {
    case TomlConfigMode::Adjust:
        fixSameOne = true;
        tomlDeviceMapSet(deviceType, device, tomlMap);
        return true;
    case TomlConfigMode::Delete:
        fixSameOne = true;
        tomlDeviceDel(deviceType, device);
        delete device;
        return true;
    case TomlConfigMode::Default:
        fixSameOne = true;
        if (TOML_Del == tomlDeviceMapSet(deviceType, device, tomlMap)) {
            tomlDeviceDel(deviceType, device);
            delete device;
        }
        return true;
    case TomlConfigMode::Add:
        // handled after loop; nothing to do here per device
        return false;
    }
    return false;
}
```

Then inside `tomlDeviceSet`, the per-device loop becomes easier to follow:

```cpp
TomlConfigMode mode = toTomlConfigMode(tomltomlconfigdemanding);
auto matchConditions = parseTomlMatchKey(tomltomlmatchkey);

for (int i = 0; i < lst.size(); ++i) {
    DeviceBaseInfo *device = lst[i];

    bool isSameOne = matchesTomlMatchKey(device, matchConditions);
    if (!isSameOne && mode == TomlConfigMode::Default) {
        // fallback matching only in default mode
        if (!isSameOne) isSameOne = findByModalias(deviceType, device, modalias);
        if (!isSameOne) isSameOne = findByVIDPID(deviceType, device, vid, pid);
        if (!isSameOne) isSameOne = findByVendorName(deviceType, device, vendor, name);
    }

    if (!isSameOne || fixSameOne)
        continue;

    applyTomlRule(deviceType, device, tomlMapLst[j], mode, fixSameOne);
}
```

This:

- Removes string-driven branching from the middle of the loop.
- Avoids reusing `fixSameOne` with subtly different meanings.
- Cleanly separates the “how do we match?” (`matchesTomlMatchKey` + `findBy*`) from “what do we do once matched?” (`applyTomlRule`).

These changes keep all existing behavior but make the flow much more readable and safer to extend.
</issue_to_address>

### Comment 5
<location> `deepin-devicemanager/src/GenerateDevice/DeviceGenerator.cpp:297` </location>
<code_context>

 void DeviceGenerator::generatorNetworkDevice()
 {
+    bool hasWlan =false;
</code_context>

<issue_to_address>
**issue (complexity):** Consider simplifying `generatorNetworkDevice` by removing the unused inner loop over `lstDevice` and extracting MAC/logical-name validation into helper functions to make the control flow clearer.

You can simplify `generatorNetworkDevice` quite a bit without changing behavior.

### 1. lshw loop: remove unused inner iteration over `lstDevice`

Right now you iterate over `lstDevice` but never use `*itDevice` inside the body; you only append new devices. On the first iteration `lstDevice` is empty, so the device‑creation code never runs.

You can keep all existing filters and the `hasWlan` behavior while dropping the inner loop entirely:

```cpp
void DeviceGenerator::generatorNetworkDevice()
{
    bool hasWlan = false;
    QList<DeviceNetwork *> lstDevice;

    const QList<QMap<QString, QString>> &lstLshw =
        DeviceManager::instance()->cmdInfo("lshw_network");

    for (auto it = lstLshw.begin(); it != lstLshw.end(); ++it) {
        if (it->find("serial") == it->end() || it->find("logical name") == it->end())
            continue;

        const QString &logicalNameLshw = (*it)["logical name"];
        const QString &macAddressLshw  = (*it)["serial"];

        if (logicalNameLshw.contains("p2p", Qt::CaseInsensitive))
            continue;
        if (logicalNameLshw.contains("wlan", Qt::CaseInsensitive) && hasWlan)
            continue;
        if (macAddressLshw.contains("00:00:00:00:00:00", Qt::CaseInsensitive) ||
            macAddressLshw.contains("ff:ff:ff:ff:ff:ff", Qt::CaseInsensitive) ||
            macAddressLshw.isEmpty())
            continue;

        QRegularExpression macRegex("([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})");
        if (!macRegex.match(macAddressLshw).hasMatch())
            continue;

        QDir dir("/sys/class/net/" + logicalNameLshw);
        if (!dir.exists())
            continue;

        auto *device = new DeviceNetwork();
        device->setInfoFromLshw(*it);
        lstDevice.append(device);
        if (logicalNameLshw.contains("wlan", Qt::CaseInsensitive))
            hasWlan = true;
    }

    // ... existing hwinfo code ...
}
```

This keeps the same filtering behavior and use of `hasWlan`, but makes the control flow obvious: “for each lshw entry that passes filters, maybe create a device”.

### 2. Extract MAC/name filtering into helpers

The inline filters and regex make the main function hard to scan. You can pull them into local statics to reduce nesting and improve readability, without touching semantics:

```cpp
static bool isValidMac(const QString &mac)
{
    if (mac.isEmpty())
        return false;
    if (mac.contains("00:00:00:00:00:00", Qt::CaseInsensitive) ||
        mac.contains("ff:ff:ff:ff:ff:ff", Qt::CaseInsensitive))
        return false;

    static const QRegularExpression macRegex(
        QStringLiteral("([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})"));
    return macRegex.match(mac).hasMatch();
}

static bool isInterestingLogicalName(const QString &name, bool hasWlan)
{
    if (name.contains("p2p", Qt::CaseInsensitive))
        return false;
    if (name.contains("wlan", Qt::CaseInsensitive) && hasWlan)
        return false;
    return true;
}
```

Then the lshw loop simplifies further:

```cpp
if (!isInterestingLogicalName(logicalNameLshw, hasWlan))
    continue;
if (!isValidMac(macAddressLshw))
    continue;
```

This keeps behavior identical but makes `generatorNetworkDevice` shorter and easier to reason about, and the validation logic becomes independently testable.
</issue_to_address>

### Comment 6
<location> `deepin-devicemanager/src/GenerateDevice/HWGenerator.cpp:118` </location>
<code_context>
     qCDebug(appLog) << "HWGenerator::generatorAudioDevice end";
 }

+QList<QMap<QString, QString> > readFileSysWifi()
+{
+    QList<QMap<QString, QString> >  lstWifiInfo;
</code_context>

<issue_to_address>
**issue (complexity):** Consider refactoring the new wifi-based Bluetooth/Network handling into small helpers and avoiding shared mutable maps and early returns to simplify control flow and make behavior clearer.

The `readFileSysWifi` extraction is good, but the new Bluetooth/Network paths now have subtle state and duplication that are easy to simplify without changing behavior.

### 1. `generatorBluetoothDevice`: shared `tempMap` across iterations

`tempMap` is declared outside the loop and reused:

```cpp
QList<QMap<QString, QString> >::const_iterator it = lstWifiInfo.begin();
QMap<QString, QString> tempMap;
for (; it != lstWifiInfo.end(); ++it) {
    ...
    foreach (const QString &key, (*it).keys()) {
        tempMap.insert(key, (*it)[key]);
    }
    ...
    tempMap["Vendor"] = Common::specialHString();
    tempMap["Type"] = "Bluetooth Device";
    tempMap["Name"] = tempMap["Chip Type"];
}
...
for (int i = 0; i < lst.size(); i++) {
    ...
    if (bus.contains("UART",Qt::CaseInsensitive)) {
        DeviceManager::instance()->tomlDeviceMapSet(DT_Bluetoorh, device,tempMap);
    }
}
```

This makes `tempMap` accumulate keys across all wifi entries and only the final state is applied to all UART Bluetooth devices. To make the intent explicit and avoid state leaks, build a single normalized map from the wifi info outside the loop, or rebuild a fresh map per entry and decide which one to use.

If only one wifi entry is expected, a simpler (and more obviously correct) version is:

```cpp
static QMap<QString, QString> buildBluetoothWifiMap(const QMap<QString, QString> &src)
{
    QMap<QString, QString> m = src;

    if (m["Chip Type"].contains(Common::specialHString(), Qt::CaseInsensitive)) {
        m["Chip Type"] = m["Chip Type"].remove(Common::specialHString()).trimmed();
    }

    m["Vendor"] = Common::specialHString();
    m["Type"]   = "Bluetooth Device";
    m["Name"]   = m["Chip Type"];

    return m;
}

void HWGenerator::generatorBluetoothDevice()
{
    qCDebug(appLog) << "HWGenerator::generatorBluetoothDevice start";
    getBluetoothInfoFromHciconfig();
    getBlueToothInfoFromHwinfo();
    getBluetoothInfoFromLshw();

    const auto lstWifiInfo = readFileSysWifi();
    QMap<QString, QString> wifiBtMap;
    if (!lstWifiInfo.isEmpty() && lstWifiInfo.first().size() >= 3) {
        wifiBtMap = buildBluetoothWifiMap(lstWifiInfo.first());
    }

    QList<DeviceBaseInfo *> lst = DeviceManager::instance()->convertDeviceList(DT_Bluetoorh);
    for (int i = 0; i < lst.size(); ++i) {
        DeviceBaseInfo *device = lst[i];
        const QString bus = DeviceManager::instance()->tomlDeviceReadKeyValue(DT_Bluetoorh, device, "Bus");
        if (bus.contains("UART", Qt::CaseInsensitive) && !wifiBtMap.isEmpty()) {
            DeviceManager::instance()->tomlDeviceMapSet(DT_Bluetoorh, device, wifiBtMap);
        }
    }
    qCDebug(appLog) << "HWGenerator::generatorBluetoothDevice end";
}
```

Key points:
- No reuse of a mutable `tempMap` across wifi entries.
- All wifi-based string massaging for Bluetooth lives in `buildBluetoothWifiMap`.

If you must support multiple wifi entries later, you can extend this to pick a specific one (first, last, or matching some criterion) without changing the call site pattern.

### 2. `generatorNetworkDevice`: duplicate wifi normalization

`generatorNetworkDevice` manually does almost the same normalization as the old `getNetworkInfoFromCatWifiInfo`:

```cpp
QList<QMap<QString, QString> >  lstWifiInfo = readFileSysWifi();
if (lstWifiInfo.size() == 0) {
    return;
}

QList<QMap<QString, QString> >::const_iterator it = lstWifiInfo.begin();
for (; it != lstWifiInfo.end(); ++it) {
    if ((*it).size() < 3) {
        continue;
    }

    QMap<QString, QString> tempMap;
    foreach (const QString &key, (*it).keys()) {
        tempMap.insert(key, (*it)[key]);
    }

    tempMap["Name"] = tempMap["Chip Type"];
    if (tempMap["Chip Type"].contains(Common::specialHString(), Qt::CaseInsensitive)) {
        tempMap["Name"] = tempMap["Chip Type"].remove(Common::specialHString()).trimmed();
    }

    if (tempMap["NIC  Type"].contains("WLAN", Qt::CaseInsensitive)) {
    }

    tempMap["Vendor"] = "HISILICON";
    tempMap["Type"] = "Wireless network";

    QList<DeviceBaseInfo *> lst = DeviceManager::instance()->convertDeviceList(DT_Network);
    ...
}
```

This logic is almost identical to Bluetooth’s and to the removed `getNetworkInfoFromCatWifiInfo`. You can keep behavior identical while consolidating the normalization and avoiding repeated list conversion inside the loop:

```cpp
static QMap<QString, QString> buildNetworkWifiMap(const QMap<QString, QString> &src)
{
    QMap<QString, QString> m = src;

    m["Name"] = m["Chip Type"];
    if (m["Chip Type"].contains(Common::specialHString(), Qt::CaseInsensitive)) {
        m["Name"] = m["Chip Type"].remove(Common::specialHString()).trimmed();
    }

    if (m["NIC  Type"].contains("WLAN", Qt::CaseInsensitive)) {
        // keep your existing handling if needed
    }

    m["Vendor"] = "HISILICON";
    m["Type"]   = "Wireless network";
    return m;
}

void HWGenerator::generatorNetworkDevice()
{
    qCDebug(appLog) << "HWGenerator::generatorNetworkDevice start";

    DeviceGenerator::generatorNetworkDevice();

    const auto lstWifiInfo = readFileSysWifi();
    if (lstWifiInfo.isEmpty()) {
        qCDebug(appLog) << "HWGenerator::generatorNetworkDevice no wifi info";
        qCDebug(appLog) << "HWGenerator::generatorNetworkDevice end";
        return; // or skip wifi augmentation only, see next section
    }

    QList<DeviceBaseInfo *> lst = DeviceManager::instance()->convertDeviceList(DT_Network);
    for (const auto &wifiInfo : lstWifiInfo) {
        if (wifiInfo.size() < 3)
            continue;

        const QMap<QString, QString> tempMap = buildNetworkWifiMap(wifiInfo);
        for (int i = 0; i < lst.size(); ++i) {
            DeviceBaseInfo *device = lst[i];
            const QString logicalName =
                DeviceManager::instance()->tomlDeviceReadKeyValue(DT_Network, device, "Logical Name");
            if (logicalName.contains("wlan", Qt::CaseInsensitive)) {
                DeviceManager::instance()->tomlDeviceMapSet(DT_Network, device, tempMap);
            }
        }
    }

    qCDebug(appLog) << "HWGenerator::generatorNetworkDevice end";
}
```

This keeps all wifi-derived massaging in one helper and removes the repeated `convertDeviceList` call inside the loop.

### 3. Early return vs guarding wifi-specific logic

In both generators you now `return` early if `lstWifiInfo.size() == 0`, which means any future non‑wifi logic added after that will silently not execute.

If you want to keep that behavior for now but make it safer for future changes, you can narrow the scope of the early exit to the wifi augmentation only. For example, in `generatorNetworkDevice`:

```cpp
void HWGenerator::generatorNetworkDevice()
{
    qCDebug(appLog) << "HWGenerator::generatorNetworkDevice start";
    DeviceGenerator::generatorNetworkDevice();

    const auto lstWifiInfo = readFileSysWifi();
    if (!lstWifiInfo.isEmpty()) {
        // wifi-augmentation block using buildNetworkWifiMap(...)
        ...
    }

    qCDebug(appLog) << "HWGenerator::generatorNetworkDevice end";
}
```

Same pattern can be applied to `generatorBluetoothDevice`: only skip the wifi-derived fields when wifi info is missing, but still run other generator logic.

---

These small helpers and scoping changes:
- Remove the subtle mutable state in `generatorBluetoothDevice`.
- Deduplicate wifi normalization between Bluetooth and Network (and the old helpers).
- Make it harder for future modifications to accidentally change behavior when `/sys/hisys/wal/wifi_devices_info` is missing.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

loadTableData();
m_TableDataTr.clear();
for (const auto &item : m_TableData) {
QString trKey = translateStr(item);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): Table data is no longer passed through translateStr, effectively disabling translations in getTableData.

With trKey now initialized to item, trKey.isEmpty() is almost never true, so translateStr is no longer called and translatable entries stay unlocalized. If you still intend to use the centralized translation mechanism, trKey should be assigned from translateStr(item) (or similar logic that calls translateStr before falling back to item).

@deepin-ci-robot
Copy link

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: add-uos, lzwind

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@add-uos
Copy link
Contributor Author

add-uos commented Nov 28, 2025

/merge

@deepin-bot
Copy link
Contributor

deepin-bot bot commented Nov 28, 2025

This pr cannot be merged! (status: unstable)

@add-uos
Copy link
Contributor Author

add-uos commented Nov 28, 2025

/forcemerge

@deepin-bot
Copy link
Contributor

deepin-bot bot commented Nov 28, 2025

This pr force merged! (status: unstable)

@deepin-bot deepin-bot bot merged commit 47e9d8d into linuxdeepin:master Nov 28, 2025
18 of 19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants