mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-04-26 14:23:09 +00:00
When disabling mobile data, instead of setting the autoconnect flag to true for the current active connection, set it to false for all connections without exception. When reenabling mobile data, instead of looking for a connection with autoconnect set, look for the connection with the latest last use timestamp, set that one to autoconnect, and also connect it immediately. There should not be any connection with autoconnect enabled if mobile data is disabled, because that makes NetworkManager reconnect it after a reboot or a modem restart. The autoconnect state on the modem is apparently lost on reboot. Also change the SignalIndicator::mobileDataEnabled() getter to account for the above. Fixes #182.
148 lines
4.9 KiB
C++
148 lines
4.9 KiB
C++
// SPDX-FileCopyrightText: 2021 Tobias Fella <fella@posteo.de>
|
|
// SPDX-FileCopyrightText: 2022 Devin Lin <devin@kde.org>
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
#include <NetworkManagerQt/GsmSetting>
|
|
#include <NetworkManagerQt/Manager>
|
|
|
|
#include "signalindicator.h"
|
|
|
|
SignalIndicator::SignalIndicator()
|
|
{
|
|
connect(ModemManager::notifier(), &ModemManager::Notifier::modemAdded, this, &SignalIndicator::updateModem);
|
|
connect(ModemManager::notifier(), &ModemManager::Notifier::modemRemoved, this, &SignalIndicator::updateModem);
|
|
updateModem();
|
|
}
|
|
|
|
int SignalIndicator::strength() const
|
|
{
|
|
if (!m_modem) {
|
|
return 0;
|
|
}
|
|
return m_modem->signalQuality().signal;
|
|
}
|
|
|
|
QString SignalIndicator::name() const
|
|
{
|
|
return m_3gppModem ? m_3gppModem->operatorName() : QString();
|
|
}
|
|
|
|
bool SignalIndicator::simLocked() const
|
|
{
|
|
if (!m_modem) {
|
|
return false;
|
|
}
|
|
return m_modem->unlockRequired() == MM_MODEM_LOCK_SIM_PIN;
|
|
}
|
|
|
|
bool SignalIndicator::available() const
|
|
{
|
|
return !ModemManager::modemDevices().isEmpty();
|
|
}
|
|
|
|
bool SignalIndicator::mobileDataSupported() const
|
|
{
|
|
return m_nmModem && m_modemDevice->sim();
|
|
}
|
|
|
|
bool SignalIndicator::mobileDataEnabled() const
|
|
{
|
|
// no modem -> no mobile data -> report disabled
|
|
if (!m_nmModem) {
|
|
return false;
|
|
}
|
|
|
|
// mobile data already activated -> report enabled
|
|
if (m_nmModem->state() == NetworkManager::Device::Activated) {
|
|
return true;
|
|
}
|
|
|
|
// autoconnect disabled on the entire modem -> report disabled
|
|
if (!m_nmModem->autoconnect()) {
|
|
return false;
|
|
}
|
|
|
|
// at least one connection set to autoconnect -> report enabled
|
|
for (NetworkManager::Connection::Ptr con : m_nmModem->availableConnections()) {
|
|
if (con->settings()->autoconnect()) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
// modem, but no connection, set to autoconnect -> report disabled (#182)
|
|
return false;
|
|
}
|
|
|
|
void SignalIndicator::setMobileDataEnabled(bool enabled)
|
|
{
|
|
if (!m_nmModem) {
|
|
return;
|
|
}
|
|
if (!enabled) {
|
|
m_nmModem->setAutoconnect(false);
|
|
// we need to also set all connections to not autoconnect (#182)
|
|
for (NetworkManager::Connection::Ptr con : m_nmModem->availableConnections()) {
|
|
con->settings()->setAutoconnect(false);
|
|
con->update(con->settings()->toMap());
|
|
}
|
|
m_nmModem->disconnectInterface().waitForFinished();
|
|
} else {
|
|
m_nmModem->setAutoconnect(true);
|
|
// activate the connection that was last used
|
|
QDateTime latestTimestamp;
|
|
NetworkManager::Connection::Ptr latestCon;
|
|
for (NetworkManager::Connection::Ptr con : m_nmModem->availableConnections()) {
|
|
QDateTime timestamp = con->settings()->timestamp();
|
|
// if con was not used yet, skip it, otherwise:
|
|
// if we have no latestTimestamp yet, con is the latest
|
|
// otherwise, compare the timestamps
|
|
// in case of a tie, use the first connection that was found
|
|
if (!timestamp.isNull() && (latestTimestamp.isNull() || timestamp > latestTimestamp)) {
|
|
latestTimestamp = timestamp;
|
|
latestCon = con;
|
|
}
|
|
}
|
|
// if we found the last used connection
|
|
if (!latestCon.isNull()) {
|
|
// set it to autoconnect and connect it immediately
|
|
latestCon->settings()->setAutoconnect(true);
|
|
latestCon->update(latestCon->settings()->toMap());
|
|
NetworkManager::activateConnection(latestCon->path(), m_nmModem->uni(), "");
|
|
}
|
|
}
|
|
}
|
|
|
|
void SignalIndicator::updateModem()
|
|
{
|
|
if (!available()) {
|
|
qWarning() << "No modems available";
|
|
return;
|
|
}
|
|
|
|
// we assume that there is a single modem
|
|
m_modemDevice = ModemManager::modemDevices()[0];
|
|
m_modem = m_modemDevice->modemInterface();
|
|
m_3gppModem = m_modemDevice->interface(ModemManager::ModemDevice::GsmInterface).objectCast<ModemManager::Modem3gpp>();
|
|
|
|
// find networkmanager modem
|
|
for (NetworkManager::Device::Ptr nmDevice : NetworkManager::networkInterfaces()) {
|
|
if (nmDevice->udi() == m_modemDevice->uni()) {
|
|
m_nmModem = nmDevice.objectCast<NetworkManager::ModemDevice>();
|
|
|
|
connect(m_nmModem.get(), &NetworkManager::Device::autoconnectChanged, this, [this]() {
|
|
Q_EMIT mobileDataEnabledChanged();
|
|
});
|
|
connect(m_nmModem.get(), &NetworkManager::Device::stateChanged, this, [this](auto, auto, auto) {
|
|
Q_EMIT mobileDataEnabledChanged();
|
|
});
|
|
}
|
|
}
|
|
|
|
connect(m_modem.get(), &ModemManager::Modem::signalQualityChanged, this, &SignalIndicator::strengthChanged);
|
|
connect(m_3gppModem.get(), &ModemManager::Modem3gpp::operatorNameChanged, this, &SignalIndicator::nameChanged);
|
|
connect(m_modem.get(), &ModemManager::Modem::unlockRequiredChanged, this, &SignalIndicator::simLockedChanged);
|
|
|
|
Q_EMIT mobileDataSupportedChanged();
|
|
Q_EMIT nameChanged();
|
|
Q_EMIT availableChanged();
|
|
}
|