Skip to content

fix: resolve hotspot device not updating when network interface changes#499

Open
caixr23 wants to merge 1 commit intolinuxdeepin:masterfrom
caixr23:BUG-303389
Open

fix: resolve hotspot device not updating when network interface changes#499
caixr23 wants to merge 1 commit intolinuxdeepin:masterfrom
caixr23:BUG-303389

Conversation

@caixr23
Copy link
Contributor

@caixr23 caixr23 commented Feb 6, 2026

Changed from QTimer to counter mechanism for handling network configuration updates
Removed QTimer and replaced with integer counter to track update cycles Fixed issue where hotspot devices were not properly updated when network interfaces changed
The previous timer approach could miss updates if network changes occurred rapidly
New counter mechanism ensures proper sequencing of configuration updates

Log: Fixed hotspot device update issue when network interfaces change

Influence:

  1. Test hotspot functionality after network interface changes
  2. Verify hotspot configuration updates properly
  3. Check that password retrieval works correctly after network changes
  4. Test multiple rapid network interface changes
  5. Verify user active state handling remains functional

fix: 修复网卡变化时热点设备未更新问题

从 QTimer 改为计数器机制处理网络配置更新
移除 QTimer 并使用整数计数器跟踪更新周期
修复当网络接口变化时热点设备未能正确更新的问题
之前的定时器方法在快速网络变化时可能错过更新
新的计数器机制确保配置更新的正确顺序

Log: 修复网卡变化时热点设备更新问题

Influence:

  1. 测试网络接口变化后的热点功能
  2. 验证热点配置是否正确更新
  3. 检查网络变化后密码获取功能是否正常
  4. 测试多次快速网络接口变化
  5. 验证用户活跃状态处理保持正常

PMS: BUG-303389

Summary by Sourcery

Replace the hotspot configuration update timer with a counter-based mechanism to ensure hotspot devices and configuration are correctly refreshed when network interfaces or connection secrets change.

Bug Fixes:

  • Ensure hotspot devices and configuration are correctly updated when network interfaces change, avoiding missed updates during rapid network changes.

Enhancements:

  • Simplify hotspot configuration update sequencing by replacing the QTimer-based debounce logic with a lightweight integer counter.

@deepin-ci-robot
Copy link

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: caixr23

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

@sourcery-ai
Copy link

sourcery-ai bot commented Feb 6, 2026

Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Replaces the previous QTimer-based debounce/sequencing mechanism in NetHotspotController with a simple integer counter to reliably gate hotspot configuration updates when network interfaces and secrets change, addressing missed hotspot device updates under rapid network changes.

Sequence diagram for hotspot configuration updates with counter-based gating

sequenceDiagram
    participant NetHotspotController
    participant NetworkController
    participant Connection
    participant WirelessSecuritySetting

    NetHotspotController->>NetworkController: hotspotController()
    activate NetworkController
    NetworkController-->>NetHotspotController: HotspotController
    deactivate NetworkController

    Note over NetHotspotController: Initial hotspot data/config setup
    NetHotspotController->>NetHotspotController: updateData()
    NetHotspotController->>NetHotspotController: updateEnabled()
    NetHotspotController->>NetHotspotController: updateEnabledable()
    NetHotspotController->>NetHotspotController: updateConfig()
    alt m_userActive is false or m_updateCount > 0
        NetHotspotController->>NetHotspotController: m_updateCount-- (if m_updateCount > 0)
        Note over NetHotspotController: Config update deferred
    else
        NetHotspotController->>Connection: secrets(name)
        Connection-->>NetHotspotController: secrets map
        NetHotspotController->>WirelessSecuritySetting: secretsFromMap(secrets)
    end

    Note over Connection: conn->secrets triggers itemChanged twice
    loop For each itemChanged signal
        Connection-->>NetHotspotController: itemChanged
        NetHotspotController->>NetHotspotController: updateData()
        NetHotspotController->>NetHotspotController: updateEnabled()
        NetHotspotController->>NetHotspotController: updateEnabledable()
        NetHotspotController->>NetHotspotController: updateConfig()
        alt First secrets handling branch
            NetHotspotController->>NetHotspotController: m_updateCount = 2
        else Subsequent calls while m_updateCount > 0
            NetHotspotController->>NetHotspotController: m_updateCount--
            Note over NetHotspotController: Skip duplicate config updates
        end
    end
Loading

Class diagram for updated NetHotspotController debounce mechanism

