File indexing completed on 2024-05-05 17:42:32
0001 /* 0002 SPDX-FileCopyrightText: 2016 Jan Grulich <jgrulich@redhat.com> 0003 SPDX-FileCopyrightText: 2020 Kai Uwe Broulik <kde@broulik.de> 0004 0005 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0006 */ 0007 0008 #include "connectivitymonitor.h" 0009 0010 #include <QDBusPendingCallWatcher> 0011 #include <QDBusPendingReply> 0012 #include <QDesktopServices> 0013 0014 #include <KIO/OpenUrlJob> 0015 #include <KLocalizedString> 0016 0017 #include <NetworkManagerQt/ActiveConnection> 0018 0019 #include "plasma_nm_kded.h" 0020 #include <chrono> 0021 0022 using namespace std::chrono_literals; 0023 0024 ConnectivityMonitor::ConnectivityMonitor(QObject *parent) 0025 : QObject(parent) 0026 { 0027 m_limitedConnectivityTimer.setSingleShot(true); 0028 m_limitedConnectivityTimer.setInterval(10s); 0029 connect(&m_limitedConnectivityTimer, &QTimer::timeout, this, &ConnectivityMonitor::showLimitedConnectivityNotification); 0030 0031 checkConnectivity(); 0032 0033 connect(NetworkManager::notifier(), &NetworkManager::Notifier::connectivityChanged, this, &ConnectivityMonitor::connectivityChanged); 0034 } 0035 0036 ConnectivityMonitor::~ConnectivityMonitor() 0037 { 0038 if (m_notification) { 0039 m_notification->close(); 0040 } 0041 } 0042 0043 void ConnectivityMonitor::connectivityChanged(NetworkManager::Connectivity connectivity) 0044 { 0045 if (m_notification && m_notification->property("nm_connectivity") != connectivity) { 0046 m_notification->close(); 0047 m_notification = nullptr; 0048 } 0049 0050 if (connectivity == NetworkManager::Limited) { 0051 qCDebug(PLASMA_NM_KDED_LOG) << "Network connectivity limited, scheduling notification"; 0052 if (!m_limitedConnectivityTimer.isActive()) { 0053 m_limitedConnectivityTimer.start(); 0054 } 0055 } else { 0056 m_limitedConnectivityTimer.stop(); 0057 0058 if (connectivity == NetworkManager::Portal) { 0059 qCDebug(PLASMA_NM_KDED_LOG) << "Detected captive portal"; 0060 const NetworkManager::ActiveConnection::Ptr primaryConnection = NetworkManager::primaryConnection(); 0061 const QString title = primaryConnection ? primaryConnection->id() : i18n("Network authentication"); 0062 0063 if (m_notification) { 0064 m_notification->setTitle(title); 0065 m_notification->update(); 0066 } else { 0067 m_notification = new KNotification(QStringLiteral("CaptivePortal"), KNotification::Persistent); 0068 m_notification->setActions(QStringList{i18n("Log in")}); 0069 m_notification->setComponentName(QStringLiteral("networkmanagement")); 0070 m_notification->setTitle(title); 0071 m_notification->setText(i18n("You need to log into this network")); 0072 connect(m_notification, &KNotification::action1Activated, this, [this]() { 0073 auto job = new KIO::OpenUrlJob(QUrl(QStringLiteral("http://networkcheck.kde.org"))); 0074 job->setStartupId(m_notification->xdgActivationToken().toUtf8()); 0075 job->start(); 0076 }); 0077 m_notification->sendEvent(); 0078 } 0079 } 0080 } 0081 } 0082 0083 void ConnectivityMonitor::showLimitedConnectivityNotification() 0084 { 0085 if (m_notification) { 0086 return; 0087 } 0088 0089 m_notification = new KNotification(QStringLiteral("LimitedConnectivity")); 0090 m_notification->setComponentName(QStringLiteral("networkmanagement")); 0091 m_notification->setTitle(i18n("Limited Connectivity")); 0092 m_notification->setText(i18n("This device appears to be connected to a network but is unable to reach the internet.")); 0093 m_notification->sendEvent(); 0094 } 0095 0096 void ConnectivityMonitor::checkConnectivity() 0097 { 0098 QDBusPendingReply<uint> pendingReply = NetworkManager::checkConnectivity(); 0099 auto callWatcher = new QDBusPendingCallWatcher(pendingReply); 0100 connect(callWatcher, &QDBusPendingCallWatcher::finished, this, [this](QDBusPendingCallWatcher *watcher) { 0101 QDBusPendingReply<uint> reply = *watcher; 0102 if (reply.isValid()) { 0103 connectivityChanged((NetworkManager::Connectivity)reply.value()); 0104 } 0105 watcher->deleteLater(); 0106 }); 0107 }