Skip to content

Conversation

@caixr23
Copy link
Contributor

@caixr23 caixr23 commented Dec 25, 2025

  1. Added child move functionality with proper signal emissions for model
    synchronization
  2. Implemented Net_noUseMoveItem flag to control move behavior in
    different contexts
  3. Enhanced wireless connection handling to use move operations instead
    of remove/add for better performance
  4. Improved NetworkSecretAgent with client connection waiting mechanism
    and timeout handling
  5. Added D-Bus configuration files for proper service registration

Log: Enhanced network item management with move operations and improved
secret agent reliability

Influence:

  1. Test wireless network item movement between "Mine" and "Other"
    sections
  2. Verify network list updates correctly when connections change
  3. Test secret agent password dialog behavior with and without client
    connections
  4. Validate D-Bus service registration and accessibility
  5. Check network model synchronization during item operations

feat: 添加项移动支持和密钥代理改进

  1. 添加子项移动功能,包含正确的信号发射以实现模型同步
  2. 实现 Net_noUseMoveItem 标志以在不同上下文中控制移动行为
  3. 增强无线连接处理,使用移动操作替代删除/添加以提高性能
  4. 改进 NetworkSecretAgent,添加客户端连接等待机制和超时处理
  5. 添加 D-Bus 配置文件以支持正确的服务注册

Log: 增强网络项管理,支持移动操作并改进密钥代理可靠性

Influence:

  1. 测试无线网络项在"我的"和"其他"部分之间的移动
  2. 验证连接变更时网络列表的正确更新
  3. 测试有客户端连接和无客户端连接时的密钥代理密码对话框行为
  4. 验证 D-Bus 服务注册和可访问性
  5. 检查项操作期间网络模型的同步情况

PMS: BUG-307099 BUG-336865

Summary by Sourcery

Introduce item move support in the network view model and improve the network secret agent’s handling of wireless password requests and service registration.

New Features:

  • Add child move support and corresponding model move notifications for network items to keep views in sync when items change parent.

Enhancements:

  • Gate item move behavior behind a new Net_noUseMoveItem flag and apply it when moving wireless connections between "Mine" and "Other" groups.
  • Refine NetworkSecretAgent to wait briefly for panel clients before falling back to an auth dialog when requesting wireless secrets, using an internal timer and request state tracking.
  • Clean up NetManagerThreadPrivate accessors and internal mappings for better const-correctness and style.

Deployment:

  • Add D-Bus configuration files for the org.deepin.dde.Network1 service to define ownership and call permissions on the bus.

@sourcery-ai
Copy link

sourcery-ai bot commented Dec 25, 2025

Reviewer's Guide

Introduces move semantics for network items to keep the Qt item model in sync when wireless connections move between sections, adds a flag to optionally fall back to remove/add behavior, refactors the NetworkSecretAgent to wait briefly for panel clients before spawning a dialog, and registers the Network1 D-Bus service with appropriate bus policies.

Sequence diagram for wireless secrets handling with client wait and timeout

sequenceDiagram
    actor user as User
    participant nm as NetworkManager
    participant agent as NetworkSecretAgent
    participant panel as PanelClient
    participant dialog as AuthDialog

    user->>nm: RequestWirelessConnection
    nm->>agent: GetSecrets(connection type 802_11_wireless)
    agent->>agent: askPasswords
    alt noPanelClients
        agent->>agent: set request.status = WaitClient
        agent->>agent: m_waitClientTimer.start(5000)
        alt panelConnectsBeforeTimeout
            panel-->>agent: newConnection
            agent->>agent: m_waitClientTimer.stop()
            agent->>agent: newConnectionHandler
            agent->>agent: waitClientTimeOut
            agent->>agent: runAuthDialog(request)
            agent-->>panel: write requestSecrets
        else timeoutWithoutPanel
            agent-->>agent: waitClientTimeOut (QTimer timeout)
            agent->>agent: runAuthDialog(request)
            agent->>agent: set request.status = WaitDialog
            agent->>dialog: start NMSecretDialogBin
            dialog-->>agent: secretsResult or timeout
        end
    else hasPanelClientsInitially
        agent->>agent: runAuthDialog(request)
        agent-->>panel: write requestSecrets
    end
    agent-->>nm: ReturnSecrets
    nm-->>user: ConnectionEstablished
