|
6 | 6 | #include "constants.h" |
7 | 7 | #include "networkdbus.h" |
8 | 8 |
|
9 | | -#include <NetworkManagerQt/Manager> |
10 | 9 | #include <NetworkManagerQt/Settings> |
11 | 10 | #include <NetworkManagerQt/VpnConnection> |
12 | 11 | #include <NetworkManagerQt/WirelessDevice> |
| 12 | +#include <NetworkManagerQt/ActiveConnection> |
| 13 | +#include <NetworkManagerQt/Connection> |
| 14 | +#include <NetworkManagerQt/ConnectionSettings> |
| 15 | +#include <NetworkManagerQt/VpnSetting> |
13 | 16 |
|
14 | 17 | #include <QDBusMessage> |
15 | 18 | #include <QProcess> |
@@ -121,6 +124,8 @@ void NetworkThread::init() |
121 | 124 | auto notifier = NetworkManager::notifier(); |
122 | 125 | connect(notifier, &NetworkManager::Notifier::deviceAdded, this, &NetworkThread::onDeviceAdded); |
123 | 126 | connect(notifier, &NetworkManager::Notifier::deviceRemoved, this, &NetworkThread::onDeviceRemoved); |
| 127 | + connect(notifier, &NetworkManager::Notifier::statusChanged, this, &NetworkThread::onStatusChanged); |
| 128 | + onStatusChanged(NetworkManager::status()); |
124 | 129 | } |
125 | 130 | m_devices.clear(); |
126 | 131 | addDevicesWithRetry(); |
@@ -370,6 +375,72 @@ QString NetworkThread::disableDevice(NetworkManager::Device::Ptr device) |
370 | 375 | return QString(); |
371 | 376 | } |
372 | 377 |
|
| 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 | + |
373 | 444 | bool NetworkThread::airplaneWifiEnabled() |
374 | 445 | { |
375 | 446 | QDBusMessage msg = QDBusMessage::createMethodCall("org.deepin.dde.AirplaneMode1", "/org/deepin/dde/AirplaneMode1", "org.freedesktop.DBus.Properties", "Get"); |
|
0 commit comments