Skip to content

fix: resolve hotspot status transition issue#496

Merged
caixr23 merged 1 commit intolinuxdeepin:masterfrom
caixr23:bug-345413
Feb 24, 2026
Merged

fix: resolve hotspot status transition issue#496
caixr23 merged 1 commit intolinuxdeepin:masterfrom
caixr23:bug-345413

Conversation

@caixr23
Copy link
Contributor

@caixr23 caixr23 commented Feb 5, 2026

When opening a hotspot, the device status was incorrectly showing as "Connecting" instead of "Disconnected" during the Prepare and Config phases. This caused visual status jump issues in the UI.

The fix adds special handling for wireless devices in hotspot mode (AP mode). When a wireless device is in AP mode during Prepare/Config status, it now returns DS_Disconnected status instead of DS_Connecting to properly reflect the hotspot state.

Log: Fixed incorrect status display when opening hotspot

Influence:

  1. Test opening hotspot and verify status shows as Disconnected during setup
  2. Verify normal wireless connections still show Connecting status correctly
  3. Check status transitions for both hotspot and regular wireless connections
  4. Test hotspot functionality end-to-end to ensure no regression

fix: 修复热点状态跳变问题

当打开热点时,设备状态在准备和配置阶段错误地显示为"正在连接"而非"已断
开"。这导致了UI中的视觉状态跳变问题。

修复方案为热点模式(AP模式)下的无线设备添加特殊处理。当无线设备在准备/
配置状态处于AP模式时,现在返回"已断开"状态而非"正在连接"状态,以正确反映
热点状态。

Log: 修复打开热点时状态显示不正确的问题

Influence:

  1. 测试打开热点功能,验证设置过程中状态正确显示为已断开
  2. 验证普通无线连接仍能正确显示正在连接状态
  3. 检查热点和普通无线连接的状态转换
  4. 端到端测试热点功能确保无回归问题

Fixes: #345413

Summary by Sourcery

Bug Fixes:

  • Ensure wireless devices in hotspot (AP) mode report as Disconnected instead of Connecting during Prepare/Config states while keeping regular wireless connections unchanged.

@sourcery-ai
Copy link

sourcery-ai bot commented Feb 5, 2026

Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Adjusts device status mapping for wireless devices in hotspot (AP) mode so that during Prepare/Config phases they report Disconnected instead of Connecting, fixing UI status jumps while preserving existing behavior for other cases.

Sequence diagram for device status resolution with hotspot AP handling

sequenceDiagram
    participant UI
    participant NetManagerThreadPrivate
    participant NetworkDeviceBase
    participant NetworkManager
    participant NetworkInterface
    participant ActiveConnection
    participant Connection
    participant ConnectionSettings
    participant WirelessSetting

    UI->>NetManagerThreadPrivate: deviceStatus(device)
    NetManagerThreadPrivate->>NetworkDeviceBase: status()
    NetworkDeviceBase-->>NetManagerThreadPrivate: DeviceStatus_Prepare_or_Config

    alt device is wireless
        NetManagerThreadPrivate->>NetworkDeviceBase: deviceType()
        NetworkDeviceBase-->>NetManagerThreadPrivate: DeviceType_Wireless
        NetManagerThreadPrivate->>NetworkDeviceBase: path()
        NetworkDeviceBase-->>NetManagerThreadPrivate: device_path
        NetManagerThreadPrivate->>NetworkManager: findNetworkInterface(device_path)
        NetworkManager-->>NetManagerThreadPrivate: NetworkInterface

        alt interface found
            NetManagerThreadPrivate->>NetworkInterface: activeConnection()
            NetworkInterface-->>NetManagerThreadPrivate: ActiveConnection
            alt activeConnection and connection exist
                NetManagerThreadPrivate->>ActiveConnection: connection()
                ActiveConnection-->>NetManagerThreadPrivate: Connection
                NetManagerThreadPrivate->>Connection: settings()
                Connection-->>NetManagerThreadPrivate: ConnectionSettings
                NetManagerThreadPrivate->>ConnectionSettings: setting(Wireless)
                ConnectionSettings-->>NetManagerThreadPrivate: WirelessSetting
                NetManagerThreadPrivate->>WirelessSetting: mode()
                WirelessSetting-->>NetManagerThreadPrivate: Mode

                alt Mode is Ap
                    NetManagerThreadPrivate-->>UI: DS_Disconnected
                else Mode is not Ap
                    NetManagerThreadPrivate-->>UI: DS_Connecting
                end
            else no active connection or connection
                NetManagerThreadPrivate-->>UI: DS_Connecting
            end
        else interface not found
            NetManagerThreadPrivate-->>UI: DS_Connecting
        end
    else device is not wireless
        NetManagerThreadPrivate-->>UI: DS_Connecting
    end
