Skip to content

Commit ca3f7d9

Browse files
committed
fix: Add automatic VPN connection after network state monitoring
VPN auto-connection is not started by NetworkManager, but by external network services. This adds the VPN startup functionality. Log: Fix VPN not auto-connecting PMS: BUG-287121 fix: 增加监听网络状态后自动连接VPN VPN自动连接并非NetworkManager启动,而是由外部网络服务启动,这里加上启动VPN的功能 Log: 修复VPN没有自动连接
1 parent 05a74fa commit ca3f7d9

File tree

2 files changed

+76
-2
lines changed

2 files changed

+76
-2
lines changed

network-service-plugin/src/system/networkthread.cpp

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,13 @@
66
#include "constants.h"
77
#include "networkdbus.h"
88

9-
#include <NetworkManagerQt/Manager>
109
#include <NetworkManagerQt/Settings>
1110
#include <NetworkManagerQt/VpnConnection>
1211
#include <NetworkManagerQt/WirelessDevice>
12+
#include <NetworkManagerQt/ActiveConnection>
13+
#include <NetworkManagerQt/Connection>
14+
#include <NetworkManagerQt/ConnectionSettings>
15+
#include <NetworkManagerQt/VpnSetting>
1316

1417
#include <QDBusMessage>
1518
#include <QProcess>
@@ -121,6 +124,8 @@ void NetworkThread::init()
121124
auto notifier = NetworkManager::notifier();
122125
connect(notifier, &NetworkManager::Notifier::deviceAdded, this, &NetworkThread::onDeviceAdded);
123126
connect(notifier, &NetworkManager::Notifier::deviceRemoved, this, &NetworkThread::onDeviceRemoved);
127+
connect(notifier, &NetworkManager::Notifier::statusChanged, this, &NetworkThread::onStatusChanged);
128+
onStatusChanged(NetworkManager::status());
124129
}
125130
m_devices.clear();
126131
addDevicesWithRetry();
@@ -370,6 +375,72 @@ QString NetworkThread::disableDevice(NetworkManager::Device::Ptr device)
370375
return QString();
371376
}
372377

378+
void NetworkThread::onStatusChanged(NetworkManager::Status status)
379+
{
380+
if (!m_networkConfig->vpnEnabled())
381+
return;
382+
383+
if (status != NetworkManager::Status::Connected)
384+
return;
385+
386+
QStringList activeConnectionPaths;
387+
NetworkManager::ActiveConnection::List allactiveConnections = NetworkManager::activeConnections();
388+
for (const NetworkManager::ActiveConnection::Ptr &activeConnection : allactiveConnections) {
389+
if (activeConnection->connection().isNull())
390+
continue;
391+
392+
if (activeConnection->state() == NetworkManager::ActiveConnection::State::Activated
393+
|| activeConnection->state() == NetworkManager::ActiveConnection::State::Activating)
394+
activeConnectionPaths << activeConnection->connection()->path();
395+
}
396+
QMap<QString, NetworkManager::Connection::Ptr> candidateVpns;
397+
// 检查到网络状态为连接成功后,检查本地是否存在自动连接的VPN,如果存在,就让它连接
398+
NetworkManager::Connection::List allConnections = NetworkManager::listConnections();
399+
for (const NetworkManager::Connection::Ptr &conn : allConnections) {
400+
// 过滤掉正在连接的或者已经连接成功的
401+
if (activeConnectionPaths.contains(conn->path()))
402+
continue;
403+
404+
// 这里只查找设置了自动连接的
405+
if (!conn->settings()->autoconnect())
406+
continue;
407+
408+
// 查找VPN的连接方式
409+
NetworkManager::ConnectionSettings::ConnectionType type = conn->settings()->connectionType();
410+
if (type == NetworkManager::ConnectionSettings::ConnectionType::Vpn) {
411+
NetworkManager::VpnSetting::Ptr setting = conn->settings()->setting(NetworkManager::Setting::SettingType::Vpn).dynamicCast<NetworkManager::VpnSetting>();
412+
if (setting.isNull())
413+
continue;
414+
415+
QString serviceType = setting->serviceType();
416+
if (candidateVpns.contains(serviceType)) {
417+
// 优先使用最后一次连接成功的连接
418+
const NetworkManager::Connection::Ptr &lastSetting = candidateVpns[serviceType];
419+
if (lastSetting->settings()->timestamp() < conn->settings()->timestamp())
420+
candidateVpns[serviceType] = conn;
421+
} else {
422+
candidateVpns[serviceType] = conn;
423+
}
424+
}
425+
}
426+
for (auto it = candidateVpns.begin(); it != candidateVpns.end(); it++) {
427+
const NetworkManager::Connection::Ptr &connection = it.value();
428+
QDBusPendingReply<QDBusObjectPath> reply = NetworkManager::activateConnection(connection->path(), "/", "/");
429+
// 使用 Watcher 监听异步结果(推荐做法)
430+
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this);
431+
QString connection_name = connection->name();
432+
connect(watcher, &QDBusPendingCallWatcher::finished, watcher, &QDBusPendingCallWatcher::deleteLater);
433+
connect(watcher, &QDBusPendingCallWatcher::finished, this, [this, connection_name](QDBusPendingCallWatcher *watcher) {
434+
QDBusPendingReply<QDBusObjectPath> reply = *watcher;
435+
if (reply.isError()) {
436+
qWarning() << "Failed to connect VPN:" << connection_name << "Reason:" << reply.error().message();
437+
} else {
438+
qDebug() << "VPN connection initiated successfully:" << connection_name;
439+
}
440+
});
441+
}
442+
}
443+
373444
bool NetworkThread::airplaneWifiEnabled()
374445
{
375446
QDBusMessage msg = QDBusMessage::createMethodCall("org.deepin.dde.AirplaneMode1", "/org/deepin/dde/AirplaneMode1", "org.freedesktop.DBus.Properties", "Get");

network-service-plugin/src/system/networkthread.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
// SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd.
1+
// SPDX-FileCopyrightText: 2025-2026 UnionTech Software Technology Co., Ltd.
22
//
33
// SPDX-License-Identifier: GPL-3.0-or-later
44
#ifndef NETWORKTHREAD_H
55
#define NETWORKTHREAD_H
66

77
#include "networkenabledconfig.h"
88

9+
#include <NetworkManagerQt/Manager>
910
#include <NetworkManagerQt/Device>
1011

1112
#include <QDBusConnection>
@@ -50,6 +51,8 @@ protected Q_SLOTS:
5051
QString enableDevice(NetworkManager::Device::Ptr device);
5152
QString disableDevice(NetworkManager::Device::Ptr device);
5253

54+
void onStatusChanged(NetworkManager::Status status);
55+
5356
protected:
5457
void disableVpn();
5558
bool airplaneWifiEnabled();

0 commit comments

Comments
 (0)