Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 17 additions & 12 deletions src/impl/networkmanager/devicemanagerrealize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@
#include "networkdevicebase.h"
#include "networkmanagerprocesser.h"
#include "accesspointproxynm.h"
#include "configsetting.h"

Check warning on line 10 in src/impl/networkmanager/devicemanagerrealize.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: "configsetting.h" not found.
#include "ipmanager.h"
#include "nmnetworkmanager.h"
#include "sessionstatetracker.h"

#include <networkmanagerqt/wirelessdevice.h>

Check warning on line 15 in src/impl/networkmanager/devicemanagerrealize.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <networkmanagerqt/wirelessdevice.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <networkmanagerqt/wireddevice.h>

Check warning on line 16 in src/impl/networkmanager/devicemanagerrealize.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <networkmanagerqt/wireddevice.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <networkmanagerqt/manager.h>
#include <networkmanagerqt/wiredsetting.h>
#include <NetworkManagerQt/Security8021xSetting>
Expand Down Expand Up @@ -846,12 +847,14 @@
wsSetting->setInitialized(keyMgmt != NetworkManager::WirelessSecuritySetting::KeyMgmt::WpaNone && keyMgmt != NetworkManager::WirelessSecuritySetting::KeyMgmt::Unknown);
NMVariantMapMap settingMap = currentConnection->settings()->toMap();
qCDebug(DNC) << "securit changed..." << settingMap;
if (currentConnection->isUnsaved()) {
currentConnection->updateUnsaved(settingMap);
} else {
currentConnection->update(settingMap);
QDBusPendingReply<> reply = currentConnection->save();
reply.waitForFinished();
if (SessionStateTracker::instance()->isSessionActive()) {
if (currentConnection->isUnsaved()) {
currentConnection->updateUnsaved(settingMap);
} else {
currentConnection->update(settingMap);
QDBusPendingReply<> reply = currentConnection->save();
reply.waitForFinished();
}
}
}
QVariantMap options;
Expand Down Expand Up @@ -1009,14 +1012,16 @@
if (activeAp && conn) {
conn->settings()->setTimestamp(QDateTime::currentDateTime());
if (state == NetworkManager::ActiveConnection::Activated && conn->isUnsaved()) {
const NetworkManager::Setting::SettingType settingType[] = { NetworkManager::Setting::Security8021x, NetworkManager::Setting::WirelessSecurity };
for (auto type : settingType) {
NetworkManager::Setting::Ptr setting = conn->settings()->setting(type);
if (setting) {
conn->secrets(setting->name());
if (SessionStateTracker::instance()->isSessionActive()) {
const NetworkManager::Setting::SettingType settingType[] = { NetworkManager::Setting::Security8021x, NetworkManager::Setting::WirelessSecurity };
for (auto type : settingType) {
NetworkManager::Setting::Ptr setting = conn->settings()->setting(type);
if (setting) {
conn->secrets(setting->name());
}
}
conn->save();
}
conn->save();
connect(conn.data(), &NetworkManager::Connection::unsavedChanged, this, [this] {
Q_EMIT activeConnectionChanged();
});
Expand Down
8 changes: 8 additions & 0 deletions src/impl/networkmanager/networkmanagerprocesser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@
#include "devicemanagerrealize.h"
#include "dslcontrollernm.h"
#include "hotspotcontrollernm.h"
#include "networkdevicebase.h"

Check warning on line 8 in src/impl/networkmanager/networkmanagerprocesser.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: "networkdevicebase.h" not found.
#include "networkmanagerprocesser.h"
#include "sessionstatetracker.h"
#include "proxycontrollernm.h"
#include "vpncontrollernm.h"
#include "networkdetails.h"

Check warning on line 13 in src/impl/networkmanager/networkmanagerprocesser.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: "networkdetails.h" not found.
#include "netutils.h"
#include "objectmanager.h"
#include "networkdetailnmrealize.h"
Expand Down Expand Up @@ -80,6 +81,13 @@
connect(NetworkManager::notifier(), &NetworkManager::Notifier::activeConnectionsChanged, this, &NetworkManagerProcesser::onUpdateNetworkDetail);
// 当网络状态发生变化时,也刷新Detail
connect(NetworkManager::notifier(), &NetworkManager::Notifier::statusChanged, this, &NetworkManagerProcesser::onUpdateNetworkDetail);
// 会话从后台切回前台时,本地用户主动刷新网络状态
connect(SessionStateTracker::instance(), &SessionStateTracker::sessionResumed, this, [this] {
if (SessionStateTracker::instance()->isLocalUser()) {
qCDebug(DNC) << "session resumed, refreshing network state";
onUpdateNetworkDetail();
}
});
}

void NetworkManagerProcesser::onDevicesChanged(const QList<QDBusObjectPath> &devices)
Expand Down
136 changes: 136 additions & 0 deletions src/impl/networkmanager/sessionstatetracker.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
// SPDX-FileCopyrightText: 2026 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later
#ifndef SESSIONSTATETRACKER_H
#define SESSIONSTATETRACKER_H

#include <QDBusConnection>

Check warning on line 7 in src/impl/networkmanager/sessionstatetracker.h

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QDBusConnection> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <QDBusInterface>

Check warning on line 8 in src/impl/networkmanager/sessionstatetracker.h

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QDBusInterface> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <QDBusMessage>

Check warning on line 9 in src/impl/networkmanager/sessionstatetracker.h

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QDBusMessage> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <QDBusPendingCallWatcher>

Check warning on line 10 in src/impl/networkmanager/sessionstatetracker.h

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QDBusPendingCallWatcher> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <QDBusPendingReply>

Check warning on line 11 in src/impl/networkmanager/sessionstatetracker.h

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QDBusPendingReply> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <QDBusObjectPath>
#include <QDBusReply>
#include <QDBusVariant>
#include <QDebug>
#include <QObject>
#include <QVariantMap>

class SessionStateTracker : public QObject {
Q_OBJECT
public:
static SessionStateTracker *instance() {
static SessionStateTracker *s_instance = new SessionStateTracker();
return s_instance;
}

bool isSessionActive() const {
return m_userActive;
}

bool isLocalUser() const {
return m_isLocal;
}

private:
SessionStateTracker()
: QObject(nullptr)
, m_userActive(true)
, m_isLocal(false)
{
// Step 1: 异步获取 User.Display(session 路径)
QDBusMessage msg = QDBusMessage::createMethodCall(
"org.freedesktop.login1",
"/org/freedesktop/login1/user/self",
"org.freedesktop.DBus.Properties",
"Get"
);
msg << "org.freedesktop.login1.User" << "Display";
QDBusConnection::systemBus().callWithCallback(msg, this, SLOT(onDisplayReady(QDBusVariant)));
}

~SessionStateTracker() = default;
SessionStateTracker(const SessionStateTracker &) = delete;
SessionStateTracker &operator=(const SessionStateTracker &) = delete;

private slots:
void onDisplayReady(const QDBusVariant &display) {
const QDBusArgument arg = display.variant().value<QDBusArgument>();
QString id;
QDBusObjectPath path;
arg.beginStructure();
arg >> id >> path;
arg.endStructure();

if (path.path().isEmpty()) {
qWarning() << "[SessionStateTracker] Display empty, keep default active";
return;
}

// Step 2: 检查 Remote 属性
QDBusMessage remoteMsg = QDBusMessage::createMethodCall(
"org.freedesktop.login1",
path.path(),
"org.freedesktop.DBus.Properties",
"Get"
);
remoteMsg << "org.freedesktop.login1.Session" << "Remote";
QDBusPendingReply<QDBusVariant> remoteReply = QDBusConnection::systemBus().asyncCall(remoteMsg);
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(remoteReply, this);
connect(watcher, &QDBusPendingCallWatcher::finished, this, [path, this](QDBusPendingCallWatcher *self) {
QDBusPendingReply<QDBusVariant> reply = *self;
bool remote = !reply.isError() && reply.value().variant().toBool();
if (!remote) {
m_isLocal = true;
// Step 3: 监听 Active 变化
QDBusConnection::systemBus().connect(
"org.freedesktop.login1",
path.path(),
"org.freedesktop.DBus.Properties",
"PropertiesChanged",
this,
SLOT(onSessionPropertiesChanged(QString, QVariantMap, QStringList))
);
// 同时读一次初始 Active 状态
QDBusMessage activeMsg = QDBusMessage::createMethodCall(
"org.freedesktop.login1",
path.path(),
"org.freedesktop.DBus.Properties",
"Get"
);
activeMsg << "org.freedesktop.login1.Session" << "Active";
QDBusPendingReply<QDBusVariant> activeReply = QDBusConnection::systemBus().asyncCall(activeMsg);
QDBusPendingCallWatcher *activeWatcher = new QDBusPendingCallWatcher(activeReply, this);
connect(activeWatcher, &QDBusPendingCallWatcher::finished, this, [this](QDBusPendingCallWatcher *sw) {
QDBusPendingReply<QDBusVariant> sr = *sw;
if (!sr.isError()) {
m_userActive = sr.value().variant().toBool();
}
sw->deleteLater();
});
}
self->deleteLater();
});
}

void onSessionPropertiesChanged(const QString &interface, const QVariantMap &properties, const QStringList &) {
if (interface == "org.freedesktop.login1.Session" && properties.contains("Active")) {
m_userActive = properties.value("Active").toBool();
if (m_userActive) {
qWarning() << "[SessionStateTracker] session resumed";
Q_EMIT sessionResumed();
} else {
qWarning() << "[SessionStateTracker] session left";
}
}
}

signals:
void sessionResumed();

private:
bool m_userActive;
bool m_isLocal;
};

#endif // SESSIONSTATETRACKER_H
17 changes: 10 additions & 7 deletions src/impl/serviceinter/deviceinterrealize.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2018 - 2022 UnionTech Software Technology Co., Ltd.
// SPDX-FileCopyrightText: 2018-2026 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later

Expand All @@ -7,6 +7,7 @@
#include "wireddevice.h"
#include "wirelessdevice.h"
#include "accesspointsproxyinter.h"
#include "../networkmanager/sessionstatetracker.h"

#include <QHostAddress>

Expand Down Expand Up @@ -366,14 +367,16 @@ void DeviceInterRealize::onActiveConnectionChanged()
connect(activeConnection.data(), &NetworkManager::ActiveConnection::stateChanged, this, [ activeConnection, this ](NetworkManager::ActiveConnection::State state) {
if (state == NetworkManager::ActiveConnection::State::Activated) {
NetworkManager::Connection::Ptr conn = activeConnection->connection();
const NetworkManager::Setting::SettingType settingType[] = { NetworkManager::Setting::Security8021x, NetworkManager::Setting::WirelessSecurity };
for (auto type : settingType) {
NetworkManager::Setting::Ptr setting = conn->settings()->setting(type);
if (setting) {
conn->secrets(setting->name());
if (SessionStateTracker::instance()->isSessionActive()) {
const NetworkManager::Setting::SettingType settingType[] = { NetworkManager::Setting::Security8021x, NetworkManager::Setting::WirelessSecurity };
for (auto type : settingType) {
NetworkManager::Setting::Ptr setting = conn->settings()->setting(type);
if (setting) {
conn->secrets(setting->name());
}
}
conn->save();
}
conn->save();
connect(conn.data(), &NetworkManager::Connection::unsavedChanged, this, [this] {
Q_EMIT activeConnectionChanged();
});
Expand Down
Loading