Loading

Class diagram for updated device status mapping logic

classDiagram
    class NetManagerThreadPrivate {
        +deviceStatus(device NetworkDeviceBase) NetType_NetDeviceStatus
    }

    class NetworkDeviceBase {
        +status() DeviceStatus
        +deviceType() DeviceType
        +path() string
    }

    class NetworkManager {
        +findNetworkInterface(path string) NetworkInterface_ptr
    }

    class NetworkInterface {
        +activeConnection() ActiveConnection_ptr
    }

    class ActiveConnection {
        +connection() Connection_ptr
    }

    class Connection {
        +settings() ConnectionSettings_ptr
    }

    class ConnectionSettings {
        +setting(type Setting) SettingBase_ptr
    }

    class WirelessSetting {
        +mode() WirelessMode
    }

    class DeviceStatus {
        <<enumeration>>
        Prepare
        Config
        Disconnected
        Needauth
        IpConfig
    }

    class NetType_NetDeviceStatus {
        <<enumeration>>
        DS_Disconnected
        DS_Connecting
        DS_Authenticating
    }

    class DeviceType {
        <<enumeration>>
        Wireless
        Wired
        Other
    }

    class Setting {
        <<enumeration>>
        Wireless
        OtherSetting
    }

    class WirelessMode {
        <<enumeration>>
        Ap
        Station
        OtherMode
    }

    NetManagerThreadPrivate --> NetworkDeviceBase : uses
    NetManagerThreadPrivate --> NetworkManager : uses
    NetworkManager --> NetworkInterface : returns
    NetworkInterface --> ActiveConnection : returns
    ActiveConnection --> Connection : returns
    Connection --> ConnectionSettings : returns
    ConnectionSettings --> WirelessSetting : returns
    NetManagerThreadPrivate --> NetType_NetDeviceStatus : returns
    NetworkDeviceBase --> DeviceStatus : returns
    NetworkDeviceBase --> DeviceType : returns
    ConnectionSettings --> Setting : parameter
    WirelessSetting --> WirelessMode : returns
Loading

File-Level Changes

Change Details Files
Add special-case handling for wireless devices in AP (hotspot) mode during Prepare/Config to report Disconnected status instead of Connecting.
  • Wrap the Prepare/Config status handling in a scoped block to allow early returns based on device type and connection settings.
  • For wireless devices, look up the corresponding network interface from NetworkManager using the device path.
  • If the wireless device has an active connection with wireless settings in AP mode, return DS_Disconnected instead of DS_Connecting during Prepare/Config.
  • Fall back to returning DS_Connecting when the device is not wireless, has no active connection, has non-wireless settings, or is not in AP mode.
net-view/operation/private/netmanagerthreadprivate.cpp

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 - I've left some high level feedback:

  • The AP-mode special case logic inside the Prepare/Config branch is becoming quite nested; consider extracting it into a small helper (e.g., isWirelessApMode(device)) to improve readability and reuse if needed elsewhere.
  • You currently only apply the AP-mode check for Wireless devices; if there are other device types that can enter AP mode, it may be worth centralizing the mode check on the connection rather than the device type to avoid future inconsistencies.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The AP-mode special case logic inside the `Prepare/Config` branch is becoming quite nested; consider extracting it into a small helper (e.g., `isWirelessApMode(device)`) to improve readability and reuse if needed elsewhere.
- You currently only apply the AP-mode check for `Wireless` devices; if there are other device types that can enter AP mode, it may be worth centralizing the mode check on the connection rather than the device type to avoid future inconsistencies.

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.

@caixr23 caixr23 force-pushed the bug-345413 branch 3 times, most recently from a1350b6 to e5c61ff Compare February 5, 2026 08:38
@deepin-bot
Copy link
Contributor

deepin-bot bot commented Feb 5, 2026

TAG Bot

New tag: 2.0.81
DISTRIBUTION: unstable
Suggest: synchronizing this PR through rebase #497

@caixr23 caixr23 requested a review from mhduiy February 6, 2026 05:28
@caixr23 caixr23 force-pushed the bug-345413 branch 4 times, most recently from e67b532 to 5a6212d Compare February 24, 2026 02:03
@deepin-ci-robot
Copy link

deepin pr auto review