Loading

Class diagram for item move support and secret agent changes

classDiagram
    class NetItem {
        +void childAdded(NetItem child)
        +void childAboutToBeRemoved(NetItem parent, int pos)
        +void childRemoved(NetItem child)
        +void childAboutToBeMoved(NetItem parent, int pos, NetItem newParent, int newPos)
        +void childMoved(NetItem child)
        +void childrenChanged()
    }

    class NetItemPrivate {
        +bool addChild(NetItemPrivate child, int index)
        +void removeChild(NetItemPrivate child)
        +void moveChild(NetItemPrivate child, NetItemPrivate newParent)
        +void updatename(QString name)
        +void updateid(QString id)
        -NetItem m_item
        -QVector~NetItem~ m_children
        -NetItem m_parent
    }

    class NetModel {
        +NetModel(QObject parent)
        +QModelIndex index(NetItem item)
        +QModelIndex parent(QModelIndex index)
        +int rowCount(QModelIndex parent)
        +int columnCount(QModelIndex parent)
        +QVariant data(QModelIndex index, int role)
        +void connectObject(NetItem obj)
        +void disconnectObject(NetItem obj)
        #void updateObject()
        #void aboutToAddObject(NetItem parent, int pos)
        #void addObject(NetItem child)
        #void aboutToRemoveObject(NetItem parent, int pos)
        #void removeObject(NetItem child)
        #void aboutToBeMoveObject(NetItem parent, int pos, NetItem newParent, int newPos)
        #void moveObject(NetItem child)
        -NetItem m_treeRoot
    }

    class NetType {
        <<enum>> NetManagerFlag
        NetManagerFlag Net_Device
        NetManagerFlag Net_VPN
        NetManagerFlag Net_SysProxy
        NetManagerFlag Net_Airplane
        NetManagerFlag Net_AirplaneTips
        NetManagerFlag Net_VPNTips
        NetManagerFlag Net_UseSecretAgent
        NetManagerFlag Net_CheckPortal
        NetManagerFlag Net_autoUpdateHiddenConfig
        NetManagerFlag Net_noUseMoveItem
        NetManagerFlag Net_DockFlags
        NetManagerFlag Net_LockFlags
        NetManagerFlag Net_GreeterFlags
        NetManagerFlag Net_DccFlags
    }

    class NetManagerThreadPrivate {
        +static QVariantMap CheckParamValid(QVariantMap param)
        +static bool CheckPasswordValid(QString key, QString password)
        +bool NetCheckAvailable() const
        +bool AirplaneModeEnabled() const
        +NetType.NetManagerFlags flags() const
        +void setEnabled(bool enabled)
        +void setAutoScanInterval(int ms)
        -NetType.NetManagerFlags m_flags
        -bool m_netCheckAvailable
        -bool m_airplaneModeEnabled
        -QMap~NetworkDetails*, QString~ m_detailsItemsMap
    }

    class NetWirelessDeviceItemPrivate {
        +void updatehasConnection(bool hasConnection)
        +NetItemPrivate getParentPrivate()
        +QString id()
    }

    class NetManagerPrivate {
        +void onDataChanged(int dataType, QString id, QVariant value)
        -NetManagerThreadPrivate m_managerThread
    }

    class SecretsRequest {
        <<enum>> Type
        Type GetSecrets
        Type SaveSecrets
        Type DeleteSecrets
        <<enum>> Status
        Status Begin
        Status WaitClient
        Status WaitDialog
        Status End
        +SecretsRequest(Type type)
        +Type type
        +Status status
        +QVariantMap connection
        +QString callId
        +QByteArray inputCache
        +QProcess process
    }

    class NetworkSecretAgent {
        +NetworkSecretAgent(QObject parent)
        +void askPasswords(SecretsRequest request, QStringList hints)
        +void newConnectionHandler()
        +void disconnectedHandler()
        +void authDialogFinished(int exitCode, QProcess.ExitStatus status)
        +void authDialogReadOutput()
        +void authDialogReadError()
        +void authDialogError(QProcess.ProcessError error)
        +void authDialogStarted()
        +void authDialogReadAllOutput(bool isEnd)
        +void doSecretsResult(QString callId, QByteArray data, bool isEnd)
        +void runAuthDialog(SecretsRequest request)
        +void waitClientTimeOut()
        -QString nextId()
        -int m_callNextId
        -QList~SecretsRequest~ m_calls
        -QLocalServer m_server
        -QList~QLocalSocket*~ m_clients
        -QByteArray m_lastData
        -SecretService m_secretService
        -QTimer m_waitClientTimer
    }

    NetItemPrivate --> NetItem : owns m_item
    NetItem --> NetItemPrivate : uses private
    NetModel --> NetItem : observes signals
    NetManagerPrivate --> NetManagerThreadPrivate : uses m_managerThread
    NetManagerThreadPrivate --> NetType : uses NetManagerFlag
    NetworkSecretAgent --> SecretsRequest : manages
    NetworkSecretAgent --> QLocalServer : uses
    NetworkSecretAgent --> QLocalSocket : manages clients
    NetWirelessDeviceItemPrivate --> NetItemPrivate : inherits
