diff --git a/src/plugins/networkinformationbackends/networkmanager/qnetworkmanagernetworkinformationbackend.cpp b/src/plugins/networkinformationbackends/networkmanager/qnetworkmanagernetworkinformationbackend.cpp index 1356078ee0a..f0627c092a4 100644 --- a/src/plugins/networkinformationbackends/networkmanager/qnetworkmanagernetworkinformationbackend.cpp +++ b/src/plugins/networkinformationbackends/networkmanager/qnetworkmanagernetworkinformationbackend.cpp @@ -91,7 +91,8 @@ public: static QNetworkInformation::Features featuresSupportedStatic() { - return QNetworkInformation::Features(QNetworkInformation::Feature::Reachability); + using Feature = QNetworkInformation::Feature; + return QNetworkInformation::Features(Feature::Reachability | Feature::CaptivePortal); } bool isValid() const { return iface.isValid(); } @@ -145,6 +146,19 @@ QNetworkManagerNetworkInformationBackend::QNetworkManagerNetworkInformationBacke setReachability(reachabilityFromNMState(prevState)); } }); + + using ConnectivityState = QNetworkManagerInterface::NMConnectivityState; + using TriState = QNetworkInformation::TriState; + + const auto connectivityState = iface.connectivityState(); + const bool behindPortal = (connectivityState == ConnectivityState::NM_CONNECTIVITY_PORTAL); + setBehindCaptivePortal(behindPortal ? TriState::True : TriState::False); + + connect(&iface, &QNetworkManagerInterface::connectivityChanged, this, + [this](ConnectivityState state) { + const bool behindPortal = (state == ConnectivityState::NM_CONNECTIVITY_PORTAL); + setBehindCaptivePortal(behindPortal ? TriState::True : TriState::False); + }); } QT_END_NAMESPACE diff --git a/src/plugins/networkinformationbackends/networkmanager/qnetworkmanagerservice.cpp b/src/plugins/networkinformationbackends/networkmanager/qnetworkmanagerservice.cpp index 12ee52675cd..bf9f156cb24 100644 --- a/src/plugins/networkinformationbackends/networkmanager/qnetworkmanagerservice.cpp +++ b/src/plugins/networkinformationbackends/networkmanager/qnetworkmanagerservice.cpp @@ -105,14 +105,25 @@ QNetworkManagerInterface::NMState QNetworkManagerInterface::state() return QNetworkManagerInterface::NM_STATE_UNKNOWN; } +QNetworkManagerInterface::NMConnectivityState QNetworkManagerInterface::connectivityState() const +{ + if (propertyMap.contains("Connectivity")) + return static_cast(propertyMap.value("Connectivity").toUInt()); + return QNetworkManagerInterface::NM_CONNECTIVITY_UNKNOWN; +} + void QNetworkManagerInterface::setProperties(const QMap &map) { for (auto i = map.cbegin(), end = map.cend(); i != end; ++i) { const bool isState = i.key() == QLatin1String("State"); + const bool isConnectivity = i.key() == QLatin1String("Connectivity"); bool stateUpdate = isState; + bool connectivityUpdate = isConnectivity; + auto it = propertyMap.lowerBound(i.key()); if (it != propertyMap.end() && it.key() == i.key()) { stateUpdate &= (it.value() != i.value()); + connectivityUpdate &= (it.value() != i.value()); *it = *i; } else { propertyMap.insert(it, i.key(), i.value()); @@ -121,6 +132,9 @@ void QNetworkManagerInterface::setProperties(const QMap &map) if (stateUpdate) { quint32 state = i.value().toUInt(); Q_EMIT stateChanged(state); + } else if (connectivityUpdate) { + quint32 state = i.value().toUInt(); + Q_EMIT connectivityChanged(static_cast(state)); } } } diff --git a/src/plugins/networkinformationbackends/networkmanager/qnetworkmanagerservice.h b/src/plugins/networkinformationbackends/networkmanager/qnetworkmanagerservice.h index 9624eaa216a..067ade6cbdd 100644 --- a/src/plugins/networkinformationbackends/networkmanager/qnetworkmanagerservice.h +++ b/src/plugins/networkinformationbackends/networkmanager/qnetworkmanagerservice.h @@ -109,14 +109,26 @@ public: NM_STATE_CONNECTED_GLOBAL = 70 }; Q_ENUM(NMState); + // Matches 'NMConnectivityState' from + // https://developer.gnome.org/NetworkManager/stable/nm-dbus-types.html#NMConnectivityState + enum NMConnectivityState { + NM_CONNECTIVITY_UNKNOWN = 0, + NM_CONNECTIVITY_NONE = 1, + NM_CONNECTIVITY_PORTAL = 2, + NM_CONNECTIVITY_LIMITED = 3, + NM_CONNECTIVITY_FULL = 4, + }; + Q_ENUM(NMConnectivityState); QNetworkManagerInterface(QObject *parent = nullptr); ~QNetworkManagerInterface(); NMState state(); + NMConnectivityState connectivityState() const; Q_SIGNALS: void stateChanged(quint32); + void connectivityChanged(NMConnectivityState); private Q_SLOTS: void setProperties(const QMap &map);