Changeset View
Changeset View
Standalone View
Standalone View
libs/handler.cpp
Show First 20 Lines • Show All 58 Lines • ▼ Show 20 Line(s) | |||||
59 | #include <KWindowSystem> | 59 | #include <KWindowSystem> | ||
60 | #include <KIconLoader> | 60 | #include <KIconLoader> | ||
61 | #include <KWallet> | 61 | #include <KWallet> | ||
62 | 62 | | |||
63 | #define AGENT_SERVICE "org.kde.kded5" | 63 | #define AGENT_SERVICE "org.kde.kded5" | ||
64 | #define AGENT_PATH "/modules/networkmanagement" | 64 | #define AGENT_PATH "/modules/networkmanagement" | ||
65 | #define AGENT_IFACE "org.kde.plasmanetworkmanagement" | 65 | #define AGENT_IFACE "org.kde.plasmanetworkmanagement" | ||
66 | 66 | | |||
67 | // 10 seconds | ||||
68 | #define NM_REQUESTSCAN_LIMIT_RATE 10000 | ||||
67 | 69 | | |||
68 | Handler::Handler(QObject *parent) | 70 | Handler::Handler(QObject *parent) | ||
69 | : QObject(parent) | 71 | : QObject(parent) | ||
70 | , m_tmpWirelessEnabled(NetworkManager::isWirelessEnabled()) | 72 | , m_tmpWirelessEnabled(NetworkManager::isWirelessEnabled()) | ||
71 | , m_tmpWwanEnabled(NetworkManager::isWwanEnabled()) | 73 | , m_tmpWwanEnabled(NetworkManager::isWwanEnabled()) | ||
72 | { | 74 | { | ||
73 | initKdedModule(); | 75 | initKdedModule(); | ||
74 | QDBusConnection::sessionBus().connect(QStringLiteral(AGENT_SERVICE), | 76 | QDBusConnection::sessionBus().connect(QStringLiteral(AGENT_SERVICE), | ||
75 | QStringLiteral(AGENT_PATH), | 77 | QStringLiteral(AGENT_PATH), | ||
76 | QStringLiteral(AGENT_IFACE), | 78 | QStringLiteral(AGENT_IFACE), | ||
77 | QStringLiteral("registered"), | 79 | QStringLiteral("registered"), | ||
78 | this, SLOT(initKdedModule())); | 80 | this, SLOT(initKdedModule())); | ||
79 | 81 | | |||
80 | QDBusConnection::sessionBus().connect(QStringLiteral(AGENT_SERVICE), | 82 | QDBusConnection::sessionBus().connect(QStringLiteral(AGENT_SERVICE), | ||
81 | QStringLiteral(AGENT_PATH), | 83 | QStringLiteral(AGENT_PATH), | ||
82 | QStringLiteral(AGENT_IFACE), | 84 | QStringLiteral(AGENT_IFACE), | ||
83 | QStringLiteral("secretsError"), | 85 | QStringLiteral("secretsError"), | ||
84 | this, SLOT(secretAgentError(QString, QString))); | 86 | this, SLOT(secretAgentError(QString, QString))); | ||
85 | | ||||
86 | // Interval (in ms) between attempts to scan for wifi networks | | |||
87 | m_wirelessScanRetryTimer.setInterval(2000); | | |||
88 | m_wirelessScanRetryTimer.setSingleShot(true); | | |||
89 | } | 87 | } | ||
90 | 88 | | |||
91 | Handler::~Handler() | 89 | Handler::~Handler() | ||
92 | { | 90 | { | ||
93 | } | 91 | } | ||
94 | 92 | | |||
95 | void Handler::activateConnection(const QString& connection, const QString& device, const QString& specificObject) | 93 | void Handler::activateConnection(const QString& connection, const QString& device, const QString& specificObject) | ||
96 | { | 94 | { | ||
▲ Show 20 Lines • Show All 394 Lines • ▼ Show 20 Line(s) | 488 | for (NetworkManager::Device::Ptr device : NetworkManager::networkInterfaces()) { | |||
491 | if (device->type() == NetworkManager::Device::Wifi) { | 489 | if (device->type() == NetworkManager::Device::Wifi) { | ||
492 | NetworkManager::WirelessDevice::Ptr wifiDevice = device.objectCast<NetworkManager::WirelessDevice>(); | 490 | NetworkManager::WirelessDevice::Ptr wifiDevice = device.objectCast<NetworkManager::WirelessDevice>(); | ||
493 | 491 | | |||
494 | if (wifiDevice && wifiDevice->state() != NetworkManager::WirelessDevice::Unavailable) { | 492 | if (wifiDevice && wifiDevice->state() != NetworkManager::WirelessDevice::Unavailable) { | ||
495 | if (!interface.isEmpty() && interface != wifiDevice->interfaceName()) { | 493 | if (!interface.isEmpty() && interface != wifiDevice->interfaceName()) { | ||
496 | continue; | 494 | continue; | ||
497 | } | 495 | } | ||
498 | 496 | | |||
497 | if (!checkRequestScanRateLimit(wifiDevice)) { | ||||
498 | QDateTime now = QDateTime::currentDateTime(); | ||||
499 | // for NM < 1.12, lastScan is not available | ||||
500 | QDateTime lastScan = wifiDevice->lastScan(); | ||||
501 | QDateTime lastRequestScan = wifiDevice->lastRequestScan(); | ||||
502 | // Compute the next time we can run a scan | ||||
503 | int timeout = NM_REQUESTSCAN_LIMIT_RATE; | ||||
504 | if (lastScan.isValid() && lastScan.msecsTo(now) < NM_REQUESTSCAN_LIMIT_RATE) { | ||||
505 | timeout = NM_REQUESTSCAN_LIMIT_RATE - lastScan.msecsTo(now); | ||||
506 | } else if (lastRequestScan.isValid() && lastRequestScan.msecsTo(now) < NM_REQUESTSCAN_LIMIT_RATE) { | ||||
507 | timeout = NM_REQUESTSCAN_LIMIT_RATE - lastRequestScan.msecsTo(now); | ||||
508 | } | ||||
509 | qCDebug(PLASMA_NM) << "Rescheduling a request scan for" << wifiDevice->interfaceName() << "in" << timeout; | ||||
510 | scheduleRequestScan(wifiDevice->interfaceName(), timeout); | ||||
511 | | ||||
512 | if (!interface.isEmpty()) { | ||||
513 | return; | ||||
514 | } | ||||
515 | continue; | ||||
516 | } else if (m_wirelessScanRetryTimer.contains(interface)){ | ||||
517 | m_wirelessScanRetryTimer.value(interface)->stop(); | ||||
518 | delete m_wirelessScanRetryTimer.take(interface); | ||||
519 | } | ||||
520 | | ||||
499 | qCDebug(PLASMA_NM) << "Requesting wifi scan on device" << wifiDevice->interfaceName(); | 521 | qCDebug(PLASMA_NM) << "Requesting wifi scan on device" << wifiDevice->interfaceName(); | ||
500 | QDBusPendingReply<> reply = wifiDevice->requestScan(); | 522 | QDBusPendingReply<> reply = wifiDevice->requestScan(); | ||
501 | QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this); | 523 | QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this); | ||
502 | watcher->setProperty("action", Handler::RequestScan); | 524 | watcher->setProperty("action", Handler::RequestScan); | ||
503 | watcher->setProperty("interface", wifiDevice->interfaceName()); | 525 | watcher->setProperty("interface", wifiDevice->interfaceName()); | ||
504 | connect(watcher, &QDBusPendingCallWatcher::finished, this, &Handler::replyFinished); | 526 | connect(watcher, &QDBusPendingCallWatcher::finished, this, &Handler::replyFinished); | ||
505 | } | 527 | } | ||
506 | } | 528 | } | ||
507 | } | 529 | } | ||
508 | } | 530 | } | ||
509 | 531 | | |||
510 | void Handler::scanRequestFailed(const QString &interface) | 532 | bool Handler::checkRequestScanRateLimit(const NetworkManager::WirelessDevice::Ptr &wifiDevice) | ||
511 | { | 533 | { | ||
512 | if (m_wirelessScanRetryTimer.isActive()) { | 534 | QDateTime now = QDateTime::currentDateTime(); | ||
513 | return; | 535 | QDateTime lastScan = wifiDevice->lastScan(); | ||
514 | } | 536 | QDateTime lastRequestScan = wifiDevice->lastRequestScan(); | ||
515 | qCDebug(PLASMA_NM) << "Trying soon a new scan on" << interface; | 537 | | ||
516 | 538 | // if the last scan finished within the last 10 seconds | |||
517 | emit wirelessScanTimerEnabled(false); | 539 | bool ret = lastScan.isValid() && lastScan.msecsTo(now) < NM_REQUESTSCAN_LIMIT_RATE; | ||
518 | 540 | // or if the last Request was sent within the last 10 seconds | |||
541 | ret |= lastRequestScan.isValid() && lastRequestScan.msecsTo(now) < NM_REQUESTSCAN_LIMIT_RATE; | ||||
542 | // skip the request scan | ||||
543 | if (ret) { | ||||
544 | qCDebug(PLASMA_NM) << "Last scan finished " << lastScan.msecsTo(now) << "ms ago and last request scan was sent " | ||||
545 | << lastRequestScan.msecsTo(now) << "ms ago, Skipping scanning interface:" << wifiDevice->interfaceName(); | ||||
546 | return false; | ||||
547 | } | ||||
548 | return true; | ||||
549 | } | ||||
550 | | ||||
551 | void Handler::scheduleRequestScan(const QString &interface, int timeout) | ||||
552 | { | ||||
553 | QTimer *timer; | ||||
jgrulich: This timer never gets deleted. | |||||
timer will be one of the value of hash m_wirelessScanRetryTimer, which are cleaned line 516. meven: timer will be one of the value of hash m_wirelessScanRetryTimer, which are cleaned line 516.
I… | |||||
You remove it just from the map, but it doesn't get deleted, you would need to do something like delete m_wirelessScanRetryTime.take(interface); jgrulich: You remove it just from the map, but it doesn't get deleted, you would need to do something… | |||||
554 | if (!m_wirelessScanRetryTimer.contains(interface)) { | ||||
555 | // create a timer for the interface | ||||
556 | timer = new QTimer(); | ||||
557 | timer->setSingleShot(true); | ||||
558 | m_wirelessScanRetryTimer.insert(interface, timer); | ||||
519 | auto retryAction = [this,interface]() { | 559 | auto retryAction = [this, interface]() { | ||
520 | m_wirelessScanRetryTimer.disconnect(); | | |||
521 | requestScan(interface); | 560 | requestScan(interface); | ||
522 | }; | 561 | }; | ||
523 | connect(&m_wirelessScanRetryTimer, &QTimer::timeout, this, retryAction); | 562 | connect(timer, &QTimer::timeout, this, retryAction); | ||
524 | m_wirelessScanRetryTimer.start(); | 563 | } else { | ||
564 | // set the new value for an existing timer | ||||
565 | timer = m_wirelessScanRetryTimer.value(interface); | ||||
566 | if (timer->isActive()) { | ||||
567 | timer->stop(); | ||||
568 | } | ||||
569 | } | ||||
570 | | ||||
571 | // +1 ms is added to avoid having the scan being rejetted by nm | ||||
572 | // because it is run at the exact last millisecond of the requestScan threshold | ||||
573 | timer->setInterval(timeout + 1); | ||||
574 | timer->start(); | ||||
575 | } | ||||
576 | | ||||
577 | void Handler::scanRequestFailed(const QString &interface) | ||||
578 | { | ||||
579 | scheduleRequestScan(interface, 2000); | ||||
525 | } | 580 | } | ||
526 | 581 | | |||
527 | void Handler::initKdedModule() | 582 | void Handler::initKdedModule() | ||
528 | { | 583 | { | ||
529 | QDBusMessage initMsg = QDBusMessage::createMethodCall(QStringLiteral(AGENT_SERVICE), | 584 | QDBusMessage initMsg = QDBusMessage::createMethodCall(QStringLiteral(AGENT_SERVICE), | ||
530 | QStringLiteral(AGENT_PATH), | 585 | QStringLiteral(AGENT_PATH), | ||
531 | QStringLiteral(AGENT_IFACE), | 586 | QStringLiteral(AGENT_IFACE), | ||
532 | QStringLiteral("init")); | 587 | QStringLiteral("init")); | ||
▲ Show 20 Lines • Show All 70 Lines • ▼ Show 20 Line(s) | 656 | case Handler::RemoveConnection: | |||
603 | notification->setText(i18n("Connection %1 has been removed", watcher->property("connection").toString())); | 658 | notification->setText(i18n("Connection %1 has been removed", watcher->property("connection").toString())); | ||
604 | break; | 659 | break; | ||
605 | case Handler::UpdateConnection: | 660 | case Handler::UpdateConnection: | ||
606 | notification = new KNotification("ConnectionUpdated", KNotification::CloseOnTimeout, this); | 661 | notification = new KNotification("ConnectionUpdated", KNotification::CloseOnTimeout, this); | ||
607 | notification->setText(i18n("Connection %1 has been updated", watcher->property("connection").toString())); | 662 | notification->setText(i18n("Connection %1 has been updated", watcher->property("connection").toString())); | ||
608 | break; | 663 | break; | ||
609 | case Handler::RequestScan: | 664 | case Handler::RequestScan: | ||
610 | qCDebug(PLASMA_NM) << "Wireless scan on" << watcher->property("interface").toString() << "succeeded"; | 665 | qCDebug(PLASMA_NM) << "Wireless scan on" << watcher->property("interface").toString() << "succeeded"; | ||
611 | emit wirelessScanTimerEnabled(true); | | |||
612 | break; | 666 | break; | ||
613 | default: | 667 | default: | ||
614 | break; | 668 | break; | ||
615 | } | 669 | } | ||
616 | 670 | | |||
617 | if (notification) { | 671 | if (notification) { | ||
618 | notification->setComponentName("networkmanagement"); | 672 | notification->setComponentName("networkmanagement"); | ||
619 | notification->setTitle(watcher->property("connection").toString()); | 673 | notification->setTitle(watcher->property("connection").toString()); | ||
Show All 17 Lines |
This timer never gets deleted.