From 1c2210b7b1ecae021d46c8e5a3cb4a53986067c4 Mon Sep 17 00:00:00 2001 From: Lorn Potter Date: Fri, 15 Jan 2016 15:45:27 +1000 Subject: make sure QNAM reacts to configuration changes Task-number: QTBUG-49760 Change-Id: Ic52fc9f7999f3dd00ef4022c959361782bd1ccd2 Reviewed-by: Markus Goetz (Woboq GmbH) --- src/network/access/qnetworkaccessmanager.cpp | 101 +++++++++++++++++++++------ src/network/access/qnetworkaccessmanager.h | 2 + src/network/access/qnetworkaccessmanager_p.h | 5 ++ 3 files changed, 86 insertions(+), 22 deletions(-) (limited to 'src/network/access') diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp index 28553e19e6..d023228fd2 100644 --- a/src/network/access/qnetworkaccessmanager.cpp +++ b/src/network/access/qnetworkaccessmanager.cpp @@ -474,6 +474,9 @@ QNetworkAccessManager::QNetworkAccessManager(QObject *parent) // connect(&d->networkConfigurationManager, SIGNAL(onlineStateChanged(bool)), SLOT(_q_onlineStateChanged(bool))); + connect(&d->networkConfigurationManager, SIGNAL(configurationChanged(const QNetworkConfiguration &)), + SLOT(_q_configurationChanged(const QNetworkConfiguration &))); + #endif } @@ -1564,6 +1567,8 @@ void QNetworkAccessManagerPrivate::createSession(const QNetworkConfiguration &co QObject::disconnect(networkSessionStrongRef.data(), SIGNAL(closed()), q, SLOT(_q_networkSessionClosed())); QObject::disconnect(networkSessionStrongRef.data(), SIGNAL(stateChanged(QNetworkSession::State)), q, SLOT(_q_networkSessionStateChanged(QNetworkSession::State))); + QObject::disconnect(networkSessionStrongRef.data(), SIGNAL(error(QNetworkSession::SessionError)), + q, SLOT(_q_networkSessionFailed(QNetworkSession::SessionError))); } //switch to new session (null if config was invalid) @@ -1571,7 +1576,6 @@ void QNetworkAccessManagerPrivate::createSession(const QNetworkConfiguration &co networkSessionWeakRef = networkSessionStrongRef.toWeakRef(); if (!networkSessionStrongRef) { - online = false; if (networkAccessible == QNetworkAccessManager::NotAccessible || !online) emit q->networkAccessibleChanged(QNetworkAccessManager::NotAccessible); @@ -1587,6 +1591,8 @@ void QNetworkAccessManagerPrivate::createSession(const QNetworkConfiguration &co QObject::connect(networkSessionStrongRef.data(), SIGNAL(closed()), q, SLOT(_q_networkSessionClosed()), Qt::QueuedConnection); QObject::connect(networkSessionStrongRef.data(), SIGNAL(stateChanged(QNetworkSession::State)), q, SLOT(_q_networkSessionStateChanged(QNetworkSession::State)), Qt::QueuedConnection); + QObject::connect(networkSessionStrongRef.data(), SIGNAL(error(QNetworkSession::SessionError)), + q, SLOT(_q_networkSessionFailed(QNetworkSession::SessionError))); _q_networkSessionStateChanged(networkSessionStrongRef->state()); } @@ -1603,6 +1609,9 @@ void QNetworkAccessManagerPrivate::_q_networkSessionClosed() QObject::disconnect(networkSession.data(), SIGNAL(closed()), q, SLOT(_q_networkSessionClosed())); QObject::disconnect(networkSession.data(), SIGNAL(stateChanged(QNetworkSession::State)), q, SLOT(_q_networkSessionStateChanged(QNetworkSession::State))); + QObject::disconnect(networkSessionStrongRef.data(), SIGNAL(error(QNetworkSession::SessionError)), + q, SLOT(_q_networkSessionFailed(QNetworkSession::SessionError))); + networkSessionStrongRef.clear(); networkSessionWeakRef.clear(); } @@ -1611,46 +1620,56 @@ void QNetworkAccessManagerPrivate::_q_networkSessionClosed() void QNetworkAccessManagerPrivate::_q_networkSessionStateChanged(QNetworkSession::State state) { Q_Q(QNetworkAccessManager); - + bool reallyOnline = false; //Do not emit the networkSessionConnected signal here, except for roaming -> connected //transition, otherwise it is emitted twice in a row when opening a connection. - if (state == QNetworkSession::Connected && lastSessionState == QNetworkSession::Roaming) + if (state == QNetworkSession::Connected && lastSessionState != QNetworkSession::Roaming) emit q->networkSessionConnected(); lastSessionState = state; - if (online) { + if (online && state == QNetworkSession::Disconnected) { + Q_FOREACH (const QNetworkConfiguration &cfg, networkConfigurationManager.allConfigurations()) { + if (cfg.state().testFlag(QNetworkConfiguration::Active)) { + reallyOnline = true; + } + } + } else if (state == QNetworkSession::Connected || state == QNetworkSession::Roaming) { + reallyOnline = true; + } + + if (!reallyOnline) { if (state != QNetworkSession::Connected && state != QNetworkSession::Roaming) { - online = false; if (networkAccessible != QNetworkAccessManager::NotAccessible) { networkAccessible = QNetworkAccessManager::NotAccessible; emit q->networkAccessibleChanged(networkAccessible); } } } else { - if (state == QNetworkSession::Connected || state == QNetworkSession::Roaming) { - online = true; - if (defaultAccessControl) - if (networkAccessible != QNetworkAccessManager::Accessible) { - networkAccessible = QNetworkAccessManager::Accessible; - emit q->networkAccessibleChanged(networkAccessible); - } - } + if (defaultAccessControl) + if (networkAccessible != QNetworkAccessManager::Accessible) { + networkAccessible = QNetworkAccessManager::Accessible; + emit q->networkAccessibleChanged(networkAccessible); + } + } + online = reallyOnline; + if (online && (state != QNetworkSession::Connected && state != QNetworkSession::Roaming)) { + _q_networkSessionClosed(); + createSession(q->configuration()); } } void QNetworkAccessManagerPrivate::_q_onlineStateChanged(bool isOnline) { Q_Q(QNetworkAccessManager); + // if the user set a config, we only care whether this one is active. // Otherwise, this QNAM is online if there is an online config. if (customNetworkConfiguration) { online = (networkConfiguration.state() & QNetworkConfiguration::Active); } else { if (online != isOnline) { - if (isOnline) { - networkSessionStrongRef.clear(); - networkSessionWeakRef.clear(); - } + _q_networkSessionClosed(); + createSession(q->configuration()); online = isOnline; } } @@ -1661,11 +1680,6 @@ void QNetworkAccessManagerPrivate::_q_onlineStateChanged(bool isOnline) emit q->networkAccessibleChanged(networkAccessible); } } - } else if (networkConfiguration.state().testFlag(QNetworkConfiguration::Undefined)) { - if (networkAccessible != QNetworkAccessManager::UnknownAccessibility) { - networkAccessible = QNetworkAccessManager::UnknownAccessibility; - emit q->networkAccessibleChanged(networkAccessible); - } } else { if (networkAccessible != QNetworkAccessManager::NotAccessible) { networkAccessible = QNetworkAccessManager::NotAccessible; @@ -1674,6 +1688,49 @@ void QNetworkAccessManagerPrivate::_q_onlineStateChanged(bool isOnline) } } +void QNetworkAccessManagerPrivate::_q_configurationChanged(const QNetworkConfiguration &configuration) +{ + const QString id = configuration.identifier(); + if (configuration.state().testFlag(QNetworkConfiguration::Active)) { + if (!onlineConfigurations.contains(id)) { + + QSharedPointer session(getNetworkSession()); + if (session) { + if (online && session->configuration().identifier() + != networkConfigurationManager.defaultConfiguration().identifier()) { + + onlineConfigurations.insert(id); + //this one disconnected but another one is online, + // close and create new session + _q_networkSessionClosed(); + createSession(networkConfigurationManager.defaultConfiguration()); + } + } + } + + } else if (onlineConfigurations.contains(id)) { + //this one is disconnecting + onlineConfigurations.remove(id); + if (!onlineConfigurations.isEmpty()) { + _q_networkSessionClosed(); + createSession(configuration); + } + } +} + + +void QNetworkAccessManagerPrivate::_q_networkSessionFailed(QNetworkSession::SessionError) +{ + Q_FOREACH (const QNetworkConfiguration &cfg, networkConfigurationManager.allConfigurations()) { + if (cfg.state().testFlag(QNetworkConfiguration::Active)) { + online = true; + _q_networkSessionClosed(); + createSession(networkConfigurationManager.defaultConfiguration()); + return; + } + } +} + #endif // QT_NO_BEARERMANAGEMENT QNetworkRequest QNetworkAccessManagerPrivate::prepareMultipart(const QNetworkRequest &request, QHttpMultiPart *multiPart) diff --git a/src/network/access/qnetworkaccessmanager.h b/src/network/access/qnetworkaccessmanager.h index c8df213ead..908d327e63 100644 --- a/src/network/access/qnetworkaccessmanager.h +++ b/src/network/access/qnetworkaccessmanager.h @@ -176,6 +176,8 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_networkSessionClosed()) Q_PRIVATE_SLOT(d_func(), void _q_networkSessionStateChanged(QNetworkSession::State)) Q_PRIVATE_SLOT(d_func(), void _q_onlineStateChanged(bool)) + Q_PRIVATE_SLOT(d_func(), void _q_configurationChanged(const QNetworkConfiguration &)) + Q_PRIVATE_SLOT(d_func(), void _q_networkSessionFailed(QNetworkSession::SessionError)) #endif }; diff --git a/src/network/access/qnetworkaccessmanager_p.h b/src/network/access/qnetworkaccessmanager_p.h index 3fc33b5c15..2528249d17 100644 --- a/src/network/access/qnetworkaccessmanager_p.h +++ b/src/network/access/qnetworkaccessmanager_p.h @@ -143,6 +143,11 @@ public: bool isSeamless); void _q_networkSessionStateChanged(QNetworkSession::State state); void _q_onlineStateChanged(bool isOnline); + void _q_configurationChanged(const QNetworkConfiguration &configuration); + void _q_networkSessionFailed(QNetworkSession::SessionError error); + + QSet onlineConfigurations; + #endif QNetworkRequest prepareMultipart(const QNetworkRequest &request, QHttpMultiPart *multiPart); -- cgit v1.2.3