diff --git a/kded/notification.cpp b/kded/notification.cpp index 130fe8a4..9e9f3b36 100644 --- a/kded/notification.cpp +++ b/kded/notification.cpp @@ -1,597 +1,596 @@ /* Copyright 2009 Will Stephenson Copyright 2013 by Daniel Nicoletti Copyright 2013 Lukas Tinkl Copyright 2013 Jan Grulich This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "debug.h" #include "notification.h" #include #include #include #include -#include #include #include #include Notification::Notification(QObject *parent) : QObject(parent) { // devices for (const NetworkManager::Device::Ptr &device : NetworkManager::networkInterfaces()) { addDevice(device); } connect(NetworkManager::notifier(), &NetworkManager::Notifier::deviceAdded, this, &Notification::deviceAdded); // connections for (const NetworkManager::ActiveConnection::Ptr &ac : NetworkManager::activeConnections()) { addActiveConnection(ac); } connect(NetworkManager::notifier(), &NetworkManager::Notifier::activeConnectionAdded, this, QOverload::of(&Notification::addActiveConnection)); QDBusConnection::systemBus().connect(QStringLiteral("org.freedesktop.login1"), QStringLiteral("/org/freedesktop/login1"), QStringLiteral("org.freedesktop.login1.Manager"), QStringLiteral("PrepareForSleep"), this, SLOT(onPrepareForSleep(bool))); } void Notification::deviceAdded(const QString &uni) { NetworkManager::Device::Ptr device = NetworkManager::findNetworkInterface(uni); addDevice(device); } void Notification::addDevice(const NetworkManager::Device::Ptr &device) { connect(device.data(), &NetworkManager::Device::stateChanged, this, &Notification::stateChanged); } void Notification::stateChanged(NetworkManager::Device::State newstate, NetworkManager::Device::State oldstate, NetworkManager::Device::StateChangeReason reason) { Q_UNUSED(oldstate) NetworkManager::Device *device = qobject_cast(sender()); if (newstate == NetworkManager::Device::Activated && m_notifications.contains(device->uni())) { KNotification *notify = m_notifications.value(device->uni()); notify->deleteLater(); m_notifications.remove(device->uni()); return; } else if (newstate != NetworkManager::Device::Failed) { return; } const QString identifier = UiUtils::prettyInterfaceName(device->type(), device->interfaceName()); QString text; switch (reason) { case NetworkManager::Device::NoReason: case NetworkManager::Device::UnknownReason: case NetworkManager::Device::NowManagedReason: case NetworkManager::Device::NowUnmanagedReason: return; case NetworkManager::Device::ConfigFailedReason: text = i18nc("@info:status Notification when the device failed due to ConfigFailedReason", "The device could not be configured"); break; case NetworkManager::Device::ConfigUnavailableReason: text = i18nc("@info:status Notification when the device failed due to ConfigUnavailableReason", "IP configuration was unavailable"); break; case NetworkManager::Device::ConfigExpiredReason: text = i18nc("@info:status Notification when the device failed due to ConfigExpiredReason", "IP configuration expired"); break; case NetworkManager::Device::NoSecretsReason: text = i18nc("@info:status Notification when the device failed due to NoSecretsReason", "No secrets were provided"); break; case NetworkManager::Device::AuthSupplicantDisconnectReason: text = i18nc("@info:status Notification when the device failed due to AuthSupplicantDisconnectReason", "Authorization supplicant disconnected"); break; case NetworkManager::Device::AuthSupplicantConfigFailedReason: text = i18nc("@info:status Notification when the device failed due to AuthSupplicantConfigFailedReason", "Authorization supplicant's configuration failed"); break; case NetworkManager::Device::AuthSupplicantFailedReason: text = i18nc("@info:status Notification when the device failed due to AuthSupplicantFailedReason", "Authorization supplicant failed"); break; case NetworkManager::Device::AuthSupplicantTimeoutReason: text = i18nc("@info:status Notification when the device failed due to AuthSupplicantTimeoutReason", "Authorization supplicant timed out"); break; case NetworkManager::Device::PppStartFailedReason: text = i18nc("@info:status Notification when the device failed due to PppStartFailedReason", "PPP failed to start"); break; case NetworkManager::Device::PppDisconnectReason: text = i18nc("@info:status Notification when the device failed due to PppDisconnectReason", "PPP disconnected"); break; case NetworkManager::Device::PppFailedReason: text = i18nc("@info:status Notification when the device failed due to PppFailedReason", "PPP failed"); break; case NetworkManager::Device::DhcpStartFailedReason: text = i18nc("@info:status Notification when the device failed due to DhcpStartFailedReason", "DHCP failed to start"); break; case NetworkManager::Device::DhcpErrorReason: text = i18nc("@info:status Notification when the device failed due to DhcpErrorReason", "A DHCP error occurred"); break; case NetworkManager::Device::DhcpFailedReason: text = i18nc("@info:status Notification when the device failed due to DhcpFailedReason", "DHCP failed "); break; case NetworkManager::Device::SharedStartFailedReason: text = i18nc("@info:status Notification when the device failed due to SharedStartFailedReason", "The shared service failed to start"); break; case NetworkManager::Device::SharedFailedReason: text = i18nc("@info:status Notification when the device failed due to SharedFailedReason", "The shared service failed"); break; case NetworkManager::Device::AutoIpStartFailedReason: text = i18nc("@info:status Notification when the device failed due to AutoIpStartFailedReason", "The auto IP service failed to start"); break; case NetworkManager::Device::AutoIpErrorReason: text = i18nc("@info:status Notification when the device failed due to AutoIpErrorReason", "The auto IP service reported an error"); break; case NetworkManager::Device::AutoIpFailedReason: text = i18nc("@info:status Notification when the device failed due to AutoIpFailedReason", "The auto IP service failed"); break; case NetworkManager::Device::ModemBusyReason: text = i18nc("@info:status Notification when the device failed due to ModemBusyReason", "The modem is busy"); break; case NetworkManager::Device::ModemNoDialToneReason: text = i18nc("@info:status Notification when the device failed due to ModemNoDialToneReason", "The modem has no dial tone"); break; case NetworkManager::Device::ModemNoCarrierReason: text = i18nc("@info:status Notification when the device failed due to ModemNoCarrierReason", "The modem shows no carrier"); break; case NetworkManager::Device::ModemDialTimeoutReason: text = i18nc("@info:status Notification when the device failed due to ModemDialTimeoutReason", "The modem dial timed out"); break; case NetworkManager::Device::ModemDialFailedReason: text = i18nc("@info:status Notification when the device failed due to ModemDialFailedReason", "The modem dial failed"); break; case NetworkManager::Device::ModemInitFailedReason: text = i18nc("@info:status Notification when the device failed due to ModemInitFailedReason", "The modem could not be initialized"); break; case NetworkManager::Device::GsmApnSelectFailedReason: text = i18nc("@info:status Notification when the device failed due to GsmApnSelectFailedReason", "The GSM APN could not be selected"); break; case NetworkManager::Device::GsmNotSearchingReason: text = i18nc("@info:status Notification when the device failed due to GsmNotSearchingReason", "The GSM modem is not searching"); break; case NetworkManager::Device::GsmRegistrationDeniedReason: text = i18nc("@info:status Notification when the device failed due to GsmRegistrationDeniedReason", "GSM network registration was denied"); break; case NetworkManager::Device::GsmRegistrationTimeoutReason: text = i18nc("@info:status Notification when the device failed due to GsmRegistrationTimeoutReason", "GSM network registration timed out"); break; case NetworkManager::Device::GsmRegistrationFailedReason: text = i18nc("@info:status Notification when the device failed due to GsmRegistrationFailedReason", "GSM registration failed"); break; case NetworkManager::Device::GsmPinCheckFailedReason: text = i18nc("@info:status Notification when the device failed due to GsmPinCheckFailedReason", "The GSM PIN check failed"); break; case NetworkManager::Device::FirmwareMissingReason: text = i18nc("@info:status Notification when the device failed due to FirmwareMissingReason", "Device firmware is missing"); break; case NetworkManager::Device::DeviceRemovedReason: text = i18nc("@info:status Notification when the device failed due to DeviceRemovedReason", "The device was removed"); break; case NetworkManager::Device::SleepingReason: text = i18nc("@info:status Notification when the device failed due to SleepingReason", "The networking system is now sleeping"); break; case NetworkManager::Device::ConnectionRemovedReason: text = i18nc("@info:status Notification when the device failed due to ConnectionRemovedReason", "The connection was removed"); break; case NetworkManager::Device::UserRequestedReason: return; case NetworkManager::Device::CarrierReason: text = i18nc("@info:status Notification when the device failed due to CarrierReason", "The cable was disconnected"); break; case NetworkManager::Device::ConnectionAssumedReason: case NetworkManager::Device::SupplicantAvailableReason: return; case NetworkManager::Device::ModemNotFoundReason: text = i18nc("@info:status Notification when the device failed due to ModemNotFoundReason", "The modem could not be found"); break; case NetworkManager::Device::BluetoothFailedReason: text = i18nc("@info:status Notification when the device failed due to BluetoothFailedReason", "The bluetooth connection failed or timed out"); break; case NetworkManager::Device::GsmSimNotInserted: text = i18nc("@info:status Notification when the device failed due to GsmSimNotInserted", "GSM Modem's SIM Card not inserted"); break; case NetworkManager::Device::GsmSimPinRequired: text = i18nc("@info:status Notification when the device failed due to GsmSimPinRequired", "GSM Modem's SIM Pin required"); break; case NetworkManager::Device::GsmSimPukRequired: text = i18nc("@info:status Notification when the device failed due to GsmSimPukRequired", "GSM Modem's SIM Puk required"); break; case NetworkManager::Device::GsmSimWrong: text = i18nc("@info:status Notification when the device failed due to GsmSimWrong", "GSM Modem's SIM wrong"); break; case NetworkManager::Device::InfiniBandMode: text = i18nc("@info:status Notification when the device failed due to InfiniBandMode", "InfiniBand device does not support connected mode"); break; case NetworkManager::Device::DependencyFailed: text = i18nc("@info:status Notification when the device failed due to DependencyFailed", "A dependency of the connection failed"); break; case NetworkManager::Device::Br2684Failed: text = i18nc("@info:status Notification when the device failed due to Br2684Failed", "Problem with the RFC 2684 Ethernet over ADSL bridge"); break; case NetworkManager::Device::ModemManagerUnavailable: text = i18nc("@info:status Notification when the device failed due to ModemManagerUnavailable", "ModemManager not running"); break; case NetworkManager::Device::SsidNotFound: text = i18nc("@info:status Notification when the device failed due to SsidNotFound", "The WiFi network could not be found"); break; case NetworkManager::Device::SecondaryConnectionFailed: text = i18nc("@info:status Notification when the device failed due to SecondaryConnectionFailed", "A secondary connection of the base connection failed"); break; case NetworkManager::Device::DcbFcoeFailed: text = i18nc("@info:status Notification when the device failed due to DcbFcoeFailed", "DCB or FCoE setup failed"); break; case NetworkManager::Device::TeamdControlFailed: text = i18nc("@info:status Notification when the device failed due to TeamdControlFailed", "teamd control failed"); break; case NetworkManager::Device::ModemFailed: text = i18nc("@info:status Notification when the device failed due to ModemFailed", "Modem failed or no longer available"); break; case NetworkManager::Device::ModemAvailable: text = i18nc("@info:status Notification when the device failed due to ModemAvailable", "Modem now ready and available"); break; case NetworkManager::Device::SimPinIncorrect: text = i18nc("@info:status Notification when the device failed due to SimPinIncorrect", "The SIM PIN was incorrect"); break; case NetworkManager::Device::NewActivation: text = i18nc("@info:status Notification when the device failed due to NewActivation", "A new connection activation was enqueued"); break; case NetworkManager::Device::ParentChanged: text = i18nc("@info:status Notification when the device failed due to ParentChanged", "The device's parent changed"); break; case NetworkManager::Device::ParentManagedChanged: text = i18nc("@info:status Notification when the device failed due to ParentManagedChanged", "The device parent's management changed"); break; case NetworkManager::Device::Reserved: return; } if (m_notifications.contains(device->uni())) { KNotification *notify = m_notifications.value(device->uni()); notify->setText(text); notify->update(); } else { KNotification *notify = new KNotification(QStringLiteral("DeviceFailed"), KNotification::CloseOnTimeout, this); connect(notify, &KNotification::closed, this, &Notification::notificationClosed); notify->setProperty("uni", device->uni()); notify->setComponentName(QStringLiteral("networkmanagement")); - notify->setPixmap(QIcon::fromTheme(QStringLiteral("dialog-warning")).pixmap(KIconLoader::SizeHuge)); + notify->setIconName(QStringLiteral("dialog-warning")); notify->setTitle(identifier); notify->setText(text); notify->sendEvent(); if (notify->id() != -1) { m_notifications[device->uni()] = notify; } } } void Notification::addActiveConnection(const QString &path) { NetworkManager::ActiveConnection::Ptr ac = NetworkManager::findActiveConnection(path); if (ac && ac->isValid()) { addActiveConnection(ac); } } void Notification::addActiveConnection(const NetworkManager::ActiveConnection::Ptr &ac) { if (ac->vpn()) { NetworkManager::VpnConnection::Ptr vpnConnection = ac.objectCast(); connect(vpnConnection.data(), &NetworkManager::VpnConnection::stateChanged, this, &Notification::onVpnConnectionStateChanged); } else if (ac->type() != NetworkManager::ConnectionSettings::Bond && ac->type() != NetworkManager::ConnectionSettings::Bridge && ac->type() != NetworkManager::ConnectionSettings::Generic && ac->type() != NetworkManager::ConnectionSettings::Infiniband && ac->type() != NetworkManager::ConnectionSettings::Team && ac->type() != NetworkManager::ConnectionSettings::Vlan && ac->type() != NetworkManager::ConnectionSettings::Tun) { connect(ac.data(), &NetworkManager::ActiveConnection::stateChanged, this, &Notification::onActiveConnectionStateChanged); } } void Notification::onActiveConnectionStateChanged(NetworkManager::ActiveConnection::State state) { NetworkManager::ActiveConnection *ac = qobject_cast(sender()); QString eventId, text, iconName; const QString acName = ac->id(); const QString connectionId = ac->path(); if (state == NetworkManager::ActiveConnection::Activated) { auto foundConnection = std::find_if(m_activeConnectionsBeforeSleep.constBegin(), m_activeConnectionsBeforeSleep.constEnd(), [ac](const QString &uuid) { return uuid == ac->uuid(); }); if (foundConnection != m_activeConnectionsBeforeSleep.constEnd()) { qCDebug(PLASMA_NM) << "Not emitting connection activated notification as the connection was active prior to suspend"; return; } eventId = QStringLiteral("ConnectionActivated"); text = i18n("Connection '%1' activated.", acName); switch (ac->type()) { case NetworkManager::ConnectionSettings::Wireless: iconName = QStringLiteral("network-wireless-on"); break; case NetworkManager::ConnectionSettings::Wired: iconName = QStringLiteral("network-wired-activated"); break; case NetworkManager::ConnectionSettings::WireGuard: iconName = QStringLiteral("network-vpn"); break; default: // silence warning break; } } else if (state == NetworkManager::ActiveConnection::Deactivated) { if (m_preparingForSleep) { qCDebug(PLASMA_NM) << "Not emitting connection deactivated notification as we're about to suspend"; return; } eventId = QStringLiteral("ConnectionDeactivated"); text = i18n("Connection '%1' deactivated.", acName); switch (ac->type()) { case NetworkManager::ConnectionSettings::Wireless: iconName = QStringLiteral("network-wireless-disconnected"); break; case NetworkManager::ConnectionSettings::Wired: iconName = QStringLiteral("network-unavailable"); break; default: // silence warning break; } } else { qCWarning(PLASMA_NM) << "Unhandled active connection state change: " << state; return; } KNotification *notify = new KNotification(eventId, KNotification::CloseOnTimeout, this); connect(notify, &KNotification::closed, this, &Notification::notificationClosed); notify->setProperty("uni", connectionId); notify->setComponentName(QStringLiteral("networkmanagement")); if (!iconName.isEmpty()) { notify->setIconName(iconName); } else { if (state == NetworkManager::ActiveConnection::Activated) { notify->setIconName(QStringLiteral("dialog-information")); } else { notify->setIconName(QStringLiteral("dialog-warning")); } } notify->setTitle(acName); notify->setText(text); notify->sendEvent(); if (notify->id() != -1) { m_notifications[connectionId] = notify; } } void Notification::onVpnConnectionStateChanged(NetworkManager::VpnConnection::State state, NetworkManager::VpnConnection::StateChangeReason reason) { NetworkManager::VpnConnection *vpn = qobject_cast(sender()); QString eventId, text; const QString vpnName = vpn->connection()->name(); const QString connectionId = vpn->path(); if (state == NetworkManager::VpnConnection::Activated) { eventId = QStringLiteral("ConnectionActivated"); text = i18n("VPN connection '%1' activated.", vpnName); } else if (state == NetworkManager::VpnConnection::Failed) { eventId = QStringLiteral("FailedToActivateConnection"); text = i18n("VPN connection '%1' failed.", vpnName); } else if (state == NetworkManager::VpnConnection::Disconnected) { eventId = QStringLiteral("ConnectionDeactivated"); text = i18n("VPN connection '%1' disconnected.", vpnName); } else { qCWarning(PLASMA_NM) << "Unhandled VPN connection state change: " << state; return; } switch (reason) { case NetworkManager::VpnConnection::UserDisconnectedReason: text = i18n("The VPN connection changed state because the user disconnected it."); break; case NetworkManager::VpnConnection::DeviceDisconnectedReason: text = i18n("The VPN connection changed state because the device it was using was disconnected."); break; case NetworkManager::VpnConnection::ServiceStoppedReason: text = i18n("The service providing the VPN connection was stopped."); break; case NetworkManager::VpnConnection::IpConfigInvalidReason: text = i18n("The IP config of the VPN connection was invalid."); break; case NetworkManager::VpnConnection::ConnectTimeoutReason: text = i18n("The connection attempt to the VPN service timed out."); break; case NetworkManager::VpnConnection::ServiceStartTimeoutReason: text = i18n("A timeout occurred while starting the service providing the VPN connection."); break; case NetworkManager::VpnConnection::ServiceStartFailedReason: text = i18n("Starting the service providing the VPN connection failed."); break; case NetworkManager::VpnConnection::NoSecretsReason: text = i18n("Necessary secrets for the VPN connection were not provided."); break; case NetworkManager::VpnConnection::LoginFailedReason: text = i18n("Authentication to the VPN server failed."); break; case NetworkManager::VpnConnection::ConnectionRemovedReason: text = i18n("The connection was deleted from settings."); break; default: case NetworkManager::VpnConnection::UnknownReason: case NetworkManager::VpnConnection::NoneReason: break; } KNotification *notify = new KNotification(eventId, KNotification::CloseOnTimeout, this); connect(notify, &KNotification::closed, this, &Notification::notificationClosed); notify->setProperty("uni", connectionId); notify->setComponentName("networkmanagement"); if (state == NetworkManager::VpnConnection::Activated) { notify->setIconName(QStringLiteral("dialog-information")); } else { notify->setIconName(QStringLiteral("dialog-warning")); } notify->setTitle(vpnName); notify->setText(text); notify->sendEvent(); if (notify->id() != -1) { m_notifications[connectionId] = notify; } } void Notification::notificationClosed() { KNotification *notify = qobject_cast(sender()); m_notifications.remove(notify->property("uni").toString()); notify->deleteLater(); } void Notification::onPrepareForSleep(bool sleep) { m_preparingForSleep = sleep; if (m_checkActiveConnectionOnResumeTimer) { m_checkActiveConnectionOnResumeTimer->stop(); } if (sleep) { // store all active notifications so we don't show a "is connected" notification // on resume if we were connected previously m_activeConnectionsBeforeSleep.clear(); const auto &connections = NetworkManager::activeConnections(); for (const auto &connection : connections) { if (!connection->vpn() && connection->state() == NetworkManager::ActiveConnection::State::Activated) { m_activeConnectionsBeforeSleep << connection->uuid(); } } } else { if (!m_checkActiveConnectionOnResumeTimer) { m_checkActiveConnectionOnResumeTimer = new QTimer(this); m_checkActiveConnectionOnResumeTimer->setInterval(10000); m_checkActiveConnectionOnResumeTimer->setSingleShot(true); connect(m_checkActiveConnectionOnResumeTimer, &QTimer::timeout, this, &Notification::onCheckActiveConnectionOnResume); } m_checkActiveConnectionOnResumeTimer->start(); } } void Notification::onCheckActiveConnectionOnResume() { if (m_activeConnectionsBeforeSleep.isEmpty()) { // if we weren't connected before, don't bother telling us now :) return; } m_activeConnectionsBeforeSleep.clear(); const auto &connections = NetworkManager::activeConnections(); for (const auto &connection : connections) { if (connection->state() == NetworkManager::ActiveConnection::State::Activated || connection->state() == NetworkManager::ActiveConnection::State::Activating) { // we have an active or activating connection, don't tell the user we're no longer connected return; } } KNotification *notify = new KNotification(QStringLiteral("NoLongerConnected"), KNotification::CloseOnTimeout, this); connect(notify, &KNotification::closed, this, &Notification::notificationClosed); const QString uni = QStringLiteral("offlineNotification"); notify->setProperty("uni", uni); notify->setComponentName("networkmanagement"); notify->setIconName(QStringLiteral("dialog-warning")); notify->setTitle(i18n("No Network Connection")); notify->setText(i18n("You are no longer connected to a network.")); notify->sendEvent(); if (notify->id() != -1) { m_notifications[uni] = notify; } } diff --git a/libs/editor/connectioneditorbase.cpp b/libs/editor/connectioneditorbase.cpp index 433f94af..7508dd3d 100644 --- a/libs/editor/connectioneditorbase.cpp +++ b/libs/editor/connectioneditorbase.cpp @@ -1,498 +1,497 @@ /* Copyright 2013-2016 Jan Grulich Copyright 2013, 2014 Lukas Tinkl This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "connectioneditorbase.h" #include "debug.h" #include "settings/bondwidget.h" #include "settings/bridgewidget.h" #include "settings/btwidget.h" #include "settings/cdmawidget.h" #include "settings/connectionwidget.h" #include "settings/gsmwidget.h" #include "settings/infinibandwidget.h" #include "settings/ipv4widget.h" #include "settings/ipv6widget.h" #include "settings/pppwidget.h" #include "settings/pppoewidget.h" #include "settings/teamwidget.h" #include "settings/vlanwidget.h" #include "settings/wificonnectionwidget.h" #include "settings/wifisecurity.h" #include "settings/wiredconnectionwidget.h" #include "settings/wiredsecurity.h" #include "settings/wireguardinterfacewidget.h" #include "vpnuiplugin.h" #include #include #include #include #include #include #include #include #include #include #include #include -#include #include #include #include #include ConnectionEditorBase::ConnectionEditorBase(const NetworkManager::ConnectionSettings::Ptr &connection, QWidget *parent, Qt::WindowFlags f) : QWidget(parent, f) , m_initialized(false) , m_valid(false) , m_pendingReplies(0) , m_connection(connection) { } ConnectionEditorBase::ConnectionEditorBase(QWidget *parent, Qt::WindowFlags f) : QWidget(parent, f) { } ConnectionEditorBase::~ConnectionEditorBase() { m_connection.clear(); } void ConnectionEditorBase::setConnection(const NetworkManager::ConnectionSettings::Ptr &connection) { // Set connection settings m_connection.clear(); m_connection = connection; m_initialized = false; // Reset UI setting widgets delete m_connectionWidget; m_connectionWidget = nullptr; qDeleteAll(m_settingWidgets); m_settingWidgets.clear(); initialize(); } NMVariantMapMap ConnectionEditorBase::setting() const { NMVariantMapMap settings = m_connectionWidget->setting(); for (SettingWidget *widget : m_settingWidgets) { const QString type = widget->type(); if (type != NetworkManager::Setting::typeAsString(NetworkManager::Setting::Security8021x) && type != NetworkManager::Setting::typeAsString(NetworkManager::Setting::WirelessSecurity)) { settings.insert(type, widget->setting()); } // add 802.1x security if needed QVariantMap security8021x; if (type == NetworkManager::Setting::typeAsString(NetworkManager::Setting::WirelessSecurity)) { WifiSecurity *wifiSecurity = static_cast(widget); if (wifiSecurity->enabled()) { settings.insert(type, wifiSecurity->setting()); } if (wifiSecurity->enabled8021x()) { security8021x = static_cast(widget)->setting8021x(); settings.insert(NetworkManager::Setting::typeAsString(NetworkManager::Setting::Security8021x), security8021x); } } else if (type == NetworkManager::Setting::typeAsString(NetworkManager::Setting::Security8021x)) { WiredSecurity *wiredSecurity = static_cast(widget); if (wiredSecurity->enabled8021x()) { security8021x = static_cast(widget)->setting(); settings.insert(NetworkManager::Setting::typeAsString(NetworkManager::Setting::Security8021x), security8021x); } } } // Set properties which are not returned from setting widgets NetworkManager::ConnectionSettings::Ptr connectionSettings = NetworkManager::ConnectionSettings::Ptr(new NetworkManager::ConnectionSettings(m_connection->connectionType())); connectionSettings->fromMap(settings); connectionSettings->setId(connectionName()); if (connectionSettings->connectionType() == NetworkManager::ConnectionSettings::WireGuard) connectionSettings->setInterfaceName(connectionName()); connectionSettings->setUuid(m_connection->uuid()); if (connectionSettings->connectionType() == NetworkManager::ConnectionSettings::Wireless) { NetworkManager::WirelessSecuritySetting::Ptr securitySetting = connectionSettings->setting(NetworkManager::Setting::WirelessSecurity).staticCast(); NetworkManager::WirelessSetting::Ptr wirelessSetting = connectionSettings->setting(NetworkManager::Setting::Wireless).staticCast(); if (securitySetting && wirelessSetting) { if (securitySetting->keyMgmt() != NetworkManager::WirelessSecuritySetting::WirelessSecuritySetting::Unknown) { wirelessSetting->setSecurity("802-11-wireless-security"); } } } return connectionSettings->toMap(); } bool ConnectionEditorBase::isInitialized() const { return m_initialized; } bool ConnectionEditorBase::isValid() const { return m_valid; } void ConnectionEditorBase::addConnectionWidget(ConnectionWidget *widget, const QString &text) { m_connectionWidget = widget; connect(widget, &ConnectionWidget::settingChanged, this, &ConnectionEditorBase::settingChanged); addWidget(widget, text); } void ConnectionEditorBase::addSettingWidget(SettingWidget *widget, const QString &text) { m_settingWidgets << widget; connect(widget, &SettingWidget::settingChanged, this, &ConnectionEditorBase::settingChanged); addWidget(widget, text); } void ConnectionEditorBase::initialize() { const bool emptyConnection = m_connection->id().isEmpty(); const NetworkManager::ConnectionSettings::ConnectionType type = m_connection->connectionType(); if (emptyConnection) { m_connection->addToPermissions(KUser().loginName(), QString()); } // General configuration common to all connection types ConnectionWidget *connectionWidget = new ConnectionWidget(m_connection); addConnectionWidget(connectionWidget, i18nc("General", "General configuration")); // Add the rest of widgets QString serviceType; if (type == NetworkManager::ConnectionSettings::Wired) { WiredConnectionWidget *wiredWidget = new WiredConnectionWidget(m_connection->setting(NetworkManager::Setting::Wired), this); addSettingWidget(wiredWidget, i18n("Wired")); WiredSecurity *wiredSecurity = new WiredSecurity(m_connection->setting(NetworkManager::Setting::Security8021x).staticCast(), this); addSettingWidget(wiredSecurity, i18n("802.1x Security")); } else if (type == NetworkManager::ConnectionSettings::Wireless) { WifiConnectionWidget *wifiWidget = new WifiConnectionWidget(m_connection->setting(NetworkManager::Setting::Wireless), this); addSettingWidget(wifiWidget, i18n("Wi-Fi")); WifiSecurity *wifiSecurity = new WifiSecurity(m_connection->setting(NetworkManager::Setting::WirelessSecurity), m_connection->setting(NetworkManager::Setting::Security8021x).staticCast(), this); addSettingWidget(wifiSecurity, i18n("Wi-Fi Security")); connect(wifiWidget, QOverload::of(&WifiConnectionWidget::ssidChanged), wifiSecurity, &WifiSecurity::onSsidChanged); } else if (type == NetworkManager::ConnectionSettings::Pppoe) { // DSL PppoeWidget *pppoeWidget = new PppoeWidget(m_connection->setting(NetworkManager::Setting::Pppoe), this); addSettingWidget(pppoeWidget, i18n("DSL")); WiredConnectionWidget *wiredWidget = new WiredConnectionWidget(m_connection->setting(NetworkManager::Setting::Wired), this); addSettingWidget(wiredWidget, i18n("Wired")); } else if (type == NetworkManager::ConnectionSettings::Gsm) { // GSM GsmWidget *gsmWidget = new GsmWidget(m_connection->setting(NetworkManager::Setting::Gsm), this); addSettingWidget(gsmWidget, i18n("Mobile Broadband (%1)", m_connection->typeAsString(m_connection->connectionType()))); } else if (type == NetworkManager::ConnectionSettings::Cdma) { // CDMA CdmaWidget *cdmaWidget = new CdmaWidget(m_connection->setting(NetworkManager::Setting::Cdma), this); addSettingWidget(cdmaWidget, i18n("Mobile Broadband (%1)", m_connection->typeAsString(m_connection->connectionType()))); } else if (type == NetworkManager::ConnectionSettings::Bluetooth) { // Bluetooth BtWidget *btWidget = new BtWidget(m_connection->setting(NetworkManager::Setting::Bluetooth), this); addSettingWidget(btWidget, i18n("Bluetooth")); NetworkManager::BluetoothSetting::Ptr btSetting = m_connection->setting(NetworkManager::Setting::Bluetooth).staticCast(); if (btSetting->profileType() == NetworkManager::BluetoothSetting::Dun) { GsmWidget *gsmWidget = new GsmWidget(m_connection->setting(NetworkManager::Setting::Gsm), this); addSettingWidget(gsmWidget, i18n("GSM")); PPPWidget *pppWidget = new PPPWidget(m_connection->setting(NetworkManager::Setting::Ppp), this); addSettingWidget(pppWidget, i18n("PPP")); } } else if (type == NetworkManager::ConnectionSettings::Infiniband) { // Infiniband InfinibandWidget *infinibandWidget = new InfinibandWidget(m_connection->setting(NetworkManager::Setting::Infiniband), this); addSettingWidget(infinibandWidget, i18n("Infiniband")); } else if (type == NetworkManager::ConnectionSettings::Bond) { // Bond BondWidget *bondWidget = new BondWidget(m_connection->uuid(), m_connection->id(), m_connection->setting(NetworkManager::Setting::Bond), this); addSettingWidget(bondWidget, i18n("Bond")); } else if (type == NetworkManager::ConnectionSettings::Bridge) { // Bridge BridgeWidget *bridgeWidget = new BridgeWidget(m_connection->uuid(), m_connection->id(), m_connection->setting(NetworkManager::Setting::Bridge), this); addSettingWidget(bridgeWidget, i18n("Bridge")); } else if (type == NetworkManager::ConnectionSettings::Vlan) { // Vlan VlanWidget *vlanWidget = new VlanWidget(m_connection->setting(NetworkManager::Setting::Vlan), this); addSettingWidget(vlanWidget, i18n("Vlan")); } else if (type == NetworkManager::ConnectionSettings::Team) { // Team TeamWidget *teamWidget = new TeamWidget(m_connection->uuid(), m_connection->id(), m_connection->setting(NetworkManager::Setting::Team), this); addSettingWidget(teamWidget, i18n("Team")); } else if (type == NetworkManager::ConnectionSettings::WireGuard) { // WireGuard WireGuardInterfaceWidget *wireGuardInterfaceWidget = new WireGuardInterfaceWidget(m_connection->setting(NetworkManager::Setting::WireGuard), this); addSettingWidget(wireGuardInterfaceWidget, i18n("WireGuard Interface")); } else if (type == NetworkManager::ConnectionSettings::Vpn) { // VPN QString error; VpnUiPlugin *vpnPlugin = nullptr; NetworkManager::VpnSetting::Ptr vpnSetting = m_connection->setting(NetworkManager::Setting::Vpn).staticCast(); if (!vpnSetting) { qCWarning(PLASMA_NM) << "Missing VPN setting!"; } else { serviceType = vpnSetting->serviceType(); vpnPlugin = KServiceTypeTrader::createInstanceFromQuery(QString::fromLatin1("PlasmaNetworkManagement/VpnUiPlugin"), QString::fromLatin1("[X-NetworkManager-Services]=='%1'").arg(serviceType), this, QVariantList(), &error); if (vpnPlugin && error.isEmpty()) { const QString shortName = serviceType.section('.', -1); SettingWidget *vpnWidget = vpnPlugin->widget(vpnSetting, this); addSettingWidget(vpnWidget, i18n("VPN (%1)", shortName)); } else { qCWarning(PLASMA_NM) << error << ", serviceType == " << serviceType; } } } // PPP widget if (type == NetworkManager::ConnectionSettings::Pppoe || type == NetworkManager::ConnectionSettings::Cdma || type == NetworkManager::ConnectionSettings::Gsm) { PPPWidget *pppWidget = new PPPWidget(m_connection->setting(NetworkManager::Setting::Ppp), this); addSettingWidget(pppWidget, i18n("PPP")); } // IPv4 widget if (!m_connection->isSlave()) { IPv4Widget *ipv4Widget = new IPv4Widget(m_connection->setting(NetworkManager::Setting::Ipv4), this); addSettingWidget(ipv4Widget, i18n("IPv4")); } // IPv6 widget if ((type == NetworkManager::ConnectionSettings::Wired || type == NetworkManager::ConnectionSettings::Wireless || type == NetworkManager::ConnectionSettings::Infiniband || type == NetworkManager::ConnectionSettings::Team || type == NetworkManager::ConnectionSettings::Cdma || type == NetworkManager::ConnectionSettings::Gsm || type == NetworkManager::ConnectionSettings::Bond || type == NetworkManager::ConnectionSettings::Bridge || type == NetworkManager::ConnectionSettings::Vlan || type == NetworkManager::ConnectionSettings::WireGuard || (type == NetworkManager::ConnectionSettings::Vpn && serviceType == QLatin1String("org.freedesktop.NetworkManager.openvpn"))) && !m_connection->isSlave()) { IPv6Widget *ipv6Widget = new IPv6Widget(m_connection->setting(NetworkManager::Setting::Ipv6), this); addSettingWidget(ipv6Widget, i18n("IPv6")); } // Re-check validation bool valid = true; for (SettingWidget *widget : m_settingWidgets) { valid = valid && widget->isValid(); connect(widget, &SettingWidget::validChanged, this, &ConnectionEditorBase::validChanged); } m_valid = valid; Q_EMIT validityChanged(valid); KAcceleratorManager::manage(this); // If the connection is not empty (not new) we want to load its secrets if (!emptyConnection) { NetworkManager::Connection::Ptr connection = NetworkManager::findConnectionByUuid(m_connection->uuid()); if (connection) { QStringList requiredSecrets; QString settingName; QVariantMap setting; QDBusPendingReply reply; if (m_connection->connectionType() == NetworkManager::ConnectionSettings::Adsl) { NetworkManager::AdslSetting::Ptr adslSetting = connection->settings()->setting(NetworkManager::Setting::Adsl).staticCast(); if (adslSetting && !adslSetting->needSecrets().isEmpty()) { requiredSecrets = adslSetting->needSecrets(); setting = adslSetting->toMap(); settingName = QLatin1String("adsl"); } } else if (m_connection->connectionType() == NetworkManager::ConnectionSettings::Bluetooth) { NetworkManager::GsmSetting::Ptr gsmSetting = connection->settings()->setting(NetworkManager::Setting::Gsm).staticCast(); if (gsmSetting && !gsmSetting->needSecrets().isEmpty()) { requiredSecrets = gsmSetting->needSecrets(); setting = gsmSetting->toMap(); settingName = QLatin1String("gsm"); } } else if (m_connection->connectionType() == NetworkManager::ConnectionSettings::Cdma) { NetworkManager::CdmaSetting::Ptr cdmaSetting = connection->settings()->setting(NetworkManager::Setting::Cdma).staticCast(); if (cdmaSetting && !cdmaSetting->needSecrets().isEmpty()) { requiredSecrets = cdmaSetting->needSecrets(); setting = cdmaSetting->toMap(); settingName = QLatin1String("cdma"); } } else if (m_connection->connectionType() == NetworkManager::ConnectionSettings::Gsm) { NetworkManager::GsmSetting::Ptr gsmSetting = connection->settings()->setting(NetworkManager::Setting::Gsm).staticCast(); if (gsmSetting && !gsmSetting->needSecrets().isEmpty()) { requiredSecrets = gsmSetting->needSecrets(); setting = gsmSetting->toMap(); settingName = QLatin1String("gsm"); } } else if (m_connection->connectionType() == NetworkManager::ConnectionSettings::Pppoe) { NetworkManager::PppoeSetting::Ptr pppoeSetting = connection->settings()->setting(NetworkManager::Setting::Pppoe).staticCast(); if (pppoeSetting && !pppoeSetting->needSecrets().isEmpty()) { requiredSecrets = pppoeSetting->needSecrets(); setting = pppoeSetting->toMap(); settingName = QLatin1String("pppoe"); } } else if (m_connection->connectionType() == NetworkManager::ConnectionSettings::Wired) { NetworkManager::Security8021xSetting::Ptr securitySetting = connection->settings()->setting(NetworkManager::Setting::Security8021x).staticCast(); if (securitySetting && !securitySetting->needSecrets().isEmpty()) { requiredSecrets = securitySetting->needSecrets(); setting = securitySetting->toMap(); settingName = QLatin1String("802-1x"); } } else if (m_connection->connectionType() == NetworkManager::ConnectionSettings::WireGuard) { NetworkManager::WireGuardSetting::Ptr securitySetting = connection->settings()->setting(NetworkManager::Setting::WireGuard).staticCast(); if (securitySetting && !securitySetting->needSecrets().isEmpty()) { requiredSecrets = securitySetting->needSecrets(); setting = securitySetting->toMap(); settingName = QLatin1String("wireguard"); } } else if (m_connection->connectionType() == NetworkManager::ConnectionSettings::Wireless) { NetworkManager::WirelessSecuritySetting::Ptr wifiSecuritySetting = connection->settings()->setting(NetworkManager::Setting::WirelessSecurity).staticCast(); if (wifiSecuritySetting && (wifiSecuritySetting->keyMgmt() == NetworkManager::WirelessSecuritySetting::WpaEap || (wifiSecuritySetting->keyMgmt() == NetworkManager::WirelessSecuritySetting::WirelessSecuritySetting::Ieee8021x && wifiSecuritySetting->authAlg() != NetworkManager::WirelessSecuritySetting::Leap))) { NetworkManager::Security8021xSetting::Ptr securitySetting = connection->settings()->setting(NetworkManager::Setting::Security8021x).staticCast(); if (securitySetting && !securitySetting->needSecrets().isEmpty()) { requiredSecrets = securitySetting->needSecrets(); setting = securitySetting->toMap(); settingName = QLatin1String("802-1x"); if (requiredSecrets.contains(NM_SETTING_802_1X_PASSWORD_RAW)) { requiredSecrets.removeAll(NM_SETTING_802_1X_PASSWORD_RAW); } } } else { if (!wifiSecuritySetting->needSecrets().isEmpty()) { requiredSecrets = wifiSecuritySetting->needSecrets(); setting = wifiSecuritySetting->toMap(); settingName = QLatin1String("802-11-wireless-security"); } } } else if (m_connection->connectionType() == NetworkManager::ConnectionSettings::Vpn) { settingName = QLatin1String("vpn"); } if (!requiredSecrets.isEmpty() || m_connection->connectionType() == NetworkManager::ConnectionSettings::Vpn) { bool requestSecrets = false; if (m_connection->connectionType() == NetworkManager::ConnectionSettings::Vpn) { NetworkManager::VpnSetting::Ptr vpnSetting = connection->settings()->setting(NetworkManager::Setting::Vpn).staticCast(); for (const QString &key : vpnSetting->data().keys()) { if (key.endsWith(QStringLiteral("-flags"))) { NetworkManager::Setting::SecretFlagType secretFlag = (NetworkManager::Setting::SecretFlagType)vpnSetting->data().value(key).toInt(); if (secretFlag == NetworkManager::Setting::None || secretFlag == NetworkManager::Setting::AgentOwned) { requestSecrets = true; } } } } else { for (const QString &secret : requiredSecrets) { if (setting.contains(secret + QLatin1String("-flags"))) { NetworkManager::Setting::SecretFlagType secretFlag = (NetworkManager::Setting::SecretFlagType)setting.value(secret + QLatin1String("-flags")).toInt(); if (secretFlag == NetworkManager::Setting::None || secretFlag == NetworkManager::Setting::AgentOwned) { requestSecrets = true; } } else { requestSecrets = true; } } } if (requestSecrets) { m_pendingReplies++; reply = connection->secrets(settingName); QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this); watcher->setProperty("connection", connection->name()); watcher->setProperty("settingName", settingName); connect(watcher, &QDBusPendingCallWatcher::finished, this, &ConnectionEditorBase::replyFinished); m_valid = false; Q_EMIT validityChanged(false); return; } } } } // We should be now fully initialized as we don't wait for secrets if (m_pendingReplies == 0) { m_initialized = true; } } void ConnectionEditorBase::replyFinished(QDBusPendingCallWatcher *watcher) { QDBusPendingReply reply = *watcher; const QString settingName = watcher->property("settingName").toString(); if (reply.isValid()) { NMVariantMapMap secrets = reply.argumentAt<0>(); for (const QString &key : secrets.keys()) { if (key == settingName) { NetworkManager::Setting::Ptr setting = m_connection->setting(NetworkManager::Setting::typeFromString(key)); if (setting) { setting->secretsFromMap(secrets.value(key)); for (SettingWidget *widget : m_settingWidgets) { const QString type = widget->type(); if (type == settingName || (settingName == NetworkManager::Setting::typeAsString(NetworkManager::Setting::Security8021x) && type == NetworkManager::Setting::typeAsString(NetworkManager::Setting::WirelessSecurity))) { widget->loadSecrets(setting); } } } } } } else { KNotification *notification = new KNotification("FailedToGetSecrets", KNotification::CloseOnTimeout); notification->setComponentName("networkmanagement"); notification->setTitle(i18n("Failed to get secrets for %1", watcher->property("connection").toString())); notification->setText(reply.error().message()); - notification->setPixmap(QIcon::fromTheme("dialog-warning").pixmap(KIconLoader::SizeHuge)); + notification->setIconName(QStringLiteral("dialog-warning")); notification->sendEvent(); } watcher->deleteLater(); validChanged(true); // We should be now fully with secrets m_pendingReplies--; m_initialized = true; } void ConnectionEditorBase::validChanged(bool valid) { if (!valid) { m_valid = false; Q_EMIT validityChanged(false); return; } else { for (SettingWidget *widget : m_settingWidgets) { if (!widget->isValid()) { m_valid = false; Q_EMIT validityChanged(false); return; } } } m_valid = true; Q_EMIT validityChanged(true); } diff --git a/libs/handler.cpp b/libs/handler.cpp index 2e6650f3..c3b61472 100644 --- a/libs/handler.cpp +++ b/libs/handler.cpp @@ -1,690 +1,689 @@ /* Copyright 2013-2014 Jan Grulich This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "handler.h" #include "connectioneditordialog.h" #include "uiutils.h" #include "debug.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if WITH_MODEMMANAGER_SUPPORT #include #include #endif #include #include #include #include #include #include #include #include #include #include #include -#include #include #define AGENT_SERVICE "org.kde.kded5" #define AGENT_PATH "/modules/networkmanagement" #define AGENT_IFACE "org.kde.plasmanetworkmanagement" // 10 seconds #define NM_REQUESTSCAN_LIMIT_RATE 10000 Handler::Handler(QObject *parent) : QObject(parent) , m_tmpWirelessEnabled(NetworkManager::isWirelessEnabled()) , m_tmpWwanEnabled(NetworkManager::isWwanEnabled()) { initKdedModule(); QDBusConnection::sessionBus().connect(QStringLiteral(AGENT_SERVICE), QStringLiteral(AGENT_PATH), QStringLiteral(AGENT_IFACE), QStringLiteral("registered"), this, SLOT(initKdedModule())); QDBusConnection::sessionBus().connect(QStringLiteral(AGENT_SERVICE), QStringLiteral(AGENT_PATH), QStringLiteral(AGENT_IFACE), QStringLiteral("secretsError"), this, SLOT(secretAgentError(QString, QString))); } Handler::~Handler() { } void Handler::activateConnection(const QString& connection, const QString& device, const QString& specificObject) { NetworkManager::Connection::Ptr con = NetworkManager::findConnection(connection); if (!con) { qCWarning(PLASMA_NM) << "Not possible to activate this connection"; return; } if (con->settings()->connectionType() == NetworkManager::ConnectionSettings::Vpn) { NetworkManager::VpnSetting::Ptr vpnSetting = con->settings()->setting(NetworkManager::Setting::Vpn).staticCast(); if (vpnSetting) { qCDebug(PLASMA_NM) << "Checking VPN" << con->name() << "type:" << vpnSetting->serviceType(); bool pluginMissing = false; // Check missing plasma-nm VPN plugin const KService::List services = KServiceTypeTrader::self()->query("PlasmaNetworkManagement/VpnUiPlugin", QString::fromLatin1("[X-NetworkManager-Services]=='%1'").arg(vpnSetting->serviceType())); pluginMissing = services.isEmpty(); // Check missing NetworkManager VPN plugin if (!pluginMissing) { GSList *plugins = nullptr; plugins = nm_vpn_plugin_info_list_load(); NMVpnPluginInfo *plugin_info = nm_vpn_plugin_info_list_find_by_service(plugins, vpnSetting->serviceType().toStdString().c_str()); pluginMissing = !plugin_info; } if (pluginMissing) { qCWarning(PLASMA_NM) << "VPN" << vpnSetting->serviceType() << "not found, skipping"; KNotification *notification = new KNotification("MissingVpnPlugin", KNotification::CloseOnTimeout, this); notification->setComponentName("networkmanagement"); notification->setTitle(con->name()); notification->setText(i18n("Missing VPN plugin")); - notification->setPixmap(QIcon::fromTheme("dialog-warning").pixmap(KIconLoader::SizeHuge)); + notification->setIconName(QStringLiteral("dialog-warning")); notification->sendEvent(); return; } } } #if WITH_MODEMMANAGER_SUPPORT if (con->settings()->connectionType() == NetworkManager::ConnectionSettings::Gsm) { NetworkManager::ModemDevice::Ptr nmModemDevice = NetworkManager::findNetworkInterface(device).objectCast(); if (nmModemDevice) { ModemManager::ModemDevice::Ptr mmModemDevice = ModemManager::findModemDevice(nmModemDevice->udi()); if (mmModemDevice) { ModemManager::Modem::Ptr modem = mmModemDevice->interface(ModemManager::ModemDevice::ModemInterface).objectCast(); NetworkManager::GsmSetting::Ptr gsmSetting = con->settings()->setting(NetworkManager::Setting::Gsm).staticCast(); if (gsmSetting && gsmSetting->pinFlags() == NetworkManager::Setting::NotSaved && modem && modem->unlockRequired() > MM_MODEM_LOCK_NONE) { QDBusInterface managerIface("org.kde.plasmanetworkmanagement", "/org/kde/plasmanetworkmanagement", "org.kde.plasmanetworkmanagement", QDBusConnection::sessionBus(), this); managerIface.call("unlockModem", mmModemDevice->uni()); connect(modem.data(), &ModemManager::Modem::unlockRequiredChanged, this, &Handler::unlockRequiredChanged); m_tmpConnectionPath = connection; m_tmpDevicePath = device; m_tmpSpecificPath = specificObject; return; } } } } #endif QDBusPendingReply reply = NetworkManager::activateConnection(connection, device, specificObject); QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this); watcher->setProperty("action", Handler::ActivateConnection); watcher->setProperty("connection", con->name()); connect(watcher, &QDBusPendingCallWatcher::finished, this, &Handler::replyFinished); } QString Handler::wifiCode(const QString& connectionPath, const QString& ssid, int _securityType) const { NetworkManager::WirelessSecurityType securityType = static_cast(_securityType); QString ret = QStringLiteral("WIFI:S:") + ssid + QLatin1Char(';'); if (securityType != NetworkManager::NoneSecurity) { switch (securityType) { case NetworkManager::NoneSecurity: break; case NetworkManager::StaticWep: ret += "T:WEP;"; break; case NetworkManager::WpaPsk: case NetworkManager::Wpa2Psk: ret += "T:WPA;"; break; default: case NetworkManager::DynamicWep: case NetworkManager::WpaEap: case NetworkManager::Wpa2Eap: case NetworkManager::Leap: return {}; } } NetworkManager::Connection::Ptr connection = NetworkManager::findConnection(connectionPath); if(!connection) return {}; const auto key = QStringLiteral("802-11-wireless-security"); auto reply = connection->secrets(key); const auto secret = reply.argumentAt<0>()[key]; QString pass; switch (securityType) { case NetworkManager::NoneSecurity: break; case NetworkManager::WpaPsk: case NetworkManager::Wpa2Psk: pass = secret["psk"].toString(); break; default: return {}; } if (!pass.isEmpty()) ret += QStringLiteral("P:") + pass + QLatin1Char(';'); return ret + QLatin1Char(';'); } void Handler::addAndActivateConnection(const QString& device, const QString& specificObject, const QString& password) { NetworkManager::AccessPoint::Ptr ap; NetworkManager::WirelessDevice::Ptr wifiDev; for (const NetworkManager::Device::Ptr &dev : NetworkManager::networkInterfaces()) { if (dev->type() == NetworkManager::Device::Wifi) { wifiDev = dev.objectCast(); ap = wifiDev->findAccessPoint(specificObject); if (ap) { break; } } } if (!ap) { return; } NetworkManager::ConnectionSettings::Ptr settings = NetworkManager::ConnectionSettings::Ptr(new NetworkManager::ConnectionSettings(NetworkManager::ConnectionSettings::Wireless)); settings->setId(ap->ssid()); settings->setUuid(NetworkManager::ConnectionSettings::createNewUuid()); settings->setAutoconnect(true); settings->addToPermissions(KUser().loginName(), QString()); NetworkManager::WirelessSetting::Ptr wifiSetting = settings->setting(NetworkManager::Setting::Wireless).dynamicCast(); wifiSetting->setInitialized(true); wifiSetting = settings->setting(NetworkManager::Setting::Wireless).dynamicCast(); wifiSetting->setSsid(ap->ssid().toUtf8()); if (ap->mode() == NetworkManager::AccessPoint::Adhoc) { wifiSetting->setMode(NetworkManager::WirelessSetting::Adhoc); } NetworkManager::WirelessSecuritySetting::Ptr wifiSecurity = settings->setting(NetworkManager::Setting::WirelessSecurity).dynamicCast(); NetworkManager::WirelessSecurityType securityType = NetworkManager::findBestWirelessSecurity(wifiDev->wirelessCapabilities(), true, (ap->mode() == NetworkManager::AccessPoint::Adhoc), ap->capabilities(), ap->wpaFlags(), ap->rsnFlags()); if (securityType != NetworkManager::NoneSecurity) { wifiSecurity->setInitialized(true); wifiSetting->setSecurity("802-11-wireless-security"); } if (securityType == NetworkManager::Leap || securityType == NetworkManager::DynamicWep || securityType == NetworkManager::Wpa2Eap || securityType == NetworkManager::WpaEap) { if (securityType == NetworkManager::DynamicWep || securityType == NetworkManager::Leap) { wifiSecurity->setKeyMgmt(NetworkManager::WirelessSecuritySetting::Ieee8021x); if (securityType == NetworkManager::Leap) { wifiSecurity->setAuthAlg(NetworkManager::WirelessSecuritySetting::Leap); } } else { wifiSecurity->setKeyMgmt(NetworkManager::WirelessSecuritySetting::WpaEap); } m_tmpConnectionUuid = settings->uuid(); m_tmpDevicePath = device; m_tmpSpecificPath = specificObject; QPointer editor = new ConnectionEditorDialog(settings); editor->show(); KWindowSystem::setState(editor->winId(), NET::KeepAbove); KWindowSystem::forceActiveWindow(editor->winId()); connect(editor.data(), &ConnectionEditorDialog::accepted, [editor, this] () { addConnection(editor->setting()); }); connect(editor.data(), &ConnectionEditorDialog::finished, [editor] () { if (editor) { editor->deleteLater(); } }); editor->setModal(true); editor->show(); } else { if (securityType == NetworkManager::StaticWep) { wifiSecurity->setKeyMgmt(NetworkManager::WirelessSecuritySetting::Wep); wifiSecurity->setWepKey0(password); if (KWallet::Wallet::isEnabled()) { wifiSecurity->setWepKeyFlags(NetworkManager::Setting::AgentOwned); } } else { if (ap->mode() == NetworkManager::AccessPoint::Adhoc) { wifiSecurity->setKeyMgmt(NetworkManager::WirelessSecuritySetting::WpaNone); } else { wifiSecurity->setKeyMgmt(NetworkManager::WirelessSecuritySetting::WpaPsk); } wifiSecurity->setPsk(password); if (KWallet::Wallet::isEnabled()) { wifiSecurity->setPskFlags(NetworkManager::Setting::AgentOwned); } } QDBusPendingReply reply = NetworkManager::addAndActivateConnection(settings->toMap(), device, specificObject); QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this); watcher->setProperty("action", Handler::AddAndActivateConnection); watcher->setProperty("connection", settings->name()); connect(watcher, &QDBusPendingCallWatcher::finished, this, &Handler::replyFinished); } settings.clear(); } void Handler::addConnection(const NMVariantMapMap& map) { QDBusPendingReply reply = NetworkManager::addConnection(map); QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this); watcher->setProperty("action", AddConnection); watcher->setProperty("connection", map.value("connection").value("id")); connect(watcher, &QDBusPendingCallWatcher::finished, this, &Handler::replyFinished); } void Handler::deactivateConnection(const QString& connection, const QString& device) { NetworkManager::Connection::Ptr con = NetworkManager::findConnection(connection); if (!con) { qCWarning(PLASMA_NM) << "Not possible to deactivate this connection"; return; } QDBusPendingReply<> reply; for (const NetworkManager::ActiveConnection::Ptr &active : NetworkManager::activeConnections()) { if (active->uuid() == con->uuid() && ((!active->devices().isEmpty() && active->devices().first() == device) || active->vpn())) { if (active->vpn()) { reply = NetworkManager::deactivateConnection(active->path()); } else { NetworkManager::Device::Ptr device = NetworkManager::findNetworkInterface(active->devices().first()); if (device) { reply = device->disconnectInterface(); } } } } QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this); watcher->setProperty("action", Handler::DeactivateConnection); connect(watcher, &QDBusPendingCallWatcher::finished, this, &Handler::replyFinished); } void Handler::disconnectAll() { for (const NetworkManager::Device::Ptr &device : NetworkManager::networkInterfaces()) { device->disconnectInterface(); } } void Handler::enableAirplaneMode(bool enable) { if (enable) { m_tmpWirelessEnabled = NetworkManager::isWirelessEnabled(); m_tmpWwanEnabled = NetworkManager::isWwanEnabled(); enableBluetooth(false); enableWireless(false); enableWwan(false); } else { enableBluetooth(true); if (m_tmpWirelessEnabled) { enableWireless(true); } if (m_tmpWwanEnabled) { enableWwan(true); } } } void Handler::enableBluetooth(bool enable) { qDBusRegisterMetaType< QMap >(); QDBusMessage message = QDBusMessage::createMethodCall("org.bluez", "/", "org.freedesktop.DBus.ObjectManager", "GetManagedObjects"); QDBusPendingReply > reply = QDBusConnection::systemBus().asyncCall(message); QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this); connect(watcher, &QDBusPendingCallWatcher::finished, [this, enable] (QDBusPendingCallWatcher *watcher) { QDBusPendingReply > reply = *watcher; if (reply.isValid()) { for (const QDBusObjectPath &path : reply.value().keys()) { const QString objPath = path.path(); qCDebug(PLASMA_NM) << "inspecting path" << objPath; const QStringList interfaces = reply.value().value(path).keys(); qCDebug(PLASMA_NM) << "interfaces:" << interfaces; if (interfaces.contains("org.bluez.Adapter1")) { // We need to check previous state first if (!enable) { QDBusMessage message = QDBusMessage::createMethodCall("org.bluez", objPath, "org.freedesktop.DBus.Properties", "Get"); QList arguments; arguments << QLatin1String("org.bluez.Adapter1"); arguments << QLatin1String("Powered"); message.setArguments(arguments); QDBusPendingReply getReply = QDBusConnection::systemBus().asyncCall(message); QDBusPendingCallWatcher *getWatcher = new QDBusPendingCallWatcher(getReply, this); connect(getWatcher, &QDBusPendingCallWatcher::finished, [this, objPath] (QDBusPendingCallWatcher *watcher) { QDBusPendingReply reply = *watcher; if (reply.isValid()) { m_bluetoothAdapters.insert(objPath, reply.value().toBool()); QDBusMessage message = QDBusMessage::createMethodCall("org.bluez", objPath, "org.freedesktop.DBus.Properties", "Set"); QList arguments; arguments << QLatin1String("org.bluez.Adapter1"); arguments << QLatin1String("Powered"); arguments << QVariant::fromValue(QDBusVariant(QVariant(false))); message.setArguments(arguments); QDBusConnection::systemBus().asyncCall(message); } watcher->deleteLater(); }); } else if (enable && m_bluetoothAdapters.value(objPath)) { QDBusMessage message = QDBusMessage::createMethodCall("org.bluez", objPath, "org.freedesktop.DBus.Properties", "Set"); QList arguments; arguments << QLatin1String("org.bluez.Adapter1"); arguments << QLatin1String("Powered"); arguments << QVariant::fromValue(QDBusVariant(QVariant(enable))); message.setArguments(arguments); QDBusConnection::systemBus().asyncCall(message); } } } } watcher->deleteLater(); }); } void Handler::enableNetworking(bool enable) { NetworkManager::setNetworkingEnabled(enable); } void Handler::enableWireless(bool enable) { NetworkManager::setWirelessEnabled(enable); } void Handler::enableWwan(bool enable) { NetworkManager::setWwanEnabled(enable); } void Handler::removeConnection(const QString& connection) { NetworkManager::Connection::Ptr con = NetworkManager::findConnection(connection); if (!con || con->uuid().isEmpty()) { qCWarning(PLASMA_NM) << "Not possible to remove connection " << connection; return; } // Remove slave connections for (const NetworkManager::Connection::Ptr &connection : NetworkManager::listConnections()) { NetworkManager::ConnectionSettings::Ptr settings = connection->settings(); if (settings->master() == con->uuid()) { connection->remove(); } } QDBusPendingReply<> reply = con->remove(); QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this); watcher->setProperty("action", Handler::RemoveConnection); watcher->setProperty("connection", con->name()); connect(watcher, &QDBusPendingCallWatcher::finished, this, &Handler::replyFinished); } void Handler::updateConnection(const NetworkManager::Connection::Ptr& connection, const NMVariantMapMap& map) { QDBusPendingReply<> reply = connection->update(map); QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this); watcher->setProperty("action", UpdateConnection); watcher->setProperty("connection", connection->name()); connect(watcher, &QDBusPendingCallWatcher::finished, this, &Handler::replyFinished); } void Handler::requestScan(const QString &interface) { for (NetworkManager::Device::Ptr device : NetworkManager::networkInterfaces()) { if (device->type() == NetworkManager::Device::Wifi) { NetworkManager::WirelessDevice::Ptr wifiDevice = device.objectCast(); if (wifiDevice && wifiDevice->state() != NetworkManager::WirelessDevice::Unavailable) { if (!interface.isEmpty() && interface != wifiDevice->interfaceName()) { continue; } if (!checkRequestScanRateLimit(wifiDevice)) { QDateTime now = QDateTime::currentDateTime(); // for NM < 1.12, lastScan is not available QDateTime lastScan = wifiDevice->lastScan(); QDateTime lastRequestScan = wifiDevice->lastRequestScan(); // Compute the next time we can run a scan int timeout = NM_REQUESTSCAN_LIMIT_RATE; if (lastScan.isValid() && lastScan.msecsTo(now) < NM_REQUESTSCAN_LIMIT_RATE) { timeout = NM_REQUESTSCAN_LIMIT_RATE - lastScan.msecsTo(now); } else if (lastRequestScan.isValid() && lastRequestScan.msecsTo(now) < NM_REQUESTSCAN_LIMIT_RATE) { timeout = NM_REQUESTSCAN_LIMIT_RATE - lastRequestScan.msecsTo(now); } qCDebug(PLASMA_NM) << "Rescheduling a request scan for" << wifiDevice->interfaceName() << "in" << timeout; scheduleRequestScan(wifiDevice->interfaceName(), timeout); if (!interface.isEmpty()) { return; } continue; } else if (m_wirelessScanRetryTimer.contains(interface)){ m_wirelessScanRetryTimer.value(interface)->stop(); delete m_wirelessScanRetryTimer.take(interface); } qCDebug(PLASMA_NM) << "Requesting wifi scan on device" << wifiDevice->interfaceName(); QDBusPendingReply<> reply = wifiDevice->requestScan(); QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this); watcher->setProperty("action", Handler::RequestScan); watcher->setProperty("interface", wifiDevice->interfaceName()); connect(watcher, &QDBusPendingCallWatcher::finished, this, &Handler::replyFinished); } } } } bool Handler::checkRequestScanRateLimit(const NetworkManager::WirelessDevice::Ptr &wifiDevice) { QDateTime now = QDateTime::currentDateTime(); QDateTime lastScan = wifiDevice->lastScan(); QDateTime lastRequestScan = wifiDevice->lastRequestScan(); // if the last scan finished within the last 10 seconds bool ret = lastScan.isValid() && lastScan.msecsTo(now) < NM_REQUESTSCAN_LIMIT_RATE; // or if the last Request was sent within the last 10 seconds ret |= lastRequestScan.isValid() && lastRequestScan.msecsTo(now) < NM_REQUESTSCAN_LIMIT_RATE; // skip the request scan if (ret) { qCDebug(PLASMA_NM) << "Last scan finished " << lastScan.msecsTo(now) << "ms ago and last request scan was sent " << lastRequestScan.msecsTo(now) << "ms ago, Skipping scanning interface:" << wifiDevice->interfaceName(); return false; } return true; } void Handler::scheduleRequestScan(const QString &interface, int timeout) { QTimer *timer; if (!m_wirelessScanRetryTimer.contains(interface)) { // create a timer for the interface timer = new QTimer(); timer->setSingleShot(true); m_wirelessScanRetryTimer.insert(interface, timer); auto retryAction = [this, interface]() { requestScan(interface); }; connect(timer, &QTimer::timeout, this, retryAction); } else { // set the new value for an existing timer timer = m_wirelessScanRetryTimer.value(interface); if (timer->isActive()) { timer->stop(); } } // +1 ms is added to avoid having the scan being rejetted by nm // because it is run at the exact last millisecond of the requestScan threshold timer->setInterval(timeout + 1); timer->start(); } void Handler::scanRequestFailed(const QString &interface) { scheduleRequestScan(interface, 2000); } void Handler::initKdedModule() { QDBusMessage initMsg = QDBusMessage::createMethodCall(QStringLiteral(AGENT_SERVICE), QStringLiteral(AGENT_PATH), QStringLiteral(AGENT_IFACE), QStringLiteral("init")); QDBusConnection::sessionBus().send(initMsg); } void Handler::secretAgentError(const QString &connectionPath, const QString &message) { // If the password was wrong, forget it removeConnection(connectionPath); emit connectionActivationFailed(connectionPath, message); } void Handler::replyFinished(QDBusPendingCallWatcher * watcher) { QDBusPendingReply<> reply = *watcher; if (reply.isError() || !reply.isValid()) { KNotification *notification = nullptr; QString error = reply.error().message(); Handler::HandlerAction action = (Handler::HandlerAction)watcher->property("action").toUInt(); switch (action) { case Handler::ActivateConnection: notification = new KNotification("FailedToActivateConnection", KNotification::CloseOnTimeout, this); notification->setTitle(i18n("Failed to activate %1", watcher->property("connection").toString())); break; case Handler::AddAndActivateConnection: notification = new KNotification("FailedToAddConnection", KNotification::CloseOnTimeout, this); notification->setTitle(i18n("Failed to add %1", watcher->property("connection").toString())); break; case Handler::AddConnection: notification = new KNotification("FailedToAddConnection", KNotification::CloseOnTimeout, this); notification->setTitle(i18n("Failed to add connection %1", watcher->property("connection").toString())); break; case Handler::DeactivateConnection: notification = new KNotification("FailedToDeactivateConnection", KNotification::CloseOnTimeout, this); notification->setTitle(i18n("Failed to deactivate %1", watcher->property("connection").toString())); break; case Handler::RemoveConnection: notification = new KNotification("FailedToRemoveConnection", KNotification::CloseOnTimeout, this); notification->setTitle(i18n("Failed to remove %1", watcher->property("connection").toString())); break; case Handler::UpdateConnection: notification = new KNotification("FailedToUpdateConnection", KNotification::CloseOnTimeout, this); notification->setTitle(i18n("Failed to update connection %1", watcher->property("connection").toString())); break; case Handler::RequestScan: { const QString interface = watcher->property("interface").toString(); qCWarning(PLASMA_NM) << "Wireless scan on" << interface << "failed:" << error; scanRequestFailed(interface); break; } default: break; } if (notification) { notification->setComponentName("networkmanagement"); notification->setText(error); - notification->setPixmap(QIcon::fromTheme("dialog-warning").pixmap(KIconLoader::SizeHuge)); + notification->setIconName(QStringLiteral("dialog-warning")); notification->sendEvent(); } } else { KNotification *notification = nullptr; Handler::HandlerAction action = (Handler::HandlerAction)watcher->property("action").toUInt(); switch (action) { case Handler::AddConnection: notification = new KNotification("ConnectionAdded", KNotification::CloseOnTimeout, this); notification->setText(i18n("Connection %1 has been added", watcher->property("connection").toString())); break; case Handler::RemoveConnection: notification = new KNotification("ConnectionRemoved", KNotification::CloseOnTimeout, this); notification->setText(i18n("Connection %1 has been removed", watcher->property("connection").toString())); break; case Handler::UpdateConnection: notification = new KNotification("ConnectionUpdated", KNotification::CloseOnTimeout, this); notification->setText(i18n("Connection %1 has been updated", watcher->property("connection").toString())); break; case Handler::RequestScan: qCDebug(PLASMA_NM) << "Wireless scan on" << watcher->property("interface").toString() << "succeeded"; break; default: break; } if (notification) { notification->setComponentName("networkmanagement"); notification->setTitle(watcher->property("connection").toString()); - notification->setPixmap(QIcon::fromTheme("dialog-information").pixmap(KIconLoader::SizeHuge)); + notification->setIconName(QStringLiteral("dialog-information")); notification->sendEvent(); } } watcher->deleteLater(); } #if WITH_MODEMMANAGER_SUPPORT void Handler::unlockRequiredChanged(MMModemLock modemLock) { if (modemLock == MM_MODEM_LOCK_NONE) { activateConnection(m_tmpConnectionPath, m_tmpDevicePath, m_tmpSpecificPath); } } #endif