这段代码主要实现了判断无线网卡是否处于 AP(接入点)模式的功能,并将其应用于设备状态的判断逻辑中。整体来看,代码逻辑清晰,空指针检查完善。以下是对代码的审查意见,包括语法逻辑、代码质量、性能和安全方面的改进建议:

1. 语法逻辑与代码质量

  • 优点

    • 空指针保护:在 isWirelessApMode 函数中,对 devicedevactiveConnconnection()settings 进行了链式的非空检查,有效防止了空指针解引用导致的崩溃。
    • 类型转换:注释中明确指出了使用 staticCast 的原因(已确认设备类型),这在 C++ 中是合理的做法,比 dynamicCast 性能更好。
    • 封装性:将 isWirelessApMode 设为 private 静态函数(在头文件中声明),符合最小权限原则,仅限内部使用。
  • 改进建议

    • 头文件声明位置:在头文件中,isWirelessApMode 被声明为 static 函数。通常辅助函数放在头文件中时,如果是仅本文件使用,建议放在 .cpp 文件中使用匿名命名空间或 static 修饰,以避免污染全局符号空间或违反 ODR(One Definition Rule)。如果该函数确实需要在头文件中暴露给其他编译单元(虽然这里是 private),请确保其实现是内联的或者在 .cpp 中有对应定义。目前的实现是在 .cpp 中,这是正确的,但要注意不要在多个 .cpp 中包含该头文件导致链接错误(虽然类成员函数通常不会这样,但如果是普通静态函数会有问题)。既然是类的 private static 成员,目前的写法是安全的。
    • 代码注释:代码中的注释非常清晰,解释了为什么使用 staticCast 以及函数的用途,值得保持。

2. 代码性能

  • 分析

    • 函数 isWirelessApMode 涉及多次跨进程调用(DBus 调用),如 findNetworkInterfaceactiveConnectionconnection()settings()。这些操作相对于本地内存操作来说是非常耗时的。
    • deviceStatus 函数的 PrepareConfig 分支中调用了 isWirelessApMode。这意味着每次查询设备状态且处于这两个中间状态时,都会触发一系列 DBus 查询。
  • 改进建议

    • 缓存机制:如果 deviceStatus 被高频调用(例如 UI 刷新频率较高),且设备状态长时间停留在 PrepareConfig,频繁的 DBus 调用会造成不必要的性能开销。
    • 建议:可以考虑在 NetworkDeviceBase 或相关上下文中缓存当前的 AP 模式状态,或者在状态变更信号(如 PropertiesChanged)触发时更新该缓存。isWirelessApMode 可以优先读取缓存,缓存未命中时再进行 DBus 查询。这样可以显著减少 IPC(进程间通信)开销。

3. 代码安全

  • 分析

    • 代码中使用了 static_cast,虽然注释说明了原因,但 settings->setting(Setting::Wireless) 返回的是 Setting::Ptr。如果 NetworkManager 库的内部实现发生变化,或者 deviceType() 的判断与实际 settings 中的类型不一致(尽管可能性很小),static_cast 可能会导致未定义行为。
    • device->path() 的安全性依赖于 device 指针的有效性,代码开头已做检查。
  • 改进建议

    • 类型转换安全性:尽管 static_cast 性能更好,但为了代码的健壮性,建议在关键路径上如果对性能极其敏感且确信类型无误,可保留 static_cast。如果为了防御性编程,可以改为 object_cast(如果是 QObject 派生类)或者保留 dynamic_cast 但添加 Q_ASSERT 或日志记录,以便在 Debug 模式下捕获类型不匹配的情况。
    • DBus 调用异常处理:虽然 NetworkManager 的 Qt 封装通常会处理 DBus 错误,但在某些极端情况下(如 DBus 服务挂起),这些调用可能会阻塞或返回空指针。目前的代码处理了空指针,但没有处理潜在的异步调用失败或超时(如果是异步调用)。如果是同步调用,长时间阻塞可能影响 UI 响应。请确认这些调用是否在主线程,如果是,需警惕阻塞风险。

4. 逻辑细节

  • 关于 deviceStatus 的修改
    • 修改逻辑为:当处于 PrepareConfig 状态时,如果是 AP 模式,则返回 DS_Disconnected
    • 潜在问题DS_Disconnected 通常表示物理链路未连接或未配置。AP 模式下,设备实际上是作为热点工作的,状态是"已连接"(作为热点),而不是"未连接"。返回 DS_Disconnected 可能会导致 UI 误以为该设备完全不可用。
    • 建议:考虑是否需要引入一个新的状态 NetType::NetDeviceStatus::DS_ApMode,或者复用 DS_Connected 但在 UI 层区分是作为热点还是 Station 模式。如果业务逻辑确实希望 AP 模式下显示为"未连接外部网络",目前的修改是符合需求的,但需确保 UI 层的文案不会引起用户误解(例如显示"网络未连接"但实际上热点是开着的)。

