make sure QNAM reacts to configuration changes

Task-number: QTBUG-49760
Change-Id: Ic52fc9f7999f3dd00ef4022c959361782bd1ccd2
Reviewed-by: Markus Goetz (Woboq GmbH) <markus@woboq.com>
bb10
Lorn Potter 2016-01-15 15:45:27 +10:00 committed by Richard J. Moore
parent 2c90973ebf
commit 1c2210b7b1
3 changed files with 86 additions and 22 deletions

View File

@ -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<QNetworkSession> 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)

View File

@ -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
};

View File

@ -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<QString> onlineConfigurations;
#endif
QNetworkRequest prepareMultipart(const QNetworkRequest &request, QHttpMultiPart *multiPart);