Remove QNetworkStatusMonitor
Since the old code is now fully integrated in QNetworkInformation backends Pick-to: dev Change-Id: Ia843d17bb3c98333e8d68752e25722b5860f48e0 Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
This commit is contained in:
parent
309a2360fd
commit
7860b9e6ff
@ -1312,7 +1312,7 @@ QHttpNetworkConnection::QHttpNetworkConnection(const QString &hostName, quint16
|
|||||||
{
|
{
|
||||||
Q_D(QHttpNetworkConnection);
|
Q_D(QHttpNetworkConnection);
|
||||||
d->init();
|
d->init();
|
||||||
if (QNetworkStatusMonitor::isEnabled()) {
|
if (QNetworkConnectionMonitor::isEnabled()) {
|
||||||
connect(&d->connectionMonitor, &QNetworkConnectionMonitor::reachabilityChanged,
|
connect(&d->connectionMonitor, &QNetworkConnectionMonitor::reachabilityChanged,
|
||||||
this, &QHttpNetworkConnection::onlineStateChanged, Qt::QueuedConnection);
|
this, &QHttpNetworkConnection::onlineStateChanged, Qt::QueuedConnection);
|
||||||
}
|
}
|
||||||
@ -1326,7 +1326,7 @@ QHttpNetworkConnection::QHttpNetworkConnection(quint16 connectionCount, const QS
|
|||||||
{
|
{
|
||||||
Q_D(QHttpNetworkConnection);
|
Q_D(QHttpNetworkConnection);
|
||||||
d->init();
|
d->init();
|
||||||
if (QNetworkStatusMonitor::isEnabled()) {
|
if (QNetworkConnectionMonitor::isEnabled()) {
|
||||||
connect(&d->connectionMonitor, &QNetworkConnectionMonitor::reachabilityChanged,
|
connect(&d->connectionMonitor, &QNetworkConnectionMonitor::reachabilityChanged,
|
||||||
this, &QHttpNetworkConnection::onlineStateChanged, Qt::QueuedConnection);
|
this, &QHttpNetworkConnection::onlineStateChanged, Qt::QueuedConnection);
|
||||||
}
|
}
|
||||||
|
@ -911,7 +911,7 @@ void QHttpNetworkConnectionChannel::_q_connected()
|
|||||||
|
|
||||||
pipeliningSupported = QHttpNetworkConnectionChannel::PipeliningSupportUnknown;
|
pipeliningSupported = QHttpNetworkConnectionChannel::PipeliningSupportUnknown;
|
||||||
|
|
||||||
if (QNetworkStatusMonitor::isEnabled()) {
|
if (QNetworkConnectionMonitor::isEnabled()) {
|
||||||
auto connectionPrivate = connection->d_func();
|
auto connectionPrivate = connection->d_func();
|
||||||
if (!connectionPrivate->connectionMonitor.isMonitoring()) {
|
if (!connectionPrivate->connectionMonitor.isMonitoring()) {
|
||||||
// Now that we have a pair of addresses, we can start monitoring the
|
// Now that we have a pair of addresses, we can start monitoring the
|
||||||
|
@ -208,7 +208,7 @@ bool QNetworkConnectionMonitor::setTargets(const QHostAddress &local, const QHos
|
|||||||
|
|
||||||
qt_sockaddr client = qt_hostaddress_to_sockaddr(local);
|
qt_sockaddr client = qt_hostaddress_to_sockaddr(local);
|
||||||
if (remote.isNull()) {
|
if (remote.isNull()) {
|
||||||
// That's a special case our QNetworkStatusMonitor is using (AnyIpv4/6 address to check an overall status).
|
// That's a special case our QNetworkInformation backend is using (AnyIpv4/6 address to check an overall status).
|
||||||
d->probe = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, reinterpret_cast<sockaddr *>(&client));
|
d->probe = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, reinterpret_cast<sockaddr *>(&client));
|
||||||
} else {
|
} else {
|
||||||
qt_sockaddr target = qt_hostaddress_to_sockaddr(remote);
|
qt_sockaddr target = qt_hostaddress_to_sockaddr(remote);
|
||||||
@ -301,124 +301,9 @@ bool QNetworkConnectionMonitor::isReachable()
|
|||||||
return d->isReachable();
|
return d->isReachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
class QNetworkStatusMonitorPrivate : public QObjectPrivate
|
bool QNetworkConnectionMonitor::isEnabled()
|
||||||
{
|
|
||||||
public:
|
|
||||||
QNetworkConnectionMonitor ipv4Probe;
|
|
||||||
bool isOnlineIpv4 = false;
|
|
||||||
QNetworkConnectionMonitor ipv6Probe;
|
|
||||||
bool isOnlineIpv6 = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
QNetworkStatusMonitor::QNetworkStatusMonitor(QObject *parent)
|
|
||||||
: QObject(*new QNetworkStatusMonitorPrivate, parent)
|
|
||||||
{
|
|
||||||
Q_D(QNetworkStatusMonitor);
|
|
||||||
|
|
||||||
if (d->ipv4Probe.setTargets(QHostAddress::AnyIPv4, {})) {
|
|
||||||
// We manage to create SCNetworkReachabilityRef for IPv4, let's
|
|
||||||
// read the last known state then!
|
|
||||||
d->isOnlineIpv4 = d->ipv4Probe.isReachable();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (d->ipv6Probe.setTargets(QHostAddress::AnyIPv6, {})) {
|
|
||||||
// We manage to create SCNetworkReachability ref for IPv6, let's
|
|
||||||
// read the last known state then!
|
|
||||||
d->isOnlineIpv6 = d->ipv6Probe.isReachable();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
connect(&d->ipv4Probe, &QNetworkConnectionMonitor::reachabilityChanged, this,
|
|
||||||
&QNetworkStatusMonitor::reachabilityChanged, Qt::QueuedConnection);
|
|
||||||
connect(&d->ipv6Probe, &QNetworkConnectionMonitor::reachabilityChanged, this,
|
|
||||||
&QNetworkStatusMonitor::reachabilityChanged, Qt::QueuedConnection);
|
|
||||||
}
|
|
||||||
|
|
||||||
QNetworkStatusMonitor::~QNetworkStatusMonitor()
|
|
||||||
{
|
|
||||||
Q_D(QNetworkStatusMonitor);
|
|
||||||
|
|
||||||
d->ipv4Probe.disconnect();
|
|
||||||
d->ipv4Probe.stopMonitoring();
|
|
||||||
d->ipv6Probe.disconnect();
|
|
||||||
d->ipv6Probe.stopMonitoring();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QNetworkStatusMonitor::start()
|
|
||||||
{
|
|
||||||
Q_D(QNetworkStatusMonitor);
|
|
||||||
|
|
||||||
if (isMonitoring()) {
|
|
||||||
qCWarning(lcNetMon, "Network status monitor is already active");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
d->ipv4Probe.startMonitoring();
|
|
||||||
d->ipv6Probe.startMonitoring();
|
|
||||||
|
|
||||||
return isMonitoring();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QNetworkStatusMonitor::stop()
|
|
||||||
{
|
|
||||||
Q_D(QNetworkStatusMonitor);
|
|
||||||
|
|
||||||
if (d->ipv4Probe.isMonitoring())
|
|
||||||
d->ipv4Probe.stopMonitoring();
|
|
||||||
if (d->ipv6Probe.isMonitoring())
|
|
||||||
d->ipv6Probe.stopMonitoring();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QNetworkStatusMonitor::isMonitoring() const
|
|
||||||
{
|
|
||||||
Q_D(const QNetworkStatusMonitor);
|
|
||||||
|
|
||||||
return d->ipv4Probe.isMonitoring() || d->ipv6Probe.isMonitoring();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QNetworkStatusMonitor::isNetworkAccessible()
|
|
||||||
{
|
|
||||||
// This function is to be executed on the thread that created
|
|
||||||
// and uses 'this'.
|
|
||||||
Q_D(QNetworkStatusMonitor);
|
|
||||||
|
|
||||||
return d->isOnlineIpv4 || d->isOnlineIpv6;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QNetworkStatusMonitor::event(QEvent *event)
|
|
||||||
{
|
|
||||||
return QObject::event(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QNetworkStatusMonitor::isEnabled()
|
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QNetworkStatusMonitor::reachabilityChanged(bool online)
|
|
||||||
{
|
|
||||||
// This function is executed on the thread that created/uses 'this',
|
|
||||||
// not on the reachability queue.
|
|
||||||
Q_D(QNetworkStatusMonitor);
|
|
||||||
|
|
||||||
auto probe = qobject_cast<QNetworkConnectionMonitor *>(sender());
|
|
||||||
if (!probe)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const bool isIpv4 = probe == &d->ipv4Probe;
|
|
||||||
bool &probeOnline = isIpv4 ? d->isOnlineIpv4 : d->isOnlineIpv6;
|
|
||||||
bool otherOnline = isIpv4 ? d->isOnlineIpv6 : d->isOnlineIpv4;
|
|
||||||
|
|
||||||
if (probeOnline == online) {
|
|
||||||
// We knew this already?
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
probeOnline = online;
|
|
||||||
if (!otherOnline) {
|
|
||||||
// We either just lost or got a network access.
|
|
||||||
emit onlineStateChanged(probeOnline);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -80,6 +80,8 @@ public:
|
|||||||
bool isMonitoring() const;
|
bool isMonitoring() const;
|
||||||
void stopMonitoring();
|
void stopMonitoring();
|
||||||
|
|
||||||
|
static bool isEnabled();
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
// Important: connect to this using QueuedConnection. On Darwin
|
// Important: connect to this using QueuedConnection. On Darwin
|
||||||
// callback is coming on a special dispatch queue.
|
// callback is coming on a special dispatch queue.
|
||||||
@ -90,37 +92,6 @@ private:
|
|||||||
Q_DISABLE_COPY_MOVE(QNetworkConnectionMonitor)
|
Q_DISABLE_COPY_MOVE(QNetworkConnectionMonitor)
|
||||||
};
|
};
|
||||||
|
|
||||||
class QNetworkStatusMonitorPrivate;
|
|
||||||
class Q_AUTOTEST_EXPORT QNetworkStatusMonitor : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
QNetworkStatusMonitor(QObject *parent);
|
|
||||||
~QNetworkStatusMonitor();
|
|
||||||
|
|
||||||
bool isNetworkAccessible();
|
|
||||||
|
|
||||||
bool start();
|
|
||||||
void stop();
|
|
||||||
bool isMonitoring() const;
|
|
||||||
|
|
||||||
bool event(QEvent *event) override;
|
|
||||||
|
|
||||||
static bool isEnabled();
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
|
||||||
// Unlike QNetworkConnectionMonitor, this can be connected to directly.
|
|
||||||
void onlineStateChanged(bool isOnline);
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void reachabilityChanged(bool isOnline);
|
|
||||||
|
|
||||||
private:
|
|
||||||
Q_DECLARE_PRIVATE(QNetworkStatusMonitor)
|
|
||||||
Q_DISABLE_COPY_MOVE(QNetworkStatusMonitor)
|
|
||||||
};
|
|
||||||
|
|
||||||
Q_DECLARE_LOGGING_CATEGORY(lcNetMon)
|
Q_DECLARE_LOGGING_CATEGORY(lcNetMon)
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -45,7 +45,7 @@ QT_BEGIN_NAMESPACE
|
|||||||
|
|
||||||
Q_LOGGING_CATEGORY(lcNetMon, "qt.network.monitor");
|
Q_LOGGING_CATEGORY(lcNetMon, "qt.network.monitor");
|
||||||
|
|
||||||
// Note: this 'stub' version is never enabled (see QNetworkStatusMonitor::isEnabled below)
|
// Note: this 'stub' version is never enabled (see QNetworkConnectionMonitor::isEnabled below)
|
||||||
// and thus should never affect QNAM in any unusuall way. Having this 'stub' version is similar
|
// and thus should never affect QNAM in any unusuall way. Having this 'stub' version is similar
|
||||||
// to building Qt with bearer management configured out.
|
// to building Qt with bearer management configured out.
|
||||||
|
|
||||||
@ -96,51 +96,9 @@ bool QNetworkConnectionMonitor::isReachable()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
class QNetworkStatusMonitorPrivate : public QObjectPrivate
|
bool QNetworkConnectionMonitor::isEnabled()
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
QNetworkStatusMonitor::QNetworkStatusMonitor(QObject *parent)
|
|
||||||
: QObject(*new QNetworkStatusMonitorPrivate, parent)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
QNetworkStatusMonitor::~QNetworkStatusMonitor()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QNetworkStatusMonitor::start()
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QNetworkStatusMonitor::stop()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QNetworkStatusMonitor::isMonitoring() const
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QNetworkStatusMonitor::isNetworkAccessible()
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QNetworkStatusMonitor::event(QEvent *event)
|
|
||||||
{
|
|
||||||
return QObject::event(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QNetworkStatusMonitor::isEnabled()
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void QNetworkStatusMonitor::reachabilityChanged(bool online)
|
|
||||||
{
|
|
||||||
Q_UNUSED(online);
|
|
||||||
}
|
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -490,280 +490,9 @@ bool QNetworkConnectionMonitor::isReachable()
|
|||||||
return d_func()->connectivity & required;
|
return d_func()->connectivity & required;
|
||||||
}
|
}
|
||||||
|
|
||||||
class QNetworkListManagerEvents : public INetworkListManagerEvents
|
bool QNetworkConnectionMonitor::isEnabled()
|
||||||
{
|
|
||||||
public:
|
|
||||||
QNetworkListManagerEvents(QNetworkStatusMonitorPrivate *monitor);
|
|
||||||
virtual ~QNetworkListManagerEvents();
|
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) override;
|
|
||||||
|
|
||||||
ULONG STDMETHODCALLTYPE AddRef() override { return ++ref; }
|
|
||||||
ULONG STDMETHODCALLTYPE Release() override
|
|
||||||
{
|
|
||||||
if (--ref == 0) {
|
|
||||||
delete this;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return ref;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE ConnectivityChanged(NLM_CONNECTIVITY newConnectivity) override;
|
|
||||||
|
|
||||||
[[nodiscard]]
|
|
||||||
bool start();
|
|
||||||
bool stop();
|
|
||||||
|
|
||||||
private:
|
|
||||||
ComPtr<INetworkListManager> networkListManager = nullptr;
|
|
||||||
ComPtr<IConnectionPoint> connectionPoint = nullptr;
|
|
||||||
|
|
||||||
QNetworkStatusMonitorPrivate *monitor = nullptr;
|
|
||||||
|
|
||||||
QAtomicInteger<ULONG> ref = 0;
|
|
||||||
DWORD cookie = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
class QNetworkStatusMonitorPrivate : public QObjectPrivate
|
|
||||||
{
|
|
||||||
Q_DECLARE_PUBLIC(QNetworkStatusMonitor);
|
|
||||||
|
|
||||||
public:
|
|
||||||
QNetworkStatusMonitorPrivate();
|
|
||||||
~QNetworkStatusMonitorPrivate();
|
|
||||||
|
|
||||||
[[nodiscard]]
|
|
||||||
bool start();
|
|
||||||
void stop();
|
|
||||||
|
|
||||||
void setConnectivity(NLM_CONNECTIVITY newConnectivity);
|
|
||||||
|
|
||||||
private:
|
|
||||||
friend class QNetworkListManagerEvents;
|
|
||||||
|
|
||||||
ComPtr<QNetworkListManagerEvents> managerEvents;
|
|
||||||
NLM_CONNECTIVITY connectivity = NLM_CONNECTIVITY_DISCONNECTED;
|
|
||||||
|
|
||||||
bool monitoring = false;
|
|
||||||
bool comInitFailed = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
QNetworkListManagerEvents::QNetworkListManagerEvents(QNetworkStatusMonitorPrivate *monitor)
|
|
||||||
: monitor(monitor)
|
|
||||||
{
|
|
||||||
auto hr = CoCreateInstance(CLSID_NetworkListManager, nullptr, CLSCTX_INPROC_SERVER,
|
|
||||||
IID_INetworkListManager, &networkListManager);
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
qCWarning(lcNetMon) << "Could not get a NetworkListManager instance:"
|
|
||||||
<< errorStringFromHResult(hr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set initial connectivity
|
|
||||||
hr = networkListManager->GetConnectivity(&monitor->connectivity);
|
|
||||||
if (FAILED(hr))
|
|
||||||
qCWarning(lcNetMon) << "Could not get connectivity:" << errorStringFromHResult(hr);
|
|
||||||
|
|
||||||
ComPtr<IConnectionPointContainer> connectionPointContainer;
|
|
||||||
hr = networkListManager.As(&connectionPointContainer);
|
|
||||||
if (SUCCEEDED(hr)) {
|
|
||||||
hr = connectionPointContainer->FindConnectionPoint(IID_INetworkListManagerEvents,
|
|
||||||
&connectionPoint);
|
|
||||||
}
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
qCWarning(lcNetMon) << "Failed to get connection point for network list manager events:"
|
|
||||||
<< errorStringFromHResult(hr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QNetworkListManagerEvents::~QNetworkListManagerEvents()
|
|
||||||
{
|
|
||||||
Q_ASSERT(ref == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE QNetworkListManagerEvents::QueryInterface(REFIID riid, void **ppvObject)
|
|
||||||
{
|
|
||||||
if (!ppvObject)
|
|
||||||
return E_INVALIDARG;
|
|
||||||
|
|
||||||
return QueryInterfaceImpl<IUnknown>(this, riid, ppvObject)
|
|
||||||
|| QueryInterfaceImpl<INetworkListManagerEvents>(this, riid, ppvObject)
|
|
||||||
? S_OK
|
|
||||||
: E_NOINTERFACE;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE
|
|
||||||
QNetworkListManagerEvents::ConnectivityChanged(NLM_CONNECTIVITY newConnectivity)
|
|
||||||
{
|
|
||||||
// This function is run on a different thread than 'monitor' is created on, so we need to run
|
|
||||||
// it on that thread
|
|
||||||
QMetaObject::invokeMethod(monitor->q_ptr,
|
|
||||||
[newConnectivity, monitor = this->monitor]() {
|
|
||||||
monitor->setConnectivity(newConnectivity);
|
|
||||||
},
|
|
||||||
Qt::QueuedConnection);
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QNetworkListManagerEvents::start()
|
|
||||||
{
|
|
||||||
if (!connectionPoint) {
|
|
||||||
qCWarning(lcNetMon, "Initialization failed, can't start!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
auto hr = connectionPoint->Advise(this, &cookie);
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
qCWarning(lcNetMon) << "Failed to subscribe to network connectivity events:"
|
|
||||||
<< errorStringFromHResult(hr);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update connectivity since it might have changed since this class was constructed
|
|
||||||
NLM_CONNECTIVITY connectivity;
|
|
||||||
hr = networkListManager->GetConnectivity(&connectivity);
|
|
||||||
if (FAILED(hr))
|
|
||||||
qCWarning(lcNetMon) << "Could not get connectivity:" << errorStringFromHResult(hr);
|
|
||||||
else
|
|
||||||
monitor->setConnectivity(connectivity);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QNetworkListManagerEvents::stop()
|
|
||||||
{
|
|
||||||
Q_ASSERT(connectionPoint);
|
|
||||||
auto hr = connectionPoint->Unadvise(cookie);
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
qCWarning(lcNetMon) << "Failed to unsubscribe from network connectivity events:"
|
|
||||||
<< errorStringFromHResult(hr);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
cookie = 0;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
QNetworkStatusMonitorPrivate::QNetworkStatusMonitorPrivate()
|
|
||||||
{
|
|
||||||
auto hr = CoInitialize(nullptr);
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
qCWarning(lcNetMon) << "Failed to initialize COM:" << errorStringFromHResult(hr);
|
|
||||||
comInitFailed = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
managerEvents = new QNetworkListManagerEvents(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
QNetworkStatusMonitorPrivate::~QNetworkStatusMonitorPrivate()
|
|
||||||
{
|
|
||||||
if (comInitFailed)
|
|
||||||
return;
|
|
||||||
if (monitoring)
|
|
||||||
stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QNetworkStatusMonitorPrivate::setConnectivity(NLM_CONNECTIVITY newConnectivity)
|
|
||||||
{
|
|
||||||
Q_Q(QNetworkStatusMonitor);
|
|
||||||
|
|
||||||
const bool oldAccessibility = q->isNetworkAccessible();
|
|
||||||
connectivity = newConnectivity;
|
|
||||||
const bool accessibility = q->isNetworkAccessible();
|
|
||||||
if (oldAccessibility != accessibility)
|
|
||||||
emit q->onlineStateChanged(accessibility);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QNetworkStatusMonitorPrivate::start()
|
|
||||||
{
|
|
||||||
Q_ASSERT(!monitoring);
|
|
||||||
|
|
||||||
if (comInitFailed) {
|
|
||||||
auto hr = CoInitialize(nullptr);
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
qCWarning(lcNetMon) << "Failed to initialize COM:" << errorStringFromHResult(hr);
|
|
||||||
comInitFailed = true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
comInitFailed = false;
|
|
||||||
}
|
|
||||||
if (!managerEvents)
|
|
||||||
managerEvents = new QNetworkListManagerEvents(this);
|
|
||||||
|
|
||||||
if (managerEvents->start())
|
|
||||||
monitoring = true;
|
|
||||||
return monitoring;
|
|
||||||
}
|
|
||||||
|
|
||||||
void QNetworkStatusMonitorPrivate::stop()
|
|
||||||
{
|
|
||||||
Q_ASSERT(managerEvents);
|
|
||||||
Q_ASSERT(monitoring);
|
|
||||||
// Can return false but realistically shouldn't since that would break everything:
|
|
||||||
managerEvents->stop();
|
|
||||||
monitoring = false;
|
|
||||||
managerEvents.Reset();
|
|
||||||
|
|
||||||
CoUninitialize();
|
|
||||||
comInitFailed = true; // we check this value in start() to see if we need to re-initialize
|
|
||||||
}
|
|
||||||
|
|
||||||
QNetworkStatusMonitor::QNetworkStatusMonitor(QObject *parent)
|
|
||||||
: QObject(*new QNetworkStatusMonitorPrivate, parent)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
QNetworkStatusMonitor::~QNetworkStatusMonitor() {}
|
|
||||||
|
|
||||||
bool QNetworkStatusMonitor::start()
|
|
||||||
{
|
|
||||||
if (isMonitoring()) {
|
|
||||||
qCWarning(lcNetMon, "Monitor is already active, call stopMonitoring() first");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return d_func()->start();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QNetworkStatusMonitor::stop()
|
|
||||||
{
|
|
||||||
if (!isMonitoring()) {
|
|
||||||
qCWarning(lcNetMon, "stopMonitoring was called when not monitoring!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
d_func()->stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QNetworkStatusMonitor::isMonitoring() const
|
|
||||||
{
|
|
||||||
return d_func()->monitoring;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QNetworkStatusMonitor::isNetworkAccessible()
|
|
||||||
{
|
|
||||||
return d_func()->connectivity
|
|
||||||
& (NLM_CONNECTIVITY_IPV4_INTERNET | NLM_CONNECTIVITY_IPV6_INTERNET
|
|
||||||
| NLM_CONNECTIVITY_IPV4_SUBNET | NLM_CONNECTIVITY_IPV6_SUBNET
|
|
||||||
| NLM_CONNECTIVITY_IPV4_LOCALNETWORK | NLM_CONNECTIVITY_IPV6_LOCALNETWORK);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QNetworkStatusMonitor::event(QEvent *event)
|
|
||||||
{
|
|
||||||
if (event->type() == QEvent::ThreadChange && isMonitoring()) {
|
|
||||||
stop();
|
|
||||||
QMetaObject::invokeMethod(this, &QNetworkStatusMonitor::start, Qt::QueuedConnection);
|
|
||||||
}
|
|
||||||
|
|
||||||
return QObject::event(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QNetworkStatusMonitor::isEnabled()
|
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QNetworkStatusMonitor::reachabilityChanged(bool online)
|
|
||||||
{
|
|
||||||
Q_UNUSED(online);
|
|
||||||
Q_UNREACHABLE();
|
|
||||||
}
|
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -30,19 +30,19 @@
|
|||||||
#include <QtCore/qdeadlinetimer.h>
|
#include <QtCore/qdeadlinetimer.h>
|
||||||
|
|
||||||
#include <QtNetwork/qhostinfo.h>
|
#include <QtNetwork/qhostinfo.h>
|
||||||
|
#include <QtNetwork/qnetworkinformation.h>
|
||||||
#include <QtNetwork/private/qnetconmonitor_p.h>
|
#include <QtNetwork/private/qnetconmonitor_p.h>
|
||||||
|
|
||||||
#include <QtTest/qsignalspy.h>
|
#include <QtTest/qsignalspy.h>
|
||||||
|
|
||||||
void testDetectDisconnection();
|
|
||||||
void testDetectRouteDisrupted();
|
void testDetectRouteDisrupted();
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
QCoreApplication app(argc, argv);
|
QCoreApplication app(argc, argv);
|
||||||
|
|
||||||
if (!QNetworkStatusMonitor::isEnabled()) {
|
if (!QNetworkConnectionMonitor::isEnabled()) {
|
||||||
qWarning("QNetworkStatusMonitor is not enabled for this platform!");
|
qWarning("QNetworkConnectionMonitor is not enabled for this platform!");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,10 +51,8 @@ int main(int argc, char *argv[])
|
|||||||
QByteArray indent(" ");
|
QByteArray indent(" ");
|
||||||
{
|
{
|
||||||
QTextStream writer(stdout);
|
QTextStream writer(stdout);
|
||||||
writer << "Manual test for QNetwork{Status|Connection}Monitor\n"
|
writer << "Manual test for QNetworkConnection}Monitor\n"
|
||||||
<< "The tests are grouped by what they test. Run them in any order\n"
|
<< "The tests are grouped by what they test. Run them in any order\n"
|
||||||
<< "- QNetworkStatusMonitor tests:\n"
|
|
||||||
<< indent << "c" << indent << "Test connection and disconnection detection.\n"
|
|
||||||
<< "- QNetworkConnectionMonitor tests:\n"
|
<< "- QNetworkConnectionMonitor tests:\n"
|
||||||
<< indent << "r" << indent << "Test detection of disruption of route to target.\n"
|
<< indent << "r" << indent << "Test detection of disruption of route to target.\n"
|
||||||
<< "- General\n"
|
<< "- General\n"
|
||||||
@ -70,9 +68,6 @@ int main(int argc, char *argv[])
|
|||||||
};
|
};
|
||||||
|
|
||||||
switch (getCommand()) {
|
switch (getCommand()) {
|
||||||
case 'c':
|
|
||||||
testDetectDisconnection();
|
|
||||||
break;
|
|
||||||
case 'r':
|
case 'r':
|
||||||
testDetectRouteDisrupted();
|
testDetectRouteDisrupted();
|
||||||
break;
|
break;
|
||||||
@ -84,16 +79,19 @@ int main(int argc, char *argv[])
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ensureNetworkAccessible(QNetworkStatusMonitor &status, QTextStream &writer)
|
bool ensureNetworkAccessible(QTextStream &writer)
|
||||||
{
|
{
|
||||||
if (!status.isNetworkAccessible()) {
|
auto netInfo = QNetworkInformation::instance();
|
||||||
|
if (netInfo->reachability() == QNetworkInformation::Reachability::Disconnected) {
|
||||||
writer << "Network currently not accessible, please make sure you have an internet "
|
writer << "Network currently not accessible, please make sure you have an internet "
|
||||||
"connection. Will wait for a connection for 20 seconds.\n";
|
"connection. Will wait for a connection for 20 seconds.\n";
|
||||||
writer.flush();
|
writer.flush();
|
||||||
QDeadlineTimer timer{ 20 * 1000 };
|
QDeadlineTimer timer{ 20 * 1000 };
|
||||||
while (!timer.hasExpired() && !status.isNetworkAccessible())
|
while (!timer.hasExpired()
|
||||||
|
&& netInfo->reachability() == QNetworkInformation::Reachability::Disconnected) {
|
||||||
QCoreApplication::processEvents();
|
QCoreApplication::processEvents();
|
||||||
if (!status.isNetworkAccessible()) {
|
}
|
||||||
|
if (netInfo->reachability() == QNetworkInformation::Reachability::Disconnected) {
|
||||||
writer << "Error: No network in 20 seconds, ending now!\n";
|
writer << "Error: No network in 20 seconds, ending now!\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -102,53 +100,16 @@ bool ensureNetworkAccessible(QNetworkStatusMonitor &status, QTextStream &writer)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void testDetectDisconnection()
|
|
||||||
{
|
|
||||||
QTextStream writer(stdout);
|
|
||||||
QNetworkStatusMonitor status;
|
|
||||||
|
|
||||||
if (!status.start()) {
|
|
||||||
writer << "Error: Failed to start";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ensureNetworkAccessible(status, writer))
|
|
||||||
return;
|
|
||||||
|
|
||||||
QSignalSpy onlineStateSpy(&status, &QNetworkStatusMonitor::onlineStateChanged);
|
|
||||||
|
|
||||||
writer << "Please disconnect from the internet within 20 seconds\n";
|
|
||||||
writer.flush();
|
|
||||||
QDeadlineTimer timer{ 20 * 1000 };
|
|
||||||
while (!timer.hasExpired() && status.isNetworkAccessible())
|
|
||||||
QCoreApplication::processEvents();
|
|
||||||
if (status.isNetworkAccessible()) {
|
|
||||||
writer << "Error: Still connected after 20 seconds, ending now!\n";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (onlineStateSpy.count() == 0) {
|
|
||||||
writer << "Error: There was a disconnection but there was no signal emitted!\n";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Get the final parameter of the final signal emission and make sure it is false.
|
|
||||||
if (onlineStateSpy.last().last().toBool()) {
|
|
||||||
writer << "Error: There was a disconnection but the latest signal emitted says we are online!\n";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
writer << "Success, connection loss was detected!\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
void testDetectRouteDisrupted()
|
void testDetectRouteDisrupted()
|
||||||
{
|
{
|
||||||
QTextStream writer(stdout);
|
QTextStream writer(stdout);
|
||||||
|
|
||||||
{
|
{
|
||||||
QNetworkStatusMonitor status;
|
if (!QNetworkInformation::load()) {
|
||||||
if (!status.start()) {
|
|
||||||
writer << "Error: Failed to start";
|
writer << "Error: Failed to start";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!ensureNetworkAccessible(status, writer))
|
if (!ensureNetworkAccessible(writer))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user