classDiagram
    class NetHotspotController {
        - bool m_hotspotEnabled
        - bool m_enabledable
        - bool m_deviceEnabled
        - bool m_userActive
        - int m_updateCount
        - QStringList m_shareDevice
        - QStringList m_optionalDevice
        - QStringList m_optionalDevicePath
        + NetHotspotController(QObject *parent)
        + void updateData()
        + void updateConfig()
    }

    class NetworkController {
        + static NetworkController* instance()
        + HotspotController* hotspotController()
    }

    class HotspotController {
    }

    NetHotspotController --> NetworkController : uses
    NetworkController --> HotspotController : returns instance
Loading

File-Level Changes

Change Details Files
Replace QTimer-based gating of hotspot configuration updates with an integer counter to better handle rapid network/interface changes and repeated itemChanged signals.
  • Remove QTimer member used to delay/configure hotspot updates and its initialization in the constructor
  • Introduce an integer member m_updateCount initialized to -1 to track remaining deferred update cycles
  • Update the configuration gating condition to check and decrement m_updateCount instead of relying on QTimer::isActive
  • Set m_updateCount to 2 instead of starting the timer when wireless security secrets updates are expected to emit itemChanged twice
  • Invoke updateConfig() directly at the end of updateData() so configuration stays in sync when hotspot data changes
net-view/operation/private/nethotspotcontroller.cpp
net-view/operation/private/nethotspotcontroller.h

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 found 1 issue, and left some high level feedback:

  • The m_updateCount logic in updateConfig() is a bit opaque; consider replacing the magic value 2 with a named constant and adding a short comment describing the intended number of skipped itemChanged events to make the sequencing behavior clearer.
  • In updateConfig(), m_updateCount-- is executed even when !m_userActive, which can drive the counter negative and change behavior once the user becomes active; it may be safer to only decrement when you actually intend to consume an update (e.g., when m_userActive is true).
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The `m_updateCount` logic in `updateConfig()` is a bit opaque; consider replacing the magic value `2` with a named constant and adding a short comment describing the intended number of skipped `itemChanged` events to make the sequencing behavior clearer.
- In `updateConfig()`, `m_updateCount--` is executed even when `!m_userActive`, which can drive the counter negative and change behavior once the user becomes active; it may be safer to only decrement when you actually intend to consume an update (e.g., when `m_userActive` is true).

## Individual Comments

