QNetworkInformation: Captive portal support for NetworkManager

Task-number: QTBUG-93848
Change-Id: I0d31e7ed75e9dbf5c7aac851982d9ed1ac226693
Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
This commit is contained in:
Mårten Nordheim 2021-05-26 11:54:56 +02:00
parent 2a60c4b99f
commit 0baf172611
3 changed files with 41 additions and 1 deletions

View File

@ -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

View File

@ -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<NMConnectivityState>(propertyMap.value("Connectivity").toUInt());
return QNetworkManagerInterface::NM_CONNECTIVITY_UNKNOWN;
}
void QNetworkManagerInterface::setProperties(const QMap<QString, QVariant> &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<QString, QVariant> &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<NMConnectivityState>(state));
}
}
}

View File

@ -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<QString, QVariant> &map);