File indexing completed on 2024-04-28 05:33:52
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 <QDBusReply> 0011 #include <QDesktopServices> 0012 0013 #include <KIO/OpenUrlJob> 0014 #include <KLocalizedString> 0015 0016 #include <NetworkManagerQt/ActiveConnection> 0017 0018 #include <QCoroCore> 0019 #include <QCoroDBus> 0020 0021 #include "plasma_nm_kded.h" 0022 #include <chrono> 0023 0024 using namespace std::chrono_literals; 0025 0026 ConnectivityMonitor::ConnectivityMonitor(QObject *parent) 0027 : QObject(parent) 0028 { 0029 m_limitedConnectivityTimer.setSingleShot(true); 0030 m_limitedConnectivityTimer.setInterval(10s); 0031 connect(&m_limitedConnectivityTimer, &QTimer::timeout, this, &ConnectivityMonitor::showLimitedConnectivityNotification); 0032 0033 checkConnectivity(); 0034 0035 connect(NetworkManager::notifier(), &NetworkManager::Notifier::connectivityChanged, this, &ConnectivityMonitor::connectivityChanged); 0036 } 0037 0038 ConnectivityMonitor::~ConnectivityMonitor() 0039 { 0040 if (m_notification) { 0041 m_notification->close(); 0042 } 0043 } 0044 0045 void ConnectivityMonitor::connectivityChanged(NetworkManager::Connectivity connectivity) 0046 { 0047 if (m_notification && m_notification->property("nm_connectivity") != connectivity) { 0048 m_notification->close(); 0049 m_notification = nullptr; 0050 } 0051 0052 if (connectivity == NetworkManager::Limited) { 0053 qCDebug(PLASMA_NM_KDED_LOG) << "Network connectivity limited, scheduling notification"; 0054 if (!m_limitedConnectivityTimer.isActive()) { 0055 m_limitedConnectivityTimer.start(); 0056 } 0057 } else { 0058 m_limitedConnectivityTimer.stop(); 0059 0060 if (connectivity == NetworkManager::Portal) { 0061 qCDebug(PLASMA_NM_KDED_LOG) << "Detected captive portal"; 0062 const NetworkManager::ActiveConnection::Ptr primaryConnection = NetworkManager::primaryConnection(); 0063 const QString title = primaryConnection ? primaryConnection->id() : i18n("Network authentication"); 0064 0065 if (m_notification) { 0066 m_notification->setTitle(title); 0067 m_notification->sendEvent(); 0068 } else { 0069 m_notification = new KNotification(QStringLiteral("CaptivePortal"), KNotification::Persistent); 0070 m_notification->setComponentName(QStringLiteral("networkmanagement")); 0071 m_notification->setTitle(title); 0072 m_notification->setText(i18n("You need to log into this network")); 0073 0074 auto logInAction = m_notification->addAction(i18n("Log in")); 0075 connect(logInAction, &KNotificationAction::activated, this, [this]() { 0076 auto job = new KIO::OpenUrlJob(QUrl(QStringLiteral("http://networkcheck.kde.org"))); 0077 job->setStartupId(m_notification->xdgActivationToken().toUtf8()); 0078 job->start(); 0079 }); 0080 m_notification->sendEvent(); 0081 } 0082 } 0083 } 0084 } 0085 0086 void ConnectivityMonitor::showLimitedConnectivityNotification() 0087 { 0088 if (m_notification) { 0089 return; 0090 } 0091 0092 m_notification = new KNotification(QStringLiteral("LimitedConnectivity")); 0093 m_notification->setComponentName(QStringLiteral("networkmanagement")); 0094 m_notification->setTitle(i18n("Limited Connectivity")); 0095 m_notification->setText(i18n("This device appears to be connected to a network but is unable to reach the internet.")); 0096 m_notification->sendEvent(); 0097 } 0098 0099 QCoro::Task<void> ConnectivityMonitor::checkConnectivity() 0100 { 0101 QDBusReply<uint> reply = co_await NetworkManager::checkConnectivity(); 0102 0103 if (reply.isValid()) { 0104 connectivityChanged((NetworkManager::Connectivity)reply.value()); 0105 } 0106 } 0107 0108 #include "moc_connectivitymonitor.cpp"