Skip to content

Commit

Permalink
[mer][qtnetwork] Create new QNetworkSession from the new online QNetw…
Browse files Browse the repository at this point in the history
…orkConfiguration. Fixes JB#34613

When network configuration configuration changes, use the QNetworkConfiguration
argument within the slot as the QNetworkConfigurationManager::defaultConfiguration()
points to the previous default configuration. Default configration
in turn is wrong e.g. when turning WLAN on so that cellular is
already enabled. This happens because the Qt Connman Bearer plugin finds
the cellular AP from the access point list.

Further, do not close QNetworkSession when changing from WLAN to cellular
as the network session created for WLAN should be kept alive.
  • Loading branch information
rainemak authored and denexter committed Jun 5, 2018
1 parent 8969865 commit 92becaf
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 7 deletions.
59 changes: 52 additions & 7 deletions src/network/access/qnetworkaccessmanager.cpp
Expand Up @@ -61,6 +61,7 @@
#include "qnetworkreplyfileimpl_p.h"

#include "QtCore/qbuffer.h"
#include "QtCore/qloggingcategory.h"
#include "QtCore/qurl.h"
#include "QtCore/qvector.h"
#include "QtNetwork/private/qauthenticator_p.h"
Expand All @@ -85,6 +86,8 @@

QT_BEGIN_NAMESPACE

Q_LOGGING_CATEGORY(lcNetworkAccess, "qt.network.access", QtWarningMsg)

Q_GLOBAL_STATIC(QNetworkAccessFileBackendFactory, fileBackend)
#if QT_CONFIG(ftp)
Q_GLOBAL_STATIC(QNetworkAccessFtpBackendFactory, ftpBackend)
Expand Down Expand Up @@ -1098,6 +1101,37 @@ QSharedPointer<QNetworkSession> QNetworkAccessManagerPrivate::getNetworkSession(
return networkSessionWeakRef.toStrongRef();
}

bool QNetworkAccessManagerPrivate::networkSessionCreationAllowed(const QNetworkConfiguration &configuration) const
{
// Do not allow network session creation if changing to non Wlan when Wlan already active.
// cellular to WLAN -> ok
// cellular to cellular -> ok
// WLAN to cellular -> not ok
// WLAN to WLAN -> ok

bool wlanActive = false;
const auto activeConfigurations = networkConfigurationManager.allConfigurations(QNetworkConfiguration::Active);
if (configuration.bearerTypeFamily() != QNetworkConfiguration::BearerWLAN) {
for (const QNetworkConfiguration &config : activeConfigurations) {
if (config.bearerType() == QNetworkConfiguration::BearerWLAN) {
wlanActive = true;
break;
}
}
}

QSharedPointer<QNetworkSession> session(getNetworkSession());
if (session) {
// Prevent moving from WLAN to mobile data.
return !((session->configuration().bearerTypeFamily() == QNetworkConfiguration::BearerWLAN && wlanActive) &&
(configuration.bearerTypeFamily() == QNetworkConfiguration::Bearer2G ||
configuration.bearerTypeFamily() == QNetworkConfiguration::Bearer3G ||
configuration.bearerTypeFamily() == QNetworkConfiguration::Bearer4G));
}

return false;
}

#endif // QT_NO_BEARERMANAGEMENT


Expand Down Expand Up @@ -1773,8 +1807,10 @@ void QNetworkAccessManagerPrivate::createSession(const QNetworkConfiguration &co
networkSessionStrongRef = networkSessionWeakRef.toStrongRef();

QSharedPointer<QNetworkSession> newSession;
if (config.isValid())
if (config.isValid()) {
newSession = QSharedNetworkSessionManager::getSession(config);
qCDebug(lcNetworkAccess) << "QNAM: get network session from network configuration.";
}

if (networkSessionStrongRef) {
//do nothing if new and old session are the same
Expand Down Expand Up @@ -1807,11 +1843,16 @@ void QNetworkAccessManagerPrivate::createSession(const QNetworkConfiguration &co
QObject::connect(networkSessionStrongRef.data(), SIGNAL(opened()), q, SIGNAL(networkSessionConnected()), Qt::QueuedConnection);
//QueuedConnection is used to avoid deleting the networkSession inside its closed signal
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(), &QNetworkSession::stateChanged,
q, [this](QNetworkSession::State s) {
qCDebug(lcNetworkAccess) << "QNAM: network session state changed:" << s;
_q_networkSessionStateChanged(s);
}, Qt::QueuedConnection);
QObject::connect(networkSessionStrongRef.data(), SIGNAL(error(QNetworkSession::SessionError)),
q, SLOT(_q_networkSessionFailed(QNetworkSession::SessionError)));


qCDebug(lcNetworkAccess) << "QNAM: initial network session" << networkSessionStrongRef->configuration().name() << "state:" << networkSessionStrongRef->state();
_q_networkSessionStateChanged(networkSessionStrongRef->state());
}

Expand Down Expand Up @@ -1914,15 +1955,19 @@ void QNetworkAccessManagerPrivate::_q_configurationChanged(const QNetworkConfigu
if (!onlineConfigurations.contains(id)) {
QSharedPointer<QNetworkSession> session(getNetworkSession());
if (session) {
if (online && session->configuration().identifier()
!= networkConfigurationManager.defaultConfiguration().identifier()) {

bool canCreateNetworkSession = networkSessionCreationAllowed(configuration);
// Use the id of the configuration over here as the networkConfigurationManager.defaultConfiguration()
// points to previous default configuration i.e. not yet changed.
if (canCreateNetworkSession && online && session->configuration().identifier() != id) {
qCDebug(lcNetworkAccess) << "QNAM: network session changing from" << session->configuration().name() << "to" << configuration.name();
onlineConfigurations.insert(id);
// CHECK: If it's having Active flag - why would it be disconnected ???
//this one disconnected but another one is online,
// close and create new session
_q_networkSessionClosed();
createSession(networkConfigurationManager.defaultConfiguration());
createSession(configuration);
} else if (!canCreateNetworkSession) {
qCDebug(lcNetworkAccess) << "QNAM: network session changed prevented from" << session->configuration().name() << "to" << configuration.name() << "as WLAN access point already online.";
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/network/access/qnetworkaccessmanager_p.h
Expand Up @@ -150,6 +150,8 @@ class QNetworkAccessManagerPrivate: public QObjectPrivate
void createSession(const QNetworkConfiguration &config);
QSharedPointer<QNetworkSession> getNetworkSession() const;

bool networkSessionCreationAllowed(const QNetworkConfiguration &configuration) const;

void _q_networkSessionClosed();
void _q_networkSessionNewConfigurationActivated();
void _q_networkSessionPreferredConfigurationChanged(const QNetworkConfiguration &config,
Expand Down

0 comments on commit 92becaf

Please sign in to comment.