diff --git a/applet/contents/ui/Toolbar.qml b/applet/contents/ui/Toolbar.qml index 7f8adbf7..5453cf9b 100644 --- a/applet/contents/ui/Toolbar.qml +++ b/applet/contents/ui/Toolbar.qml @@ -1,171 +1,179 @@ /* Copyright 2013-2017 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 . */ import QtQuick 2.2 import QtQuick.Layouts 1.2 import org.kde.plasma.components 2.0 as PlasmaComponents import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.networkmanagement 0.2 as PlasmaNM import org.kde.kquickcontrolsaddons 2.0 GridLayout { id: toolbar function closeSearch() { searchToggleButton.checked = false } rows: 2 columns: 2 PlasmaCore.Svg { id: lineSvg imagePath: "widgets/line" } PlasmaNM.EnabledConnections { id: enabledConnections onWirelessEnabledChanged: { wifiSwitchButton.checked = wifiSwitchButton.enabled && enabled } onWirelessHwEnabledChanged: { wifiSwitchButton.enabled = enabled && availableDevices.wirelessDeviceAvailable && !planeModeSwitchButton.airplaneModeEnabled } onWwanEnabledChanged: { wwanSwitchButton.checked = wwanSwitchButton.enabled && enabled } onWwanHwEnabledChanged: { wwanSwitchButton.enabled = enabled && availableDevices.modemDeviceAvailable && !planeModeSwitchButton.airplaneModeEnabled } } Row { Layout.fillWidth: true SwitchButton { id: wifiSwitchButton checked: enabled && enabledConnections.wirelessEnabled enabled: enabledConnections.wirelessHwEnabled && availableDevices.wirelessDeviceAvailable && !planeModeSwitchButton.airplaneModeEnabled tooltip: i18n("Enable wireless") icon: enabled ? "network-wireless-on" : "network-wireless-off" visible: availableDevices.wirelessDeviceAvailable onClicked: { handler.enableWireless(checked); } } SwitchButton { id: wwanSwitchButton checked: enabled && enabledConnections.wwanEnabled enabled: enabledConnections.wwanHwEnabled && availableDevices.modemDeviceAvailable && !planeModeSwitchButton.airplaneModeEnabled tooltip: i18n("Enable mobile network") icon: enabled ? "network-mobile-on" : "network-mobile-off" visible: availableDevices.modemDeviceAvailable onClicked: { handler.enableWwan(checked); } } SwitchButton { id: planeModeSwitchButton + property bool initialized: false property bool airplaneModeEnabled: false checked: airplaneModeEnabled tooltip: i18n("Enable airplane mode") icon: airplaneModeEnabled ? "network-flightmode-on" : "network-flightmode-off" + visible: availableDevices.modemDeviceAvailable || availableDevices.wirelessDeviceAvailable onClicked: { handler.enableAirplaneMode(checked); airplaneModeEnabled = !airplaneModeEnabled; } Binding { - target: connectionIconProvider - property: "airplaneMode" + target: configuration + property: "airplaneModeEnabled" value: planeModeSwitchButton.airplaneModeEnabled + when: planeModeSwitchButton.initialized + } + + Component.onCompleted: { + airplaneModeEnabled = configuration.airplaneModeEnabled + initialized = true } } } Row { Layout.column: 1 PlasmaComponents.ToolButton { id: searchToggleButton iconSource: "search" tooltip: i18ndc("plasma-nm", "button tooltip", "Search the connections") checkable: true } PlasmaComponents.ToolButton { id: openEditorButton iconSource: "configure" tooltip: i18n("Configure network connections...") visible: mainWindow.kcmAuthorized onClicked: { KCMShell.open(mainWindow.kcm) } } } PlasmaComponents.TextField { id: searchTextField Layout.row: 1 Layout.columnSpan: 2 Layout.fillWidth: true Layout.leftMargin: units.smallSpacing Layout.rightMargin: units.smallSpacing Layout.bottomMargin: units.smallSpacing focus: true clearButtonShown: true placeholderText: i18ndc("plasma-nm", "text field placeholder text", "Search...") visible: searchToggleButton.checked onVisibleChanged: if (!visible) text = "" Keys.onEscapePressed: { //Check if the searchbar is actually visible before accepting the escape key. Otherwise, the escape key cannot dismiss the applet until one interacts with some other element. if (searchToggleButton.checked) { searchToggleButton.checked = false; } else { event.accepted = false; } } onTextChanged: { // Show search field when starting to type directly if (text.length && !searchToggleButton.checked) { searchToggleButton.checked = true } appletProxyModel.setFilterRegExp(text) } } } diff --git a/applet/contents/ui/main.qml b/applet/contents/ui/main.qml index 67d18407..5ba6877c 100644 --- a/applet/contents/ui/main.qml +++ b/applet/contents/ui/main.qml @@ -1,90 +1,91 @@ /* Copyright 2013-2017 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 . */ import QtQuick 2.2 import org.kde.plasma.plasmoid 2.0 import org.kde.plasma.networkmanagement 0.2 as PlasmaNM import org.kde.kquickcontrolsaddons 2.0 import QtQuick.Layouts 1.1 Item { id: mainWindow property bool showSections: true readonly property string kcm: "kcm_networkmanagement.desktop" readonly property bool kcmAuthorized: KCMShell.authorize(kcm).length == 1 Plasmoid.toolTipMainText: i18n("Networks") Plasmoid.toolTipSubText: networkStatus.activeConnections Plasmoid.icon: connectionIconProvider.connectionTooltipIcon Plasmoid.switchWidth: units.gridUnit * 10 Plasmoid.switchHeight: units.gridUnit * 10 Plasmoid.compactRepresentation: CompactRepresentation { } Plasmoid.fullRepresentation: PopupDialog { id: dialogItem Layout.minimumWidth: units.iconSizes.medium * 10 Layout.minimumHeight: units.gridUnit * 20 anchors.fill: parent focus: true } function action_openKCM() { KCMShell.open(kcm) } Component.onCompleted: { if (kcmAuthorized) { plasmoid.setAction("openKCM", i18n("&Configure Network Connections..."), "preferences-system-network"); } } PlasmaNM.NetworkStatus { id: networkStatus } PlasmaNM.ConnectionIcon { id: connectionIconProvider } PlasmaNM.Handler { id: handler onWirelessScanTimerEnabled: { if (enabled) { scanTimer.restart() } else { scanTimer.stop() } } } Timer { id: scanTimer interval: 15000 repeat: true running: plasmoid.expanded onTriggered: handler.requestScan() } PlasmaNM.Configuration { + id: configuration unlockModemOnDetection: plasmoid.configuration.unlockModemOnDetection manageVirtualConnections: plasmoid.configuration.manageVirtualConnections } } diff --git a/libs/configuration.cpp b/libs/configuration.cpp index ea9ebf52..1dec19c2 100644 --- a/libs/configuration.cpp +++ b/libs/configuration.cpp @@ -1,78 +1,110 @@ /* Copyright 2017 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 "configuration.h" #include #include Q_GLOBAL_STATIC_WITH_ARGS(KSharedConfigPtr, config, (KSharedConfig::openConfig(QLatin1String("plasma-nm")))) bool Configuration::unlockModemOnDetection() { KConfigGroup grp(*config, QLatin1String("General")); if (grp.isValid()) { return grp.readEntry(QLatin1String("UnlockModemOnDetection"), true); } return true; } void Configuration::setUnlockModemOnDetection(bool unlock) { KConfigGroup grp(*config, QLatin1String("General")); if (grp.isValid()) { grp.writeEntry(QLatin1String("UnlockModemOnDetection"), unlock); } } bool Configuration::manageVirtualConnections() { KConfigGroup grp(*config, QLatin1String("General")); if (grp.isValid()) { return grp.readEntry(QLatin1String("ManageVirtualConnections"), false); } return true; } void Configuration::setManageVirtualConnections(bool manage) { KConfigGroup grp(*config, QLatin1String("General")); if (grp.isValid()) { grp.writeEntry(QLatin1String("ManageVirtualConnections"), manage); } } +bool Configuration::airplaneModeEnabled() +{ + // Check whether other devices are disabled to assume airplane mode is enabled + // after suspend + const bool isWifiDisabled = !NetworkManager::isWirelessEnabled() || !NetworkManager::isWirelessHardwareEnabled(); + const bool isWwanDisabled = !NetworkManager::isWwanEnabled() || !NetworkManager::isWwanHardwareEnabled(); + + KConfigGroup grp(*config, QLatin1String("General")); + + if (grp.isValid()) { + if (grp.readEntry(QLatin1String("AirplaneModeEnabled"), false)) { + // We can assume that airplane mode is still activated after resume + if (isWifiDisabled && isWwanDisabled) + return true; + else { + setAirplaneModeEnabled(false); + } + } + } + + return false; +} + +void Configuration::setAirplaneModeEnabled(bool enabled) +{ + KConfigGroup grp(*config, QLatin1String("General")); + + if (grp.isValid()) { + grp.writeEntry(QLatin1String("AirplaneModeEnabled"), enabled); + } +} + bool Configuration::showPasswordDialog() { KConfigGroup grp(*config, QLatin1String("General")); if (grp.isValid()) { return grp.readEntry(QLatin1String("ShowPasswordDialog"), true); } return true; } diff --git a/libs/configuration.h b/libs/configuration.h index 6c2a1231..b2192f85 100644 --- a/libs/configuration.h +++ b/libs/configuration.h @@ -1,46 +1,51 @@ /* Copyright 2017 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 . */ #ifndef PLASMA_NM_CONFIGURATION_H #define PLASMA_NM_CONFIGURATION_H #include #include class Q_DECL_EXPORT Configuration : public QObject { Q_PROPERTY(bool unlockModemOnDetection READ unlockModemOnDetection WRITE setUnlockModemOnDetection) Q_PROPERTY(bool manageVirtualConnections READ manageVirtualConnections WRITE setManageVirtualConnections) + Q_PROPERTY(bool airplaneModeEnabled READ airplaneModeEnabled WRITE setAirplaneModeEnabled) + //Readonly constant property, as this value should only be set by the platform Q_PROPERTY(bool showPasswordDialog READ showPasswordDialog CONSTANT) Q_OBJECT public: static bool unlockModemOnDetection(); static void setUnlockModemOnDetection(bool unlock); static bool manageVirtualConnections(); static void setManageVirtualConnections(bool manage); + static bool airplaneModeEnabled(); + static void setAirplaneModeEnabled(bool enabled); + static bool showPasswordDialog(); }; #endif // PLAMA_NM_CONFIGURATION_H diff --git a/libs/declarative/connectionicon.cpp b/libs/declarative/connectionicon.cpp index d4ba2e3e..798fdbd7 100644 --- a/libs/declarative/connectionicon.cpp +++ b/libs/declarative/connectionicon.cpp @@ -1,651 +1,636 @@ /* 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 "connectionicon.h" +#include "configuration.h" #include "uiutils.h" #include #include #include #include #include #include #include #include #include #if WITH_MODEMMANAGER_SUPPORT #include #include #endif ConnectionIcon::ConnectionIcon(QObject* parent) : QObject(parent) , m_signal(0) , m_wirelessNetwork(nullptr) , m_connecting(false) , m_limited(false) , m_vpn(false) - , m_airplaneMode(false) #if WITH_MODEMMANAGER_SUPPORT , m_modemNetwork(nullptr) #endif { connect(NetworkManager::notifier(), &NetworkManager::Notifier::primaryConnectionChanged, this, &ConnectionIcon::primaryConnectionChanged); connect(NetworkManager::notifier(), &NetworkManager::Notifier::activatingConnectionChanged, this, &ConnectionIcon::activatingConnectionChanged); connect(NetworkManager::notifier(), &NetworkManager::Notifier::activeConnectionAdded, this, &ConnectionIcon::activeConnectionAdded); connect(NetworkManager::notifier(), &NetworkManager::Notifier::connectivityChanged, this, &ConnectionIcon::connectivityChanged); connect(NetworkManager::notifier(), &NetworkManager::Notifier::deviceAdded, this, &ConnectionIcon::deviceAdded); connect(NetworkManager::notifier(), &NetworkManager::Notifier::deviceRemoved, this, &ConnectionIcon::deviceRemoved); connect(NetworkManager::notifier(), &NetworkManager::Notifier::networkingEnabledChanged, this, &ConnectionIcon::networkingEnabledChanged); connect(NetworkManager::notifier(), &NetworkManager::Notifier::statusChanged, this, &ConnectionIcon::statusChanged); connect(NetworkManager::notifier(), &NetworkManager::Notifier::wirelessEnabledChanged, this, &ConnectionIcon::wirelessEnabledChanged); connect(NetworkManager::notifier(), &NetworkManager::Notifier::wirelessHardwareEnabledChanged, this, &ConnectionIcon::wirelessEnabledChanged); connect(NetworkManager::notifier(), &NetworkManager::Notifier::wwanEnabledChanged, this, &ConnectionIcon::wwanEnabledChanged); connect(NetworkManager::notifier(), &NetworkManager::Notifier::wwanHardwareEnabledChanged, this, &ConnectionIcon::wwanEnabledChanged); for (const NetworkManager::Device::Ptr &device : NetworkManager::networkInterfaces()) { if (device->type() == NetworkManager::Device::Ethernet) { NetworkManager::WiredDevice::Ptr wiredDevice = device.staticCast(); if (wiredDevice) { connect(wiredDevice.data(), &NetworkManager::WiredDevice::carrierChanged, this, &ConnectionIcon::carrierChanged); } } else if (device->type() == NetworkManager::Device::Wifi) { NetworkManager::WirelessDevice::Ptr wifiDevice = device.staticCast(); if (wifiDevice) { connect(wifiDevice.data(), &NetworkManager::WirelessDevice::availableConnectionAppeared, this, &ConnectionIcon::wirelessNetworkAppeared); connect(wifiDevice.data(), &NetworkManager::WirelessDevice::networkAppeared, this, &ConnectionIcon::wirelessNetworkAppeared); } } } for (const NetworkManager::ActiveConnection::Ptr &activeConnection : NetworkManager::activeConnections()) { addActiveConnection(activeConnection->path()); } setStates(); connectivityChanged(); setIcons(); } ConnectionIcon::~ConnectionIcon() { } bool ConnectionIcon::connecting() const { return m_connecting; } QString ConnectionIcon::connectionIcon() const { if (m_vpn && !m_connectionIcon.contains("available")) { return m_connectionIcon + "-locked"; } if (m_limited && !m_connectionIcon.contains("available")) { return m_connectionIcon + "-limited"; } return m_connectionIcon; } QString ConnectionIcon::connectionTooltipIcon() const { return m_connectionTooltipIcon; } -bool ConnectionIcon::airplaneMode() const -{ - return m_airplaneMode; -} - -void ConnectionIcon::setAirplaneMode(bool airplaneMode) -{ - if (m_airplaneMode != airplaneMode) { - m_airplaneMode = airplaneMode; - Q_EMIT airplaneModeChanged(airplaneMode); - - setIcons(); - } -} - void ConnectionIcon::activatingConnectionChanged(const QString& connection) { Q_UNUSED(connection); setIcons(); } void ConnectionIcon::addActiveConnection(const QString &activeConnection) { NetworkManager::ActiveConnection::Ptr active = NetworkManager::findActiveConnection(activeConnection); if (active) { NetworkManager::VpnConnection::Ptr vpnConnection; connect(active.data(), &NetworkManager::ActiveConnection::destroyed, this, &ConnectionIcon::activeConnectionDestroyed); if (active->vpn()) { vpnConnection = active.objectCast(); connect(vpnConnection.data(), &NetworkManager::VpnConnection::stateChanged, this, &ConnectionIcon::vpnConnectionStateChanged); } else { connect(active.data(), &NetworkManager::ActiveConnection::stateChanged, this, &ConnectionIcon::activeConnectionStateChanged, Qt::UniqueConnection); } } } void ConnectionIcon::activeConnectionAdded(const QString &activeConnection) { addActiveConnection(activeConnection); setStates(); } void ConnectionIcon::activeConnectionStateChanged(NetworkManager::ActiveConnection::State state) { Q_UNUSED(state); setStates(); } void ConnectionIcon::activeConnectionDestroyed() { setStates(); } void ConnectionIcon::carrierChanged(bool carrier) { Q_UNUSED(carrier); setIcons(); } void ConnectionIcon::connectivityChanged() { NetworkManager::Connectivity conn = NetworkManager::connectivity(); setLimited(conn == NetworkManager::Portal || conn == NetworkManager::Limited); } void ConnectionIcon::deviceAdded(const QString& device) { NetworkManager::Device::Ptr dev = NetworkManager::findNetworkInterface(device); if (!dev) { return; } if (dev->type() == NetworkManager::Device::Ethernet) { NetworkManager::WiredDevice::Ptr wiredDev = dev.objectCast(); connect(wiredDev.data(), &NetworkManager::WiredDevice::carrierChanged, this, &ConnectionIcon::carrierChanged); } } void ConnectionIcon::deviceRemoved(const QString& device) { Q_UNUSED(device); if (NetworkManager::status() == NetworkManager::Disconnected) { setDisconnectedIcon(); } } #if WITH_MODEMMANAGER_SUPPORT void ConnectionIcon::modemNetworkRemoved() { m_modemNetwork.clear(); } void ConnectionIcon::modemSignalChanged(const ModemManager::SignalQualityPair &signalQuality) { int diff = m_signal - signalQuality.signal; if (diff >= 10 || diff <= -10) { m_signal = signalQuality.signal; setIconForModem(); } } #endif void ConnectionIcon::networkingEnabledChanged(bool enabled) { if (!enabled) { setConnectionIcon("network-unavailable"); } } void ConnectionIcon::primaryConnectionChanged(const QString& connection) { if (!connection.isEmpty()) { setIcons(); } } void ConnectionIcon::statusChanged(NetworkManager::Status status) { if (status == NetworkManager::Disconnected) { setDisconnectedIcon(); } } void ConnectionIcon::vpnConnectionStateChanged(NetworkManager::VpnConnection::State state, NetworkManager::VpnConnection::StateChangeReason reason) { Q_UNUSED(state); Q_UNUSED(reason); setStates(); setIcons(); } void ConnectionIcon::wirelessEnabledChanged(bool enabled) { Q_UNUSED(enabled); setIcons(); } void ConnectionIcon::wwanEnabledChanged(bool enabled) { Q_UNUSED(enabled); setIcons(); } void ConnectionIcon::wirelessNetworkAppeared(const QString& network) { Q_UNUSED(network); setIcons(); } void ConnectionIcon::setStates() { bool connecting = false; bool vpn = false; for (const NetworkManager::ActiveConnection::Ptr &activeConnection : NetworkManager::activeConnections()) { NetworkManager::VpnConnection::Ptr vpnConnection; if (activeConnection->vpn()) { vpnConnection = activeConnection.objectCast(); } if (!vpnConnection) { if (activeConnection->state() == NetworkManager::ActiveConnection::Activating && UiUtils::isConnectionTypeSupported(activeConnection->type())) { connecting = true; } if (activeConnection->type() == NetworkManager::ConnectionSettings::ConnectionType::WireGuard) { vpn = true; } } else { if (vpnConnection->state() == NetworkManager::VpnConnection::Activated) { vpn = true; } else if (vpnConnection->state() == NetworkManager::VpnConnection::Prepare || vpnConnection->state() == NetworkManager::VpnConnection::NeedAuth || vpnConnection->state() == NetworkManager::VpnConnection::Connecting || vpnConnection->state() == NetworkManager::VpnConnection::GettingIpConfig) { connecting = true; } } } setVpn(vpn); setConnecting(connecting); } void ConnectionIcon::setIcons() { m_signal = 0; #if WITH_MODEMMANAGER_SUPPORT if (m_modemNetwork) { disconnect(m_modemNetwork.data(), nullptr, this, nullptr); m_modemNetwork.clear(); } #endif if (m_wirelessNetwork) { disconnect(m_wirelessNetwork.data(), nullptr, this, nullptr); m_wirelessNetwork.clear(); } NetworkManager::ActiveConnection::Ptr connection = NetworkManager::activatingConnection(); // Set icon based on the current primary connection if the activating connection is virtual // since we're not setting icons for virtual connections if (!connection || (connection && UiUtils::isConnectionTypeVirtual(connection->type()))) { connection = NetworkManager::primaryConnection(); } /* Fallback: If we still don't have an active connection with default route or the default route goes through a connection of generic type (some type of VPNs) we need to go through all other active connections and pick the one with highest probability of being the main one (order is: vpn, wired, wireless, gsm, cdma, bluetooth) */ if ((!connection && !NetworkManager::activeConnections().isEmpty()) || (connection && connection->type() == NetworkManager::ConnectionSettings::Generic) || (connection && connection->type() == NetworkManager::ConnectionSettings::Tun)) { for (const NetworkManager::ActiveConnection::Ptr &activeConnection : NetworkManager::activeConnections()) { const NetworkManager::ConnectionSettings::ConnectionType type = activeConnection->type(); if (type == NetworkManager::ConnectionSettings::Bluetooth) { if (connection && connection->type() <= NetworkManager::ConnectionSettings::Bluetooth) { connection = activeConnection; } } else if (type == NetworkManager::ConnectionSettings::Cdma) { if (connection && connection->type() <= NetworkManager::ConnectionSettings::Cdma) { connection = activeConnection; } } else if (type == NetworkManager::ConnectionSettings::Gsm) { if (connection && connection->type() <= NetworkManager::ConnectionSettings::Gsm) { connection = activeConnection; } } else if (type == NetworkManager::ConnectionSettings::Vpn) { connection = activeConnection; } else if (type == NetworkManager::ConnectionSettings::WireGuard) { connection = activeConnection; } else if (type == NetworkManager::ConnectionSettings::Wired) { if (connection && (connection->type() != NetworkManager::ConnectionSettings::Vpn || connection->type() != NetworkManager::ConnectionSettings::WireGuard)) { connection = activeConnection; } } else if (type == NetworkManager::ConnectionSettings::Wireless) { if (connection && (connection->type() != NetworkManager::ConnectionSettings::Vpn && (connection->type() != NetworkManager::ConnectionSettings::Wired))) { connection = activeConnection; } } } } if (connection && !connection->devices().isEmpty()) { NetworkManager::Device::Ptr device = NetworkManager::findNetworkInterface(connection->devices().first()); if (device) { NetworkManager::Device::Type type = device->type(); if (type == NetworkManager::Device::Wifi) { NetworkManager::WirelessDevice::Ptr wifiDevice = device.objectCast(); if (wifiDevice->mode() == NetworkManager::WirelessDevice::Adhoc) { setWirelessIconForSignalStrength(100); } else { NetworkManager::AccessPoint::Ptr ap = wifiDevice->activeAccessPoint(); if (ap) { setWirelessIcon(device, ap->ssid()); } } } else if (type == NetworkManager::Device::Ethernet) { setConnectionIcon("network-wired-activated"); setConnectionTooltipIcon("network-wired-activated"); } else if (type == NetworkManager::Device::Modem) { #if WITH_MODEMMANAGER_SUPPORT setModemIcon(device); #else setConnectionIcon("network-mobile-0"); setConnectionTooltipIcon("phone"); #endif } else if (type == NetworkManager::Device::Bluetooth) { NetworkManager::BluetoothDevice::Ptr btDevice = device.objectCast(); if (btDevice) { if (btDevice->bluetoothCapabilities().testFlag(NetworkManager::BluetoothDevice::Dun)) { #if WITH_MODEMMANAGER_SUPPORT setModemIcon(device); #else setConnectionIcon("network-mobile-0"); setConnectionTooltipIcon("phone"); #endif } else { setConnectionIcon("network-bluetooth-activated"); setConnectionTooltipIcon("preferences-system-bluetooth"); } } } else if (type == 29) { // TODO change to WireGuard enum value once it is added // WireGuard is a VPN but is not implemented // in NetworkManager as a VPN, so we don't want to // do anything just because it has a device // associated with it. } else { // Ignore other devices (bond/bridge/team etc.) setDisconnectedIcon(); } } } else { setDisconnectedIcon(); } } void ConnectionIcon::setDisconnectedIcon() { - if (m_airplaneMode) { + if (Configuration::airplaneModeEnabled()) { setConnectionIcon(QStringLiteral("network-flightmode-on")); return; } if (NetworkManager::status() == NetworkManager::Unknown || NetworkManager::status() == NetworkManager::Asleep) { setConnectionIcon("network-unavailable"); return; } bool wired = false; bool wireless = false; bool modem = false; m_limited = false; m_vpn = false; for (const NetworkManager::Device::Ptr &device : NetworkManager::networkInterfaces()) { if (device->type() == NetworkManager::Device::Ethernet) { NetworkManager::WiredDevice::Ptr wiredDev = device.objectCast(); if (wiredDev->carrier()) { wired = true; } } else if (device->type() == NetworkManager::Device::Wifi && NetworkManager::isWirelessEnabled() && NetworkManager::isWirelessHardwareEnabled()) { NetworkManager::WirelessDevice::Ptr wifiDevice = device.objectCast(); if (!wifiDevice->accessPoints().isEmpty() || !wifiDevice->availableConnections().isEmpty()) { wireless = true; } } else if (device->type() == NetworkManager::Device::Modem && NetworkManager::isWwanEnabled() && NetworkManager::isWwanHardwareEnabled()) { modem = true; } } if (wired) { setConnectionIcon("network-wired-available"); setConnectionTooltipIcon("network-wired"); return; } else if (wireless) { setConnectionIcon("network-wireless-available"); setConnectionTooltipIcon("network-wireless-connected-00"); return; } else if (modem) { setConnectionIcon("network-mobile-available"); setConnectionTooltipIcon("phone"); return; } else { setConnectionIcon("network-unavailable"); setConnectionTooltipIcon("network-wired"); } } #if WITH_MODEMMANAGER_SUPPORT void ConnectionIcon::setModemIcon(const NetworkManager::Device::Ptr & device) { NetworkManager::ModemDevice::Ptr modemDevice = device.objectCast(); if (!modemDevice) { setConnectionIcon("network-mobile-100"); return; } ModemManager::ModemDevice::Ptr modem = ModemManager::findModemDevice(device->udi()); if (modem) { if (modem->hasInterface(ModemManager::ModemDevice::ModemInterface)) { m_modemNetwork = modem->interface(ModemManager::ModemDevice::ModemInterface).objectCast(); } } if (m_modemNetwork) { connect(m_modemNetwork.data(), &ModemManager::Modem::signalQualityChanged, this, &ConnectionIcon::modemSignalChanged, Qt::UniqueConnection); connect(m_modemNetwork.data(), &ModemManager::Modem::accessTechnologiesChanged, this, &ConnectionIcon::setIconForModem, Qt::UniqueConnection); connect(m_modemNetwork.data(), &ModemManager::Modem::destroyed, this, &ConnectionIcon::modemNetworkRemoved); m_signal = m_modemNetwork->signalQuality().signal; setIconForModem(); } else { setConnectionIcon("network-mobile-0"); setConnectionTooltipIcon("phone"); return; } } void ConnectionIcon::setIconForModem() { if (!m_signal) { m_signal = m_modemNetwork->signalQuality().signal; } QString strength = "00"; if (m_signal == 0) { strength = '0'; } else if (m_signal < 20) { strength = "20"; } else if (m_signal < 40) { strength = "40"; } else if (m_signal < 60) { strength = "60"; } else if (m_signal < 80) { strength = "80"; } else { strength = "100"; } QString result; switch(m_modemNetwork->accessTechnologies()) { case MM_MODEM_ACCESS_TECHNOLOGY_GSM: case MM_MODEM_ACCESS_TECHNOLOGY_GSM_COMPACT: result = "network-mobile-%1"; break; case MM_MODEM_ACCESS_TECHNOLOGY_GPRS: result = "network-mobile-%1-gprs"; break; case MM_MODEM_ACCESS_TECHNOLOGY_EDGE: result = "network-mobile-%1-edge"; break; case MM_MODEM_ACCESS_TECHNOLOGY_UMTS: result = "network-mobile-%1-umts"; break; case MM_MODEM_ACCESS_TECHNOLOGY_HSDPA: result = "network-mobile-%1-hsdpa"; break; case MM_MODEM_ACCESS_TECHNOLOGY_HSUPA: result = "network-mobile-%1-hsupa"; break; case MM_MODEM_ACCESS_TECHNOLOGY_HSPA: case MM_MODEM_ACCESS_TECHNOLOGY_HSPA_PLUS: result = "network-mobile-%1-hspa"; break; case MM_MODEM_ACCESS_TECHNOLOGY_LTE: result = "network-mobile-%1-lte"; break; default: result = "network-mobile-%1"; break; } setConnectionIcon(QString(result).arg(strength)); setConnectionTooltipIcon("phone"); } #endif void ConnectionIcon::setWirelessIcon(const NetworkManager::Device::Ptr &device, const QString& ssid) { NetworkManager::WirelessDevice::Ptr wirelessDevice = device.objectCast(); if (device) { m_wirelessNetwork = wirelessDevice->findNetwork(ssid); } else { m_wirelessNetwork.clear(); } if (m_wirelessNetwork) { connect(m_wirelessNetwork.data(), &NetworkManager::WirelessNetwork::signalStrengthChanged, this, &ConnectionIcon::setWirelessIconForSignalStrength, Qt::UniqueConnection); setWirelessIconForSignalStrength(m_wirelessNetwork->signalStrength()); } else { setDisconnectedIcon(); } } void ConnectionIcon::setWirelessIconForSignalStrength(int strength) { int iconStrength = 100; if (strength == 0) { iconStrength = 0; setConnectionTooltipIcon("network-wireless-connected-00"); } else if (strength < 20) { iconStrength = 20; setConnectionTooltipIcon("network-wireless-connected-20"); } else if (strength < 40) { iconStrength = 40; setConnectionTooltipIcon("network-wireless-connected-40"); } else if (strength < 60) { iconStrength = 60; setConnectionTooltipIcon("network-wireless-connected-60"); } else if (strength < 80) { iconStrength = 80; setConnectionTooltipIcon("network-wireless-connected-80"); } else if (strength < 100) { setConnectionTooltipIcon("network-wireless-connected-100"); } QString icon = QString("network-wireless-%1").arg(iconStrength); setConnectionIcon(icon); } void ConnectionIcon::setConnecting(bool connecting) { if (connecting != m_connecting) { m_connecting = connecting; Q_EMIT connectingChanged(m_connecting); } } void ConnectionIcon::setConnectionIcon(const QString & icon) { if (icon != m_connectionIcon) { m_connectionIcon = icon; Q_EMIT connectionIconChanged(connectionIcon()); } } void ConnectionIcon::setConnectionTooltipIcon(const QString & icon) { if (icon != m_connectionTooltipIcon) { m_connectionTooltipIcon = icon; Q_EMIT connectionTooltipIconChanged(m_connectionTooltipIcon); } } void ConnectionIcon::setVpn(bool vpn) { if (m_vpn != vpn) { m_vpn = vpn; Q_EMIT connectionIconChanged(connectionIcon()); } } void ConnectionIcon::setLimited(bool limited) { if (m_limited != limited) { m_limited = limited; Q_EMIT connectionIconChanged(connectionIcon()); } } diff --git a/libs/declarative/connectionicon.h b/libs/declarative/connectionicon.h index 742127df..d1c7defd 100644 --- a/libs/declarative/connectionicon.h +++ b/libs/declarative/connectionicon.h @@ -1,106 +1,100 @@ /* 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 . */ #ifndef PLASMA_NM_CONNECTION_ICON_H #define PLASMA_NM_CONNECTION_ICON_H #include #include #include #include #if WITH_MODEMMANAGER_SUPPORT #include #endif class ConnectionIcon : public QObject { Q_PROPERTY(bool connecting READ connecting NOTIFY connectingChanged) Q_PROPERTY(QString connectionIcon READ connectionIcon NOTIFY connectionIconChanged) Q_PROPERTY(QString connectionTooltipIcon READ connectionTooltipIcon NOTIFY connectionTooltipIconChanged) - -Q_PROPERTY(bool airplaneMode READ airplaneMode WRITE setAirplaneMode NOTIFY airplaneModeChanged) Q_OBJECT public: explicit ConnectionIcon(QObject* parent = nullptr); ~ConnectionIcon() override; bool connecting() const; QString connectionIcon() const; QString connectionTooltipIcon() const; - bool airplaneMode() const; - void setAirplaneMode(bool airplaneMode); - private Q_SLOTS: void activatingConnectionChanged(const QString & connection); void activeConnectionAdded(const QString & activeConnection); void activeConnectionDestroyed(); void activeConnectionStateChanged(NetworkManager::ActiveConnection::State state); void carrierChanged(bool carrier); void connectivityChanged(); void deviceAdded(const QString & device); void deviceRemoved(const QString & device); void networkingEnabledChanged(bool enabled); void primaryConnectionChanged(const QString & connection); #if WITH_MODEMMANAGER_SUPPORT void modemNetworkRemoved(); void modemSignalChanged(const ModemManager::SignalQualityPair &signalQuality); void setIconForModem(); #endif void statusChanged(NetworkManager::Status status); void setWirelessIconForSignalStrength(int strength); void vpnConnectionStateChanged(NetworkManager::VpnConnection::State state, NetworkManager::VpnConnection::StateChangeReason reason); void wirelessEnabledChanged(bool enabled); void wirelessNetworkAppeared(const QString &network); void wwanEnabledChanged(bool enabled); Q_SIGNALS: void connectingChanged(bool connecting); void connectionIconChanged(const QString & icon); void connectionTooltipIconChanged(const QString & icon); void airplaneModeChanged(bool airplaneMode); private: void addActiveConnection(const QString & activeConnection); void setConnecting(bool connecting); void setConnectionIcon(const QString & icon); void setConnectionTooltipIcon(const QString & icon); void setVpn(bool vpn); void setLimited(bool limited); uint m_signal; NetworkManager::WirelessNetwork::Ptr m_wirelessNetwork; bool m_connecting; bool m_limited; bool m_vpn; QString m_connectionIcon; QString m_connectionTooltipIcon; - bool m_airplaneMode; void setDisconnectedIcon(); void setIcons(); void setStates(); void setWirelessIcon(const NetworkManager::Device::Ptr & device, const QString & ssid); #if WITH_MODEMMANAGER_SUPPORT ModemManager::Modem::Ptr m_modemNetwork; void setModemIcon(const NetworkManager::Device::Ptr & device); #endif }; #endif // PLASMA_NM_CONNECTION_ICON_H diff --git a/libs/handler.cpp b/libs/handler.cpp index 54155eab..4bcf9f43 100644 --- a/libs/handler.cpp +++ b/libs/handler.cpp @@ -1,584 +1,583 @@ /* 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 #define AGENT_SERVICE "org.kde.kded5" #define AGENT_PATH "/modules/networkmanagement" #define AGENT_IFACE "org.kde.plasmanetworkmanagement" 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))); // Interval (in ms) between attempts to scan for wifi networks m_wirelessScanRetryTimer.setInterval(2000); m_wirelessScanRetryTimer.setSingleShot(true); } 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->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); } 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 << QLatin1Literal("org.bluez.Adapter1"); arguments << QLatin1Literal("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 << QLatin1Literal("org.bluez.Adapter1"); arguments << QLatin1Literal("Powered"); arguments << QVariant::fromValue(QDBusVariant(QVariant(false))); message.setArguments(arguments); QDBusConnection::systemBus().asyncCall(message); } - + watcher->deleteLater(); }); - getWatcher->deleteLater(); } else if (enable && m_bluetoothAdapters.value(objPath)) { QDBusMessage message = QDBusMessage::createMethodCall("org.bluez", objPath, "org.freedesktop.DBus.Properties", "Set"); QList arguments; arguments << QLatin1Literal("org.bluez.Adapter1"); arguments << QLatin1Literal("Powered"); arguments << QVariant::fromValue(QDBusVariant(QVariant(enable))); message.setArguments(arguments); QDBusConnection::systemBus().asyncCall(message); } } } } + watcher->deleteLater(); }); - 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) { if (!interface.isEmpty() && interface != wifiDevice->interfaceName()) { continue; } 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); } } } } void Handler::scanRequestFailed(const QString &interface) { if (m_wirelessScanRetryTimer.isActive()) { return; } qCDebug(PLASMA_NM) << "Trying soon a new scan on" << interface; emit wirelessScanTimerEnabled(false); auto retryAction = [this,interface]() { m_wirelessScanRetryTimer.disconnect(); requestScan(interface); }; connect(&m_wirelessScanRetryTimer, &QTimer::timeout, this, retryAction); m_wirelessScanRetryTimer.start(); } 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(); qCDebug(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->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"; emit wirelessScanTimerEnabled(true); break; default: break; } if (notification) { notification->setComponentName("networkmanagement"); notification->setTitle(watcher->property("connection").toString()); notification->setPixmap(QIcon::fromTheme("dialog-information").pixmap(KIconLoader::SizeHuge)); 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