Loading

File-Level Changes

Change Details Files
Add child move support in NetItem/NetModel and use it when wireless APs move between Mine and Other sections.
  • Introduce NetItemPrivate::moveChild to reparent children while emitting childAboutToBeMoved/childMoved and childrenChanged signals for both old and new parents.
  • Extend NetItem with childAboutToBeMoved/childMoved signals and connect them in NetModel to new aboutToBeMoveObject/moveObject slots that wrap beginMoveRows/endMoveRows.
  • Update NetModel slot names (AboutToAdd/RemoveObject → aboutToAdd/RemoveObject) and keep connections consistent.
  • Use moveChild for wireless items when AvailableConnectionsChanged moves APs between Mine and Other, while still handling add/remove for empty parents.
net-view/operation/private/netitemprivate.cpp
net-view/operation/private/netitemprivate.h
net-view/window/private/netmodel.cpp
net-view/window/private/netmodel.h
net-view/operation/netitem.h
net-view/operation/netmanager.cpp
Introduce Net_noUseMoveItem flag to control whether move operations are used in different UI contexts.
  • Add Net_noUseMoveItem flag to NetType::NetManagerFlags and include it in Net_DccFlags while removing monitoring-related flags from Net_GreeterFlags.
  • Expose NetManagerThreadPrivate::flags() as a const accessor and use it in NetManagerPrivate::onDataChanged to decide between moveChild and removeChild when rearranging wireless items.
  • Make NetCheckAvailable and AirplaneModeEnabled const accessors and clean up includes/formatting in NetManagerThreadPrivate.
net-view/operation/nettype.h
net-view/operation/private/netmanagerthreadprivate.h
net-view/operation/netmanager.cpp
Refactor NetworkSecretAgent to wait for client connections before deciding whether to send a panel request or spawn the password dialog, with a timeout fallback.
  • Extend SecretsRequest::Status with WaitClient and add a QTimer m_waitClientTimer configured as a single-shot 5s timer in NetworkSecretAgent.
  • Change askPasswords so that for wireless connections with no clients yet, it marks the request as WaitClient and starts the timer; otherwise it delegates to a new runAuthDialog helper.
  • Implement runAuthDialog to set status to WaitDialog and either write requestSecrets to connected clients (wireless) or start the NMSecretDialog process with all existing signal/timeout wiring.
  • On new QLocalServer connections, stop the wait timer, append the client, and call waitClientTimeOut to process any pending WaitClient request immediately.
  • Implement waitClientTimeOut to scan m_calls for a WaitClient request and invoke runAuthDialog as a timeout or when a client arrives.
network-service-plugin/src/session/networksecretagent.cpp
network-service-plugin/src/session/networksecretagent.h
Register org.deepin.dde.Network1 D-Bus service with system and session bus policies.
  • Add org.deepin.dde.Network1.conf for the session bus, allowing root to own/send to the service and all users to send to it.
  • Add a corresponding org.deepin.dde.Network1.conf for the system bus with the same policy structure.