总结

代码整体质量较高,逻辑正确,安全性较好。主要的优化点在于性能(减少 DBus 调用)和状态语义的准确性(AP 模式下的状态显示)

优化后的代码片段建议(针对安全性微调):

bool NetManagerThreadPrivate::isWirelessApMode(NetworkDeviceBase *device)
{
    // 增加空指针保护
    if (!device || device->deviceType() != dde::network::DeviceType::Wireless) {
        return false;
    }

    // 查找 NetworkManager 的接口对象
    auto dev = NetworkManager::findNetworkInterface(device->path());
    if (!dev) {
        return false;
    }

    // 获取当前活动连接
    auto activeConn = dev->activeConnection();
    if (!activeConn || !activeConn->connection()) {
        return false;
    }

    // 获取连接设置
    auto settings = activeConn->connection()->settings();
    if (!settings) {
        return false;
    }

    // 获取无线设置
    // 使用 staticCast 基于前置的类型检查
    auto wSettings = settings->setting(Setting::Wireless).staticCast<NetworkManager::WirelessSetting>();

    // 检查有效性及模式
    // 添加 Q_ASSERT 确保在 Debug 模式下类型转换的安全性
    Q_ASSERT(!wSettings.isNull()); 
    return !wSettings.isNull() && wSettings->mode() == NetworkManager::WirelessSetting::Ap;
}

关于性能优化的补充说明
如果 deviceStatus 调用非常频繁,建议在 NetworkDeviceBase 类中增加一个成员变量 m_isApMode,并在监听 ActiveConnection 变化或 Connection 更新的槽函数中更新该标志位。isWirelessApMode 函数可以直接返回该标志位,从而避免每次状态查询都进行 DBus 交互。

When opening a hotspot, the device status was incorrectly showing as
"Connecting" instead of "Disconnected" during the Prepare and Config
phases. This caused visual status jump issues in the UI.

The fix adds special handling for wireless devices in hotspot mode
(AP mode). When a wireless device is in AP mode during Prepare/Config
status, it now returns DS_Disconnected status instead of DS_Connecting
to properly reflect the hotspot state.

Log: Fixed incorrect status display when opening hotspot

Influence:
1. Test opening hotspot and verify status shows as Disconnected during
setup
2. Verify normal wireless connections still show Connecting status
correctly
3. Check status transitions for both hotspot and regular wireless
connections
4. Test hotspot functionality end-to-end to ensure no regression

fix: 修复热点状态跳变问题

当打开热点时,设备状态在准备和配置阶段错误地显示为"正在连接"而非"已断
开"。这导致了UI中的视觉状态跳变问题。

修复方案为热点模式(AP模式)下的无线设备添加特殊处理。当无线设备在准备/
配置状态处于AP模式时,现在返回"已断开"状态而非"正在连接"状态,以正确反映
热点状态。

Log: 修复打开热点时状态显示不正确的问题

Influence:
1. 测试打开热点功能,验证设置过程中状态正确显示为已断开
2. 验证普通无线连接仍能正确显示正在连接状态
3. 检查热点和普通无线连接的状态转换
4. 端到端测试热点功能确保无回归问题

Fixes: #345413
@deepin-ci-robot
Copy link

deepin pr auto review

这段代码主要实现了无线 AP 模式的检测逻辑,并据此修正了设备状态的显示。以下是对该代码的审查意见,涵盖语法逻辑、代码质量、性能和安全性四个方面:

1. 语法逻辑

  • SPDX 版权年份更新
    • 现状:将版权年份从 2019 - 2022 更新为 2019 - 2026
    • 意见:通常建议将结束年份设为当前年份(如 2024 或 2025),除非有特定的长期规划。直接设置到 2026 年略显突兀,建议根据实际情况更新。
  • 成员函数可见性修改
    • 现状:在头文件中,将 addDevice 函数从 protected 移至 private
    • 意见:这是一个好的重构,如果该函数不需要被子类访问,private 是正确的封装级别。
  • 逻辑判断
    • 现状:在 deviceStatus 函数中,当状态为 PrepareConfig 时,调用 isWirelessApMode 判断是否为 AP 模式。如果是,则返回 DS_Disconnected,否则返回 DS_Connecting
    • 意见:逻辑正确。AP 模式(热点)下,设备自身不连接外部网络,底层状态虽然可能是配置中,但从用户视角看确实不是"正在连接外部网络",返回"未连接"状态是合理的,避免了 UI 误导。