### Comment 1
<location> `net-view/operation/private/nethotspotcontroller.cpp:138-139` </location>
<code_context>
 {
     // 用户不为Active状态时,获取密码需要认证
-    if (!m_userActive || m_updatedTimer->isActive()) {
+    if (!m_userActive || m_updateCount > 0) {
+        m_updateCount--;
         return;
     }
</code_context>

<issue_to_address>
**issue (bug_risk):** Avoid decrementing m_updateCount when the user is inactive; split the conditions.

Previously, when `!m_userActive` the function returned without changing any state. Now, every inactive call decrements `m_updateCount`, which can drive it negative or wrap over time. Please separate the checks so inactivity only returns, and decrement happens only when active, e.g.:

```cpp
if (!m_userActive) {
    return;
}
if (m_updateCount > 0) {
    m_updateCount--;
    return;
}
```
</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.

Changed from QTimer to counter mechanism for handling network
configuration updates
Removed QTimer and replaced with integer counter to track update cycles
Fixed issue where hotspot devices were not properly updated when network
interfaces changed
The previous timer approach could miss updates if network changes
occurred rapidly
New counter mechanism ensures proper sequencing of configuration updates

Log: Fixed hotspot device update issue when network interfaces change

Influence:
1. Test hotspot functionality after network interface changes
2. Verify hotspot configuration updates properly
3. Check that password retrieval works correctly after network changes
4. Test multiple rapid network interface changes
5. Verify user active state handling remains functional

fix: 修复网卡变化时热点设备未更新问题

从 QTimer 改为计数器机制处理网络配置更新
移除 QTimer 并使用整数计数器跟踪更新周期
修复当网络接口变化时热点设备未能正确更新的问题
之前的定时器方法在快速网络变化时可能错过更新
新的计数器机制确保配置更新的正确顺序

Log: 修复网卡变化时热点设备更新问题

Influence:
1. 测试网络接口变化后的热点功能
2. 验证热点配置是否正确更新
3. 检查网络变化后密码获取功能是否正常
4. 测试多次快速网络接口变化
5. 验证用户活跃状态处理保持正常

PMS: BUG-303389
@deepin-ci-robot
Copy link

deepin pr auto review

这段代码的主要改动是将使用 QTimer 进行防抖动处理改为使用计数器 m_updateCount 来过滤重复信号。以下是对这段 diff 的详细审查和改进建议:

1. 代码逻辑与功能分析

  • 改动目的:原代码中,conn->secrets(...) 调用会触发两次 itemChanged 信号。为了防止在这两次信号触发过程中重复执行 updateConfig()(可能涉及耗时操作或UI刷新),原代码使用了 QTimer 进行了 50ms 的防抖动。新代码试图通过设置 m_updateCount = 2,并在每次 onItemChanged 时递减计数,减为 0 时才执行 updateConfig,以此来精确过滤掉这两次多余的信号。

  • 潜在逻辑漏洞

    • 信号丢失风险:目前的逻辑假设 itemChanged 信号严格只会在 secrets 调用后触发且只触发 2 次。如果在 m_updateCount 减为 0 之前(即处于等待第 2 次信号的过程中),系统底层(NetworkManager)因为其他原因(如真实的网络状态变化)再次发出了 itemChanged 信号,onItemChanged 会将其误认为是 secrets 触发的第二次信号,导致计数器归零并执行 updateConfig。此时,真实的网络变化信号被“吞掉”了,没有触发应有的更新逻辑。
    • 计数器溢出/死锁:如果 conn->secrets 触发的信号次数发生变化(例如底层库升级后变为 1 次或 3 次),或者因为某种异常信号没有触发,m_updateCount 可能永远不会归零,导致后续所有的 itemChanged 信号都被忽略,功能失效。

2. 代码质量与可维护性

  • 魔法数字:代码中硬编码了 m_updateCount = 2。这个数字依赖于 NetworkManager 底层的行为,属于“魔法数字”。如果底层行为改变,这里很难排查问题。
  • 状态管理复杂化:使用计数器引入了一个状态变量,使得代码流变得不直观。相比 QTimer 的标准防抖模式,维护一个计数器需要开发者时刻记住当前处于“过滤模式”还是“正常模式”。

3. 代码性能

  • 性能提升有限:虽然去掉了 QTimer 对象的实例化,减少了一点点内存开销,但引入了额外的槽函数调用和整数比较。两者的性能差异在实际应用中几乎可以忽略不计。
  • Qt::QueuedConnection:代码中保留了 Qt::QueuedConnection,这是很好的做法,确保了槽函数在事件循环中执行,避免了重入问题。

4. 代码安全

  • 竞态条件:如果 updateConfig 被其他路径(非 itemChanged)调用,且其中也调用了 conn->secrets,可能会导致 m_updateCount 被重置为 2,从而干扰正在进行的计数逻辑,导致状态混乱。

改进建议

建议 1:保留 QTimer 方案(推荐)

QTimer 的防抖动机制是处理此类高频或重复信号的标准模式,它不依赖于信号触发的具体次数,而是依赖于“在一段时间内没有新信号”这一更稳定的条件。

// 在构造函数中
m_updatedTimer = new QTimer(this);
m_updatedTimer->setSingleShot(true);
m_updatedTimer->setInterval(100); // 适当增加间隔,确保两次信号都能被捕获

// 连接处
connect(m_hotspotController, &HotspotController::itemChanged, this, [this] {
    // 每次信号到来都重启计时器,只有停止触发 100ms 后才会执行 updateConfig
    m_updatedTimer->start(); 
});

// 连接计时器超时信号到更新函数
connect(m_updatedTimer, &QTimer::timeout, this, &NetHotspotController::updateConfig);

建议 2:如果必须使用计数器方案(优化版)

如果确实因为特殊原因必须使用计数器,建议增加保护机制,防止信号丢失或死锁,并添加注释说明原因。

// 头文件
private:
    int m_updateCount = 0;
    bool m_isIgnoringSignals = false; // 标记是否处于忽略信号的特定流程中

// 源文件 updateConfig 中
// ...
} else {
    // conn->secrets会触发两次itemChanged信号,我们需要忽略这两次信号
    // 使用标志位确保只忽略 secrets 调用产生的副作用,不影响其他真实变化
    m_isIgnoringSignals = true;
    m_updateCount = 2; 
    // ... secrets 调用 ...
}

// 源文件 onItemChanged 中
void NetHotspotController::onItemChanged()
{
    if (m_isIgnoringSignals) {
        if (m_updateCount > 0) {
            m_updateCount--;
        } else {
            // 预期的忽略次数已结束,恢复正常状态
            m_isIgnoringSignals = false;
            // 必须显式调用一次更新,因为刚才的信号被消耗了
            updateConfig(); 
        }
    } else {
        // 正常状态下直接更新
        updateConfig();
    }
}

总结
当前的 diff 修改虽然试图解决重复调用问题,但引入了较高的逻辑风险。强烈建议回退到使用 QTimer 的防抖动方案,这是处理此类问题最稳健、最符合 Qt 惯用法的方式。如果必须使用计数器,请务必增加状态标志位(如 m_isIgnoringSignals)来隔离特定的副作用流程,防止误过滤正常的业务信号。

@caixr23 caixr23 requested a review from mhduiy February 6, 2026 09:03
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.

2 participants