network-service-plugin/src/session/org.deepin.dde.Network1.conf
network-service-plugin/src/system/org.deepin.dde.Network1.conf

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 2 issues, and left some high level feedback:

  • In NetworkSecretAgent::waitClientTimeOut(), the iterator is never advanced inside the loop when request.status != SecretsRequest::WaitClient, which will lead to an infinite loop; make sure to increment the iterator (or use a range-for) so the function can safely scan all requests.
  • NetworkSecretAgent::waitClientTimeOut() currently breaks after handling the first SecretsRequest in WaitClient state, leaving any additional waiting requests unprocessed with no timer running; consider iterating over and handling all WaitClient entries or otherwise ensuring they will be processed later.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In NetworkSecretAgent::waitClientTimeOut(), the iterator is never advanced inside the loop when request.status != SecretsRequest::WaitClient, which will lead to an infinite loop; make sure to increment the iterator (or use a range-for) so the function can safely scan all requests.
- NetworkSecretAgent::waitClientTimeOut() currently breaks after handling the first SecretsRequest in WaitClient state, leaving any additional waiting requests unprocessed with no timer running; consider iterating over and handling all WaitClient entries or otherwise ensuring they will be processed later.

## Individual Comments

### Comment 1
<location> `network-service-plugin/src/session/networksecretagent.cpp:559-561` </location>
<code_context>
+    }
+}
+
+void NetworkSecretAgent::waitClientTimeOut()
+{
+    for (auto it = m_calls.begin(); it != m_calls.end();) {
+        SecretsRequest &request = *it;
+        if (request.status == SecretsRequest::WaitClient) {
</code_context>

<issue_to_address>
**issue (bug_risk):** waitClientTimeOut iterates m_calls without advancing the iterator, causing an infinite loop

The loop never increments `it`, so any non-`WaitClient` entry will cause an infinite loop and hang the thread. Even when a `WaitClient` is found, earlier non-matching entries would still loop forever. This should either increment the iterator in the `for` header:

```cpp
for (auto it = m_calls.begin(); it != m_calls.end(); ++it) {
    SecretsRequest &request = *it;
    if (request.status == SecretsRequest::WaitClient) {
        runAuthDialog(request);
        break;
    }
}
```

or use a range-based `for` if you don’t need the iterator itself.
</issue_to_address>

### Comment 2
<location> `network-service-plugin/src/session/networksecretagent.cpp:210-213` </location>
<code_context>
-        for (auto &&client : m_clients) {
-            client->write("\nrequestSecrets:" + reqJSON.toUtf8() + "\n");
-        }
+    if (connType == "802-11-wireless" && m_clients.isEmpty()) {
+        // 启动定时器,等待
+        request.status = SecretsRequest::WaitClient;
+        m_waitClientTimer->start();
     } else {
-        // run auth dialog
</code_context>

<issue_to_address>
**suggestion (bug_risk):** A single shared wait timer for all wireless requests can lead to surprising behavior when multiple requests are pending

Using a single `m_waitClientTimer` for all wireless `SecretsRequest`s means a new request can reset the timer while a previous one is still in `WaitClient`. Since `waitClientTimeOut` advances only one request at a time, earlier requests can be delayed or starved. Consider either tracking wait state per `SecretsRequest` (own timer or timestamp) or enforcing that only one wireless request may be in `WaitClient` at a time and rejecting/queuing additional ones accordingly.

Suggested implementation:

```cpp
    request.inputCache = reqJSON.toUtf8();
    // For wireless connections, only allow one request to be in WaitClient state at a time.
    // If m_waitClientTimer is already active, we skip the wait and immediately fall back
    // to the normal handling path to avoid starving earlier pending requests.
    if (connType == "802-11-wireless" && m_clients.isEmpty() && !m_waitClientTimer->isActive()) {
        // 启动定时器,等待
        request.status = SecretsRequest::WaitClient;
        m_waitClientTimer->start();
    } else {

```

If you prefer true queuing (i.e. multiple wireless requests all going through a client-wait phase in order), you will need to:
1. Track pending `SecretsRequest`s in a queue structure instead of relying solely on a single timer.
2. Adjust the `waitClientTimeOut` handler (or equivalent) to pop the next queued wireless request and move it out of `WaitClient` state, starting the timer again if more remain.
3. Optionally, add a helper such as `bool NetworkSecretAgent::hasWaitingWirelessRequest() const` and base the condition on that instead of `m_waitClientTimer->isActive()`.
The current change implements the "only one wireless request may be in WaitClient at a time" policy with minimal impact: additional wireless requests will follow the existing non-wait path while a wait is already in progress.
</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.

Comment on lines +210 to +213
if (connType == "802-11-wireless" && m_clients.isEmpty()) {
// 启动定时器,等待
request.status = SecretsRequest::WaitClient;
m_waitClientTimer->start();
Copy link

Choose a reason for hiding this comment

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

suggestion (bug_risk): A single shared wait timer for all wireless requests can lead to surprising behavior when multiple requests are pending

Using a single m_waitClientTimer for all wireless SecretsRequests means a new request can reset the timer while a previous one is still in WaitClient. Since waitClientTimeOut advances only one request at a time, earlier requests can be delayed or starved. Consider either tracking wait state per SecretsRequest (own timer or timestamp) or enforcing that only one wireless request may be in WaitClient at a time and rejecting/queuing additional ones accordingly.

Suggested implementation:

    request.inputCache = reqJSON.toUtf8();
    // For wireless connections, only allow one request to be in WaitClient state at a time.
    // If m_waitClientTimer is already active, we skip the wait and immediately fall back
    // to the normal handling path to avoid starving earlier pending requests.
    if (connType == "802-11-wireless" && m_clients.isEmpty() && !m_waitClientTimer->isActive()) {
        // 启动定时器,等待
        request.status = SecretsRequest::WaitClient;
        m_waitClientTimer->start();
    } else {

If you prefer true queuing (i.e. multiple wireless requests all going through a client-wait phase in order), you will need to:

  1. Track pending SecretsRequests in a queue structure instead of relying solely on a single timer.
  2. Adjust the waitClientTimeOut handler (or equivalent) to pop the next queued wireless request and move it out of WaitClient state, starting the timer again if more remain.
  3. Optionally, add a helper such as bool NetworkSecretAgent::hasWaitingWirelessRequest() const and base the condition on that instead of m_waitClientTimer->isActive().
    The current change implements the "only one wireless request may be in WaitClient at a time" policy with minimal impact: additional wireless requests will follow the existing non-wait path while a wait is already in progress.

@caixr23 caixr23 force-pushed the master branch 4 times, most recently from 33161af to 7e79f48 Compare December 25, 2025 09:30
@deepin-bot
Copy link
Contributor

deepin-bot bot commented Dec 25, 2025

TAG Bot

New tag: 2.0.78
DISTRIBUTION: unstable
Suggest: synchronizing this PR through rebase #466

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR enhances network item management by adding move operations for wireless network items and improving the secret agent's reliability. The changes enable wireless network items to be moved between "Mine" and "Other" sections without remove/add operations, and add a client waiting mechanism to the NetworkSecretAgent for better password dialog handling.

Key Changes

  • Added child move functionality with proper model synchronization through new signals (childAboutToBeMoved, childMoved) and a move flag to filter out intermediate add/remove signals
  • Implemented a 5-second client wait mechanism in NetworkSecretAgent before falling back to auth dialogs for wireless password requests
  • Updated D-Bus service configuration from org.deepin.service.SessionNetwork/SystemNetwork to org.deepin.dde.Network1

Reviewed changes

Copilot reviewed 12 out of 13 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
network-service-plugin/src/system/org.deepin.dde.Network1.conf Updated D-Bus service name from org.deepin.service.SessionNetwork to org.deepin.dde.Network1
network-service-plugin/src/session/org.deepin.dde.Network1.conf Added new session D-Bus configuration file for org.deepin.dde.Network1 service
network-service-plugin/src/session/networksecretagent.h Added WaitClient status enum value and timer member for client waiting mechanism
network-service-plugin/src/session/networksecretagent.cpp Implemented client waiting logic with timer and refactored auth dialog launching
network-service-plugin/CMakeLists.txt Updated D-Bus config file installation paths to match new service names
net-view/window/private/netmodel.h Added move-related slots and moving flag to support item move operations
net-view/window/private/netmodel.cpp Implemented move signal handlers with flag-based filtering of intermediate signals
net-view/operation/private/netmanagerthreadprivate.h Code style improvements (const correctness and formatting)
net-view/operation/private/netitemprivate.h Added moveChild method declaration and changed removeChild return type to bool
net-view/operation/private/netitemprivate.cpp Implemented moveChild functionality and refactored getChildIndex/removeChild
net-view/operation/netmanager.cpp Replaced remove/add pattern with moveChild calls for wireless connection changes
net-view/operation/netitem.h Added childAboutToBeMoved and childMoved signals
debian/deepin-service-plugin-network.install Changed to wildcard pattern for D-Bus configuration file installation

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

}
auto it = std::find(m_children.begin(), m_children.end(), child);
if (it == m_children.end()) {
return false;
Copy link

Copilot AI Dec 29, 2025

Choose a reason for hiding this comment

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

The function returns false (a boolean) when the child is not found, but the return type is int. This should return -1 instead to match the return type and the subsequent ternary expression.

Suggested change
return false;
return -1;

Copilot uses AI. Check for mistakes.
Comment on lines +158 to +157
Q_EMIT m_item->childAboutToBeMoved(m_item, it - m_children.begin(), newParent->item(), newParent->getChildrenNumber());
removeChild(child);
newParent->addChild(child);
Copy link

Copilot AI Dec 29, 2025

Choose a reason for hiding this comment

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

The moveChild function calls removeChild(child) and newParent->addChild(child) which will emit their own add/remove signals. This means that in addition to the move signals (childAboutToBeMoved and childMoved), the old parent will also emit childAboutToBeRemoved and childRemoved, while the new parent will emit childAboutToBeAdded and childAdded. According to the comment in netitem.h line 66, these add/remove signals should be filtered out during moves, but this design is error-prone and could lead to incorrect model updates if not handled carefully in all consumers.

Suggested change
Q_EMIT m_item->childAboutToBeMoved(m_item, it - m_children.begin(), newParent->item(), newParent->getChildrenNumber());
removeChild(child);
newParent->addChild(child);
const int oldIndex = static_cast<int>(it - m_children.begin());
const int newIndex = newParent->getChildrenNumber();
Q_EMIT m_item->childAboutToBeMoved(m_item, oldIndex, newParent->item(), newIndex);
// Perform the move without emitting add/remove signals.
m_children.erase(it);
child->m_parent = newParent->item();
newParent->m_children.push_back(child->item());
// Notify both parents that their children collections changed.
Q_EMIT m_item->childrenChanged();
Q_EMIT newParent->item()->childrenChanged();

Copilot uses AI. Check for mistakes.
if (connType == "802-11-wireless" && m_clients.isEmpty()) {
// 启动定时器,等待
request.status = SecretsRequest::WaitClient;
m_waitClientTimer->start();
Copy link

Copilot AI Dec 29, 2025

Choose a reason for hiding this comment

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

The single timer m_waitClientTimer is shared for all wireless secret requests. If multiple wireless secret requests arrive while waiting for clients, calling start() on line 213 for a subsequent request will restart the timer, potentially causing the first request to wait longer than 5 seconds or the wrong request to be processed when waitClientTimeOut() is called. Consider using per-request timers or tracking multiple waiting requests properly.

Suggested change
m_waitClientTimer->start();
if (!m_waitClientTimer->isActive()) {
m_waitClientTimer->start();
}

Copilot uses AI. Check for mistakes.
@deepin-ci-robot
Copy link

deepin pr auto review

我来对这个git diff进行详细的代码审查:

  1. 代码结构和逻辑改进:
// netitemprivate.cpp 中的改进
int NetItemPrivate::getChildIndex(const NetItem *child) const
{
    auto it = std::find(m_children.begin(), m_children.end(), child);
    return it == m_children.end() ? -1 : it - m_children.begin();
}

优点:

  • 使用STL算法替代手动循环,代码更简洁
  • 返回值计算更准确
  • 性能略有提升
  1. 安全性改进:
// netitemprivate.cpp 中的 moveChild 函数
bool NetItemPrivate::moveChild(NetItemPrivate *child, NetItemPrivate *newParent)
{
    if (!child || !newParent || child->m_parent == newParent->item()) {
        return false;
    }
    // ...
}

优点:

  • 增加了空指针检查
  • 避免了无效的移动操作
  • 返回值可以用于错误处理
  1. 信号处理改进:
// netmodel.cpp 中的移动操作处理
void NetModel::aboutToBeMoveObject(const NetItem *parent, int pos, const NetItem *newParent, int newPos)
{
    m_moving = true;
    QModelIndex i = index(parent);
    QModelIndex newI = index(newParent);
    beginMoveRows(i, pos, pos, newI, newPos);
}

优点:

  • 增加了移动状态标记
  • 正确处理了模型更新
  • 避免了重复触发更新
  1. 性能优化:
// networksecretagent.cpp 中的改进
void NetworkSecretAgent::waitClientTimeOut()
{
    auto it = std::find_if(m_calls.begin(), m_calls.end(), [](const SecretsRequest &req) {
        return req.status == SecretsRequest::WaitClient;
    });
    // ...
}

优点:

  • 使用lambda表达式提高代码可读性
  • 使用STL算法提高效率
  • 添加了超时处理机制
  1. 建议改进:

  2. 在 NetItemPrivate::moveChild 中,建议添加日志记录:

bool NetItemPrivate::moveChild(NetItemPrivate *child, NetItemPrivate *newParent)
{
    if (!child || !newParent || child->m_parent == newParent->item()) {
        qWarning() << "Invalid move operation";
        return false;
    }
    // ...
}
  1. 在 NetworkSecretAgent 中,建议增加错误处理:
void NetworkSecretAgent::runAuthDialog(SecretsRequest &request)
{
    if (request.status != SecretsRequest::WaitClient) {
        qWarning() << "Invalid request status";
        return;
    }
    // ...
}
  1. 在网络配置文件变更时,建议添加版本控制:
# CMakeLists.txt
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/system/org.deepin.dde.Network1.conf 
        DESTINATION share/dbus-1/system.d/
        RENAME org.deepin.dde.Network1.conf.${PROJECT_VERSION})
  1. 安全性建议:

  2. 在处理网络连接时,建议添加权限检查:

bool NetItemPrivate::moveChild(NetItemPrivate *child, NetItemPrivate *newParent)
{
    if (!checkPermission()) {
        qWarning() << "Permission denied";
        return false;
    }
    // ...
}
  1. 在处理密码请求时,建议添加加密:
void NetworkSecretAgent::askPasswords(SecretsRequest &request, const QStringList &fields)
{
    // 加密敏感数据
    QString encryptedReq = encryptRequest(reqJSON);
    // ...
}
  1. 总体评价:

这些改进主要围绕:

  • 代码结构优化
  • 错误处理完善
  • 性能提升
  • 安全性增强

建议在后续版本中:

  1. 添加更多的单元测试
  2. 增加日志记录
  3. 完善错误处理机制
  4. 加强安全性检查
  5. 优化性能关键路径

这些改动整体上是积极的,提高了代码质量和可维护性。

@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

1. Added child move functionality with proper signal emissions for model
synchronization
2. Implemented Net_noUseMoveItem flag to control move behavior in
different contexts
3. Enhanced wireless connection handling to use move operations instead
of remove/add for better performance
4. Improved NetworkSecretAgent with client connection waiting mechanism
and timeout handling
5. Added D-Bus configuration files for proper service registration

Log: Enhanced network item management with move operations and improved
secret agent reliability

Influence:
1. Test wireless network item movement between "Mine" and "Other"
sections
2. Verify network list updates correctly when connections change
3. Test secret agent password dialog behavior with and without client
connections
4. Validate D-Bus service registration and accessibility
5. Check network model synchronization during item operations

feat: 添加项移动支持和密钥代理改进

1. 添加子项移动功能,包含正确的信号发射以实现模型同步
2. 实现 Net_noUseMoveItem 标志以在不同上下文中控制移动行为
3. 增强无线连接处理,使用移动操作替代删除/添加以提高性能
4. 改进 NetworkSecretAgent,添加客户端连接等待机制和超时处理
5. 添加 D-Bus 配置文件以支持正确的服务注册

Log: 增强网络项管理,支持移动操作并改进密钥代理可靠性

Influence:
1. 测试无线网络项在"我的"和"其他"部分之间的移动
2. 验证连接变更时网络列表的正确更新
3. 测试有客户端连接和无客户端连接时的密钥代理密码对话框行为
4. 验证 D-Bus 服务注册和可访问性
5. 检查项操作期间网络模型的同步情况

PMS: BUG-307099 BUG-336865
@caixr23 caixr23 merged commit c96e984 into linuxdeepin:master Dec 30, 2025
15 of 17 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