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 const QString &backendName()
35{
36 static auto name = u"glib"_s;
37 return name;
38}
39
40class QGlibNetworkInformationBackend : public QNetworkInformationBackend
41{
42 Q_OBJECT
43public:
44 QGlibNetworkInformationBackend();
45 ~QGlibNetworkInformationBackend();
46
47 QString name() const override { return backendName(); }
48 QNetworkInformation::Features featuresSupported() const override
49 {
50 if (!isValid())
51 return {};
52 return featuresSupportedStatic();
53 }
54
55 static QNetworkInformation::Features featuresSupportedStatic()
56 {
57 using Feature = QNetworkInformation::Feature;
58 return QNetworkInformation::Features(Feature::Reachability | Feature::CaptivePortal
59 | Feature::Metered);
60 }
61
62 bool isValid() const;
63
64private:
65 Q_DISABLE_COPY_MOVE(QGlibNetworkInformationBackend)
66
67 static void updateConnectivity(QGlibNetworkInformationBackend *backend);
68 static void updateMetered(QGlibNetworkInformationBackend *backend);
69
70 GNetworkMonitor *networkMonitor = nullptr;
71 gulong connectivityHandlerId = 0;
72 gulong meteredHandlerId = 0;
73};
74
75class QGlibNetworkInformationBackendFactory : public QNetworkInformationBackendFactory
76{
77 Q_OBJECT
78 Q_PLUGIN_METADATA(IID QNetworkInformationBackendFactory_iid)
79 Q_INTERFACES(QNetworkInformationBackendFactory)
80public:
81 QGlibNetworkInformationBackendFactory() = default;
82 ~QGlibNetworkInformationBackendFactory() = default;
83 QString name() const override { return backendName(); }
84 QNetworkInformation::Features featuresSupported() const override
85 {
86 return QGlibNetworkInformationBackend::featuresSupportedStatic();
87 }
88
89 QNetworkInformationBackend *create(QNetworkInformation::Features requiredFeatures) const override
90 {
91 if ((requiredFeatures & featuresSupported()) != requiredFeatures)
92 return nullptr;
93 auto backend = new QGlibNetworkInformationBackend();
94 if (!backend->isValid())
95 delete std::exchange(obj&: backend, new_val: nullptr);
96 return backend;
97 }
98private:
99 Q_DISABLE_COPY_MOVE(QGlibNetworkInformationBackendFactory)
100};
101
102QGlibNetworkInformationBackend::QGlibNetworkInformationBackend()
103: networkMonitor(g_network_monitor_get_default())
104{
105 updateConnectivity(backend: this);
106 updateMetered(backend: this);
107
108 connectivityHandlerId = g_signal_connect_swapped(networkMonitor, "notify::connectivity",
109 G_CALLBACK(updateConnectivity), this);
110
111 meteredHandlerId = g_signal_connect_swapped(networkMonitor, "notify::network-metered",
112 G_CALLBACK(updateMetered), this);
113}
114
115QGlibNetworkInformationBackend::~QGlibNetworkInformationBackend()
116{
117 g_signal_handler_disconnect(instance: networkMonitor, handler_id: meteredHandlerId);
118 g_signal_handler_disconnect(instance: networkMonitor, handler_id: connectivityHandlerId);
119}
120
121bool QGlibNetworkInformationBackend::isValid() const
122{
123 return QLatin1StringView(G_OBJECT_TYPE_NAME(networkMonitor)) != "GNetworkMonitorBase"_L1;
124}
125
126void QGlibNetworkInformationBackend::updateConnectivity(QGlibNetworkInformationBackend *backend)
127{
128 const auto connectivityState = g_network_monitor_get_connectivity(monitor: backend->networkMonitor);
129 const bool behindPortal = (connectivityState == G_NETWORK_CONNECTIVITY_PORTAL);
130 backend->setReachability(reachabilityFromGNetworkConnectivity(connectivity: connectivityState));
131 backend->setBehindCaptivePortal(behindPortal);
132}
133
134void QGlibNetworkInformationBackend::updateMetered(QGlibNetworkInformationBackend *backend)
135{
136 backend->setMetered(g_network_monitor_get_network_metered(monitor: backend->networkMonitor));
137}
138
139QT_END_NAMESPACE
140
141#include "qglibnetworkinformationbackend.moc"
142

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

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