1// Copyright (C) 2021 Ilya Fedin <fedin-ilja2010@ya.ru>
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include <QtNetwork/private/qnetworkinformation_p.h>
5
6#include <QtCore/qglobal.h>
7#include <QtCore/private/qobject_p.h>
8
9#include <gio/gio.h>
10
11QT_BEGIN_NAMESPACE
12
13using namespace Qt::StringLiterals;
14
15Q_DECLARE_LOGGING_CATEGORY(lcNetInfoGlib)
16Q_LOGGING_CATEGORY(lcNetInfoGlib, "qt.network.info.glib");
17
18namespace {
19QNetworkInformation::Reachability reachabilityFromGNetworkConnectivity(GNetworkConnectivity connectivity)
20{
21 switch (connectivity) {
22 case G_NETWORK_CONNECTIVITY_LOCAL:
23 return QNetworkInformation::Reachability::Disconnected;
24 case G_NETWORK_CONNECTIVITY_LIMITED:
25 case G_NETWORK_CONNECTIVITY_PORTAL:
26 return QNetworkInformation::Reachability::Site;
27 case G_NETWORK_CONNECTIVITY_FULL:
28 return QNetworkInformation::Reachability::Online;
29 }
30 return QNetworkInformation::Reachability::Unknown;
31}
32}
33
34static QString backendName = QStringLiteral("glib");
35
36class QGlibNetworkInformationBackend : public QNetworkInformationBackend
37{
38 Q_OBJECT
39public:
40 QGlibNetworkInformationBackend();
41 ~QGlibNetworkInformationBackend();
42
43 QString name() const override { return backendName; }
44 QNetworkInformation::Features featuresSupported() const override
45 {
46 if (!isValid())
47 return {};
48 return featuresSupportedStatic();
49 }
50
51 static QNetworkInformation::Features featuresSupportedStatic()
52 {
53 using Feature = QNetworkInformation::Feature;
54 return QNetworkInformation::Features(Feature::Reachability | Feature::CaptivePortal);
55 }
56
57 bool isValid() const;
58
59private:
60 Q_DISABLE_COPY_MOVE(QGlibNetworkInformationBackend)
61
62 static void updateInformation(QGlibNetworkInformationBackend *backend);
63
64 GNetworkMonitor *networkMonitor = nullptr;
65 gulong handlerId = 0;
66};
67
68class QGlibNetworkInformationBackendFactory : public QNetworkInformationBackendFactory
69{
70 Q_OBJECT
71 Q_PLUGIN_METADATA(IID QNetworkInformationBackendFactory_iid)
72 Q_INTERFACES(QNetworkInformationBackendFactory)
73public:
74 QGlibNetworkInformationBackendFactory() = default;
75 ~QGlibNetworkInformationBackendFactory() = default;
76 QString name() const override { return backendName; }
77 QNetworkInformation::Features featuresSupported() const override
78 {
79 return QGlibNetworkInformationBackend::featuresSupportedStatic();
80 }
81
82 QNetworkInformationBackend *create(QNetworkInformation::Features requiredFeatures) const override
83 {
84 if ((requiredFeatures & featuresSupported()) != requiredFeatures)
85 return nullptr;
86 auto backend = new QGlibNetworkInformationBackend();
87 if (!backend->isValid())
88 delete std::exchange(obj&: backend, new_val: nullptr);
89 return backend;
90 }
91private:
92 Q_DISABLE_COPY_MOVE(QGlibNetworkInformationBackendFactory)
93};
94
95QGlibNetworkInformationBackend::QGlibNetworkInformationBackend()
96: networkMonitor(g_network_monitor_get_default())
97{
98 updateInformation(backend: this);
99
100 handlerId = g_signal_connect_swapped(networkMonitor, "notify::connectivity",
101 G_CALLBACK(updateInformation), this);
102}
103
104QGlibNetworkInformationBackend::~QGlibNetworkInformationBackend()
105{
106 g_signal_handler_disconnect(instance: networkMonitor, handler_id: handlerId);
107}
108
109bool QGlibNetworkInformationBackend::isValid() const
110{
111 return G_OBJECT_TYPE_NAME(networkMonitor) != "GNetworkMonitorBase"_L1;
112}
113
114void QGlibNetworkInformationBackend::updateInformation(QGlibNetworkInformationBackend *backend)
115{
116 const auto connectivityState = g_network_monitor_get_connectivity(monitor: backend->networkMonitor);
117 const bool behindPortal = (connectivityState == G_NETWORK_CONNECTIVITY_PORTAL);
118 backend->setReachability(reachabilityFromGNetworkConnectivity(connectivity: connectivityState));
119 backend->setBehindCaptivePortal(behindPortal);
120}
121
122QT_END_NAMESPACE
123
124#include "qglibnetworkinformationbackend.moc"
125

source code of qtbase/src/plugins/networkinformation/glib/qglibnetworkinformationbackend.cpp