QNetworkAccessManager: track online / accessible state without session

In particular, set online state right upon construction of the
QNetworkAccessManager instance. Therefor, QNAM needs an instance of a
QNetworkConfigurationManager internally.
Before, this would only work properly if a network session was created.
Now, networkAccessible() returns the correct status.

Change-Id: I7ff9ccfd18ad376a131fc5977843b55bf185fba0
Reviewed-by: Rafael Roquetto <rafael.roquetto@kdab.com>
Reviewed-by: Shane Kearns <shane.kearns@accenture.com>
This commit is contained in:
Peter Hartmann 2013-02-28 17:41:59 +01:00 committed by The Qt Project
parent 16269904a2
commit 9efd40bd77
4 changed files with 83 additions and 17 deletions

View File

@ -431,6 +431,7 @@ static void ensureInitialized()
QNetworkAccessManager::QNetworkAccessManager(QObject *parent)
: QObject(*new QNetworkAccessManagerPrivate, parent)
{
Q_D(QNetworkAccessManager);
ensureInitialized();
qRegisterMetaType<QNetworkReply::NetworkError>();
@ -447,6 +448,19 @@ QNetworkAccessManager::QNetworkAccessManager(QObject *parent)
#endif
qRegisterMetaType<QNetworkReply::NetworkError>();
qRegisterMetaType<QSharedPointer<char> >();
#ifndef QT_NO_BEARERMANAGEMENT
if (!d->networkSessionRequired) {
// if a session is required, we track online state through
// the QNetworkSession's signals
connect(&d->networkConfigurationManager, SIGNAL(onlineStateChanged(bool)),
SLOT(_q_onlineStateChanged(bool)));
// we would need all active configurations to check for
// d->networkConfigurationManager.isOnline(), which is asynchronous
// and potentially expensive. We can just check the configuration here
d->online = (d->networkConfiguration.state() & QNetworkConfiguration::Active);
}
#endif
}
/*!
@ -833,6 +847,11 @@ QNetworkReply *QNetworkAccessManager::deleteResource(const QNetworkRequest &requ
To restore the default network configuration set the network configuration to the value
returned from QNetworkConfigurationManager::defaultConfiguration().
Setting a network configuration means that the QNetworkAccessManager instance will only
be using the specified one. In particular, if the default network configuration changes
(upon e.g. Wifi being available), this new configuration needs to be enabled
manually if desired.
\snippet code/src_network_access_qnetworkaccessmanager.cpp 2
If an invalid network configuration is set, a network session will not be created. In this
@ -846,6 +865,7 @@ void QNetworkAccessManager::setConfiguration(const QNetworkConfiguration &config
{
Q_D(QNetworkAccessManager);
d->networkConfiguration = config;
d->customNetworkConfiguration = true;
d->createSession(config);
}
@ -928,16 +948,23 @@ QNetworkAccessManager::NetworkAccessibility QNetworkAccessManager::networkAccess
{
Q_D(const QNetworkAccessManager);
QSharedPointer<QNetworkSession> networkSession(d->getNetworkSession());
if (networkSession) {
// d->online holds online/offline state of this network session.
if (d->networkSessionRequired) {
QSharedPointer<QNetworkSession> networkSession(d->getNetworkSession());
if (networkSession) {
// d->online holds online/offline state of this network session.
if (d->online)
return d->networkAccessible;
else
return NotAccessible;
} else {
// Network accessibility is either disabled or unknown.
return (d->networkAccessible == NotAccessible) ? NotAccessible : UnknownAccessibility;
}
} else {
if (d->online)
return d->networkAccessible;
else
return NotAccessible;
} else {
// Network accessibility is either disabled or unknown.
return (d->networkAccessible == NotAccessible) ? NotAccessible : UnknownAccessibility;
}
}
@ -1439,6 +1466,18 @@ void QNetworkAccessManagerPrivate::_q_networkSessionStateChanged(QNetworkSession
}
}
}
void QNetworkAccessManagerPrivate::_q_onlineStateChanged(bool isOnline)
{
// 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 {
online = isOnline;
}
}
#endif // QT_NO_BEARERMANAGEMENT
QNetworkRequest QNetworkAccessManagerPrivate::prepareMultipart(const QNetworkRequest &request, QHttpMultiPart *multiPart)

View File

@ -165,6 +165,7 @@ private:
#ifndef QT_NO_BEARERMANAGEMENT
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))
#endif
};

View File

@ -60,6 +60,9 @@
#include "QtNetwork/qnetworkproxy.h"
#include "QtNetwork/qnetworksession.h"
#include "qnetworkaccessauthenticationmanager_p.h"
#ifndef QT_NO_BEARERMANAGEMENT
#include "QtNetwork/qnetworkconfigmanager.h"
#endif
QT_BEGIN_NAMESPACE
@ -79,6 +82,10 @@ public:
#endif
#ifndef QT_NO_BEARERMANAGEMENT
lastSessionState(QNetworkSession::Invalid),
networkConfiguration(networkConfigurationManager.defaultConfiguration()),
customNetworkConfiguration(false),
networkSessionRequired(networkConfigurationManager.capabilities()
& QNetworkConfigurationManager::NetworkSessionRequired),
networkAccessible(QNetworkAccessManager::Accessible),
activeReplyCount(0),
online(false),
@ -127,6 +134,7 @@ public:
void _q_networkSessionPreferredConfigurationChanged(const QNetworkConfiguration &config,
bool isSeamless);
void _q_networkSessionStateChanged(QNetworkSession::State state);
void _q_onlineStateChanged(bool isOnline);
#endif
QNetworkRequest prepareMultipart(const QNetworkRequest &request, QHttpMultiPart *multiPart);
@ -148,7 +156,12 @@ public:
QSharedPointer<QNetworkSession> networkSessionStrongRef;
QWeakPointer<QNetworkSession> networkSessionWeakRef;
QNetworkSession::State lastSessionState;
QNetworkConfigurationManager networkConfigurationManager;
QNetworkConfiguration networkConfiguration;
// we need to track whether the user set a config or not,
// because the default config might change
bool customNetworkConfiguration;
bool networkSessionRequired;
QNetworkAccessManager::NetworkAccessibility networkAccessible;
int activeReplyCount;
bool online;

View File

@ -77,30 +77,43 @@ void tst_QNetworkAccessManager::networkAccessible()
QSignalSpy spy(&manager,
SIGNAL(networkAccessibleChanged(QNetworkAccessManager::NetworkAccessibility)));
QCOMPARE(manager.networkAccessible(), QNetworkAccessManager::UnknownAccessibility);
// if there is no session, we cannot know in which state we are in
QNetworkAccessManager::NetworkAccessibility initialAccessibility =
manager.networkAccessible();
QCOMPARE(manager.networkAccessible(), initialAccessibility);
manager.setNetworkAccessible(QNetworkAccessManager::NotAccessible);
QCOMPARE(spy.count(), 1);
QCOMPARE(spy.takeFirst().at(0).value<QNetworkAccessManager::NetworkAccessibility>(),
QNetworkAccessManager::NotAccessible);
int expectedCount = (initialAccessibility == QNetworkAccessManager::Accessible) ? 1 : 0;
QCOMPARE(spy.count(), expectedCount);
if (expectedCount > 0)
QCOMPARE(spy.takeFirst().at(0).value<QNetworkAccessManager::NetworkAccessibility>(),
QNetworkAccessManager::NotAccessible);
QCOMPARE(manager.networkAccessible(), QNetworkAccessManager::NotAccessible);
manager.setNetworkAccessible(QNetworkAccessManager::Accessible);
QCOMPARE(spy.count(), 1);
QCOMPARE(spy.takeFirst().at(0).value<QNetworkAccessManager::NetworkAccessibility>(),
QNetworkAccessManager::UnknownAccessibility);
QCOMPARE(manager.networkAccessible(), QNetworkAccessManager::UnknownAccessibility);
QCOMPARE(spy.count(), expectedCount);
if (expectedCount > 0)
QCOMPARE(spy.takeFirst().at(0).value<QNetworkAccessManager::NetworkAccessibility>(),
initialAccessibility);
QCOMPARE(manager.networkAccessible(), initialAccessibility);
QNetworkConfigurationManager configManager;
bool sessionRequired = (configManager.capabilities()
& QNetworkConfigurationManager::NetworkSessionRequired);
QNetworkConfiguration defaultConfig = configManager.defaultConfiguration();
if (defaultConfig.isValid()) {
manager.setConfiguration(defaultConfig);
QCOMPARE(spy.count(), 1);
QCOMPARE(spy.takeFirst().at(0).value<QNetworkAccessManager::NetworkAccessibility>(),
QNetworkAccessManager::Accessible);
// the accessibility has not changed if no session is required
if (sessionRequired) {
QCOMPARE(spy.count(), 1);
QCOMPARE(spy.takeFirst().at(0).value<QNetworkAccessManager::NetworkAccessibility>(),
QNetworkAccessManager::Accessible);
} else {
QCOMPARE(spy.count(), 0);
}
QCOMPARE(manager.networkAccessible(), QNetworkAccessManager::Accessible);
manager.setNetworkAccessible(QNetworkAccessManager::NotAccessible);