2. 代码质量

  • 空指针检查
    • 现状isWirelessApMode 函数开头检查了 device 是否为空,后续对 dev, activeConn, settings 等指针也进行了判空。
    • 意见:做得非常好。防御性编程能有效避免因底层接口返回空指针导致的崩溃。
  • 注释
    • 现状:代码中添加了清晰的注释(如"增加空指针保护"、"使用 staticCast 因为...")。
    • 意见:注释清晰,解释了"为什么"这样做,而不仅仅是"做了什么",这有助于后续维护。
  • 类型转换
    • 现状:使用 staticCast 而非 dynamicCast
    • 意见:如注释所述,由于前面已经通过 deviceType() 确认了设备类型,使用 static_cast 是安全的,且避免了 dynamic_cast 带来的运行时开销,是高质量的选择。
  • 命名规范
    • 现状:变量命名如 wSettings 略显简略。
    • 意见:建议改为 wirelessSetting 以提高可读性,虽然 wSettings 在局部作用域内尚可接受。

3. 代码性能

  • 多次接口调用与查找
    • 现状isWirelessApMode 函数中依次调用了 NetworkManager::findNetworkInterfacedev->activeConnection()activeConn->connection()settings->setting(...)
    • 意见
      • 这些调用涉及 DBus 通信或对象查找,开销相对较大。
      • 优化建议:由于 deviceStatus 可能会被频繁调用(例如 UI 刷新、状态轮询),如果 isWirelessApMode 被频繁调用,可能会造成性能瓶颈。建议考虑在 NetworkDeviceBase 或其派生类中缓存 AP 模式状态,或者在连接状态变化时更新该标志,避免每次都重新查询 DBus/NetworkManager。
      • 如果无法缓存,建议确认 deviceStatus 的调用频率是否过高,必要时由调用方进行节流。

4. 代码安全

  • 空指针解引用风险
    • 现状:代码中对指针进行了层层检查。
    • 意见:目前看来是安全的。唯一需要注意的是 staticCast 之后,wSettings 指针本身的有效性。代码中 return wSettings && ... 已经处理了 wSettings 为空的情况,非常安全。
  • 线程安全
    • 现状NetManagerThreadPrivate 从名字看涉及线程操作。
    • 意见:需要确认 NetworkManager::findNetworkInterface 以及后续获取的指针是否是线程安全的。如果这些对象属于主线程或被多个线程共享,直接在子线程中调用可能会有竞态条件。通常 NetworkManagerQt 库在多线程环境下需要小心使用,建议确认相关库的线程安全性说明。

5. 改进建议代码示例

针对变量命名和潜在的性能优化(如果无法缓存,至少保持代码整洁),微调建议如下:

bool NetManagerThreadPrivate::isWirelessApMode(NetworkDeviceBase *device)
{
    // 增加空指针保护,防止 deviceType() 崩溃
    if (!device || device->deviceType() != dde::network::DeviceType::Wireless) {
        return false;
    }

    // 查找 NetworkManager 的接口对象
    // 注意:频繁调用可能有性能开销,建议关注调用频率
    auto dev = NetworkManager::findNetworkInterface(device->path());
    if (!dev) {
        return false;
    }

    // 获取当前活动连接
    auto activeConn = dev->activeConnection();
    if (!activeConn || !activeConn->connection()) {
        return false;
    }

    // 获取连接设置
    auto settings = activeConn->connection()->settings();
    if (!settings) {
        return false;
    }

    // 检查无线设置的模式是否为 AP
    // 使用 staticCast 因为前面已经确认了设备类型,性能优于 dynamicCast
    auto wirelessSetting = settings->setting(Setting::Wireless).staticCast<NetworkManager::WirelessSetting>();

    // 检查 wirelessSetting 是否有效以及模式是否匹配
    return wirelessSetting && wirelessSetting->mode() == NetworkManager::WirelessSetting::Ap;
}

总结

整体代码质量很高,逻辑严密,安全性考虑周全。主要关注点在于性能(频繁调用 DBus 接口的开销)以及线程安全(跨线程访问 NetworkManager 对象)。建议在实际运行环境中观察该函数的调用耗时,必要时进行状态缓存优化。

@deepin-ci-robot
Copy link

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: caixr23, mhduiy

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

@caixr23 caixr23 merged commit 9e359be into linuxdeepin:master Feb 24, 2026
16 of 18 checks passed
@caixr23 caixr23 deleted the bug-345413 branch February 24, 2026 05:11
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