| /**************************************************************************** |
| ** |
| ** Copyright (C) 2016 The Qt Company Ltd. |
| ** Contact: https://www.qt.io/licensing/ |
| ** |
| ** This file is part of the QtNetwork module of the Qt Toolkit. |
| ** |
| ** $QT_BEGIN_LICENSE:LGPL$ |
| ** Commercial License Usage |
| ** Licensees holding valid commercial Qt licenses may use this file in |
| ** accordance with the commercial license agreement provided with the |
| ** Software or, alternatively, in accordance with the terms contained in |
| ** a written agreement between you and The Qt Company. For licensing terms |
| ** and conditions see https://www.qt.io/terms-conditions. For further |
| ** information use the contact form at https://www.qt.io/contact-us. |
| ** |
| ** GNU Lesser General Public License Usage |
| ** Alternatively, this file may be used under the terms of the GNU Lesser |
| ** General Public License version 3 as published by the Free Software |
| ** Foundation and appearing in the file LICENSE.LGPL3 included in the |
| ** packaging of this file. Please review the following information to |
| ** ensure the GNU Lesser General Public License version 3 requirements |
| ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. |
| ** |
| ** GNU General Public License Usage |
| ** Alternatively, this file may be used under the terms of the GNU |
| ** General Public License version 2.0 or (at your option) the GNU General |
| ** Public license version 3 or any later version approved by the KDE Free |
| ** Qt Foundation. The licenses are as published by the Free Software |
| ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 |
| ** included in the packaging of this file. Please review the following |
| ** information to ensure the GNU General Public License requirements will |
| ** be met: https://www.gnu.org/licenses/gpl-2.0.html and |
| ** https://www.gnu.org/licenses/gpl-3.0.html. |
| ** |
| ** $QT_END_LICENSE$ |
| ** |
| ****************************************************************************/ |
| |
| #include <QtNetwork/private/qtnetworkglobal_p.h> |
| |
| #include "qnetworksession.h" |
| #include "qnetworksession_p.h" |
| #include "qbearerengine_p.h" |
| |
| #include <QEventLoop> |
| #include <QMetaMethod> |
| #include <QTimer> |
| #include <QThread> |
| |
| #include "qnetworkconfigmanager_p.h" |
| |
| // for QNetworkSession::interface |
| #ifdef interface |
| # undef interface |
| #endif |
| |
| #ifndef QT_NO_BEARERMANAGEMENT |
| |
| QT_BEGIN_NAMESPACE |
| |
| /*! |
| \class QNetworkSession |
| \obsolete |
| |
| \brief The QNetworkSession class provides control over the system's access points |
| and enables session management for cases when multiple clients access the same access point. |
| |
| \since 4.7 |
| |
| \inmodule QtNetwork |
| \ingroup network |
| |
| A QNetworkSession enables control over the system's network interfaces. The session's configuration |
| parameter are determined via the QNetworkConfiguration object to which it is bound. Depending on the |
| type of the session (single access point or service network) a session may be linked to one or more |
| network interfaces. By means of \l{open()}{opening} and \l{close()}{closing} of network sessions |
| a developer can start and stop the systems network interfaces. If the configuration represents |
| multiple access points (see \l QNetworkConfiguration::ServiceNetwork) more advanced features such as roaming may be supported. |
| |
| QNetworkSession supports session management within the same process and depending on the platform's |
| capabilities may support out-of-process sessions. If the same |
| network configuration is used by multiple open sessions the underlying network interface is only terminated once |
| the last session has been closed. |
| |
| \section1 Roaming |
| |
| Applications may connect to the preferredConfigurationChanged() signal in order to |
| receive notifications when a more suitable access point becomes available. |
| In response to this signal the application must either initiate the roaming via migrate() |
| or ignore() the new access point. Once the session has roamed the |
| newConfigurationActivated() signal is emitted. The application may now test the |
| carrier and must either accept() or reject() it. The session will return to the previous |
| access point if the roaming was rejected. The subsequent state diagram depicts the required |
| state transitions. |
| |
| \image roaming-states.png |
| |
| Some platforms may distinguish forced roaming and application level roaming (ALR). |
| ALR implies that the application controls (via migrate(), ignore(), accept() and reject()) |
| whether a network session can roam from one access point to the next. Such control is useful |
| if the application maintains stateful socket connections and wants to control the transition from |
| one interface to the next. Forced roaming implies that the system automatically roams to the next network without |
| consulting the application. This has the advantage that the application can make use of roaming features |
| without actually being aware of it. It is expected that the application detects that the underlying |
| socket is broken and automatically reconnects via the new network link. |
| |
| If the platform supports both modes of roaming, an application indicates its preference |
| by connecting to the preferredConfigurationChanged() signal. Connecting to this signal means that |
| the application wants to take control over the roaming behavior and therefore implies application |
| level roaming. If the client does not connect to the preferredConfigurationChanged(), forced roaming |
| is used. If forced roaming is not supported the network session will not roam by default. |
| |
| Some applications may want to suppress any form of roaming altogether. Possible use cases may be |
| high priority downloads or remote services which cannot handle a roaming enabled client. Clients |
| can suppress roaming by connecting to the preferredConfigurationChanged() signal and answer each |
| signal emission with ignore(). |
| |
| \sa QNetworkConfiguration, QNetworkConfigurationManager |
| */ |
| |
| /*! |
| \enum QNetworkSession::State |
| |
| This enum describes the connectivity state of the session. If the session is based on a |
| single access point configuration the state of the session is the same as the state of the |
| associated network interface. |
| |
| \value Invalid The session is invalid due to an invalid configuration. This may |
| happen due to a removed access point or a configuration that was |
| invalid to begin with. |
| \value NotAvailable The session is based on a defined but not yet discovered QNetworkConfiguration |
| (see \l QNetworkConfiguration::StateFlag). |
| \value Connecting The network session is being established. |
| \value Connected The network session is connected. If the current process wishes to use this session |
| it has to register its interest by calling open(). A network session |
| is considered to be ready for socket operations if it isOpen() and connected. |
| \value Closing The network session is in the process of being shut down. |
| \value Disconnected The network session is not connected. The associated QNetworkConfiguration |
| has the state QNetworkConfiguration::Discovered. |
| \value Roaming The network session is roaming from one access point to another |
| access point. |
| */ |
| |
| /*! |
| \enum QNetworkSession::SessionError |
| |
| This enum describes the session errors that can occur. |
| |
| \value UnknownSessionError An unidentified error occurred. |
| \value SessionAbortedError The session was aborted by the user or system. |
| \value RoamingError The session cannot roam to a new configuration. |
| \value OperationNotSupportedError The operation is not supported for current configuration. |
| \value InvalidConfigurationError The operation cannot currently be performed for the |
| current configuration. |
| */ |
| |
| /*! |
| \enum QNetworkSession::UsagePolicy |
| \since 5.0 |
| |
| These flags allow the system to inform the application of network usage restrictions that |
| may be in place. |
| |
| \value NoPolicy No policy in force, usage is unrestricted. |
| \value NoBackgroundTrafficPolicy Background network traffic (not user initiated) should be avoided |
| for example to save battery or data charges |
| */ |
| |
| /*! |
| \fn void QNetworkSession::stateChanged(QNetworkSession::State state) |
| |
| This signal is emitted whenever the state of the network session changes. |
| The \a state parameter is the new state. |
| |
| \sa state() |
| */ |
| |
| /*! |
| \fn void QNetworkSession::error(QNetworkSession::SessionError error) |
| |
| This signal is emitted after an error occurred. The \a error parameter |
| describes the error that occurred. |
| |
| \sa error(), errorString() |
| */ |
| |
| /*! |
| \fn void QNetworkSession::preferredConfigurationChanged(const QNetworkConfiguration &config, bool isSeamless) |
| |
| This signal is emitted when the preferred configuration/access point for the |
| session changes. Only sessions which are based on service network configurations |
| may emit this signal. \a config can be used to determine access point specific |
| details such as proxy settings and \a isSeamless indicates whether roaming will |
| break the sessions IP address. |
| |
| As a consequence to this signal the application must either start the roaming process |
| by calling migrate() or choose to ignore() the new access point. |
| |
| If the roaming process is non-seamless the IP address will change which means that |
| a socket becomes invalid. However seamless mobility can ensure that the local IP address |
| does not change. This is achieved by using a virtual IP address which is bound to the actual |
| link address. During the roaming process the virtual address is attached to the new link |
| address. |
| |
| Some platforms may support the concept of Forced Roaming and Application Level Roaming (ALR). |
| Forced roaming implies that the platform may simply roam to a new configuration without |
| consulting applications. It is up to the application to detect the link layer loss and reestablish |
| its sockets. In contrast ALR provides the opportunity to prevent the system from roaming. |
| If this session is based on a configuration that supports roaming the application can choose |
| whether it wants to be consulted (ALR use case) by connecting to this signal. For as long as this signal |
| connection remains the session remains registered as a roaming stakeholder; otherwise roaming will |
| be enforced by the platform. |
| |
| \sa migrate(), ignore(), QNetworkConfiguration::isRoamingAvailable() |
| */ |
| |
| /*! |
| \fn void QNetworkSession::newConfigurationActivated() |
| |
| This signal is emitted once the session has roamed to the new access point. |
| The application may reopen its socket and test the suitability of the new network link. |
| Subsequently it must either accept() or reject() the new access point. |
| |
| \sa accept(), reject() |
| */ |
| |
| /*! |
| \fn void QNetworkSession::opened() |
| |
| This signal is emitted when the network session has been opened. |
| |
| The underlying network interface will not be shut down as long as the session remains open. |
| Note that this feature is dependent on \l{QNetworkConfigurationManager::SystemSessionSupport}{system wide session support}. |
| */ |
| |
| /*! |
| \fn void QNetworkSession::closed() |
| |
| This signal is emitted when the network session has been closed. |
| */ |
| |
| /*! |
| \fn void QNetworkSession::usagePoliciesChanged(QNetworkSession::UsagePolicies usagePolicies) |
| \since 5.0 |
| |
| This signal is emitted when the \a usagePolicies in force are changed by the system. |
| */ |
| |
| /*! |
| Constructs a session based on \a connectionConfig with the given \a parent. |
| |
| \sa QNetworkConfiguration |
| */ |
| QNetworkSession::QNetworkSession(const QNetworkConfiguration &connectionConfig, QObject *parent) |
| : QObject(parent), d(nullptr) |
| { |
| qRegisterMetaType<QNetworkSession::State>(); |
| qRegisterMetaType<QNetworkSession::SessionError>(); |
| qRegisterMetaType<QNetworkSession::UsagePolicies>(); |
| |
| // invalid configuration |
| if (!connectionConfig.identifier().isEmpty()) { |
| auto priv = qNetworkConfigurationManagerPrivate(); |
| const auto engines = priv ? priv->engines() : QList<QBearerEngine *>(); |
| for (QBearerEngine *engine : engines) { |
| if (engine->hasIdentifier(connectionConfig.identifier())) { |
| d = engine->createSessionBackend(); |
| d->q = this; |
| d->publicConfig = connectionConfig; |
| d->syncStateWithInterface(); |
| connect(d, SIGNAL(quitPendingWaitsForOpened()), this, SIGNAL(opened())); |
| connect(d, SIGNAL(error(QNetworkSession::SessionError)), |
| this, SIGNAL(error(QNetworkSession::SessionError))); |
| connect(d, SIGNAL(stateChanged(QNetworkSession::State)), |
| this, SIGNAL(stateChanged(QNetworkSession::State))); |
| connect(d, SIGNAL(closed()), this, SIGNAL(closed())); |
| connect(d, SIGNAL(preferredConfigurationChanged(QNetworkConfiguration,bool)), |
| this, SIGNAL(preferredConfigurationChanged(QNetworkConfiguration,bool))); |
| connect(d, SIGNAL(newConfigurationActivated()), |
| this, SIGNAL(newConfigurationActivated())); |
| connect(d, SIGNAL(usagePoliciesChanged(QNetworkSession::UsagePolicies)), |
| this, SIGNAL(usagePoliciesChanged(QNetworkSession::UsagePolicies))); |
| break; |
| } |
| } |
| } |
| } |
| |
| /*! |
| Frees the resources associated with the QNetworkSession object. |
| */ |
| QNetworkSession::~QNetworkSession() |
| { |
| delete d; |
| } |
| |
| /*! |
| Creates an open session which increases the session counter on the underlying network interface. |
| The system will not terminate a network interface until the session reference counter reaches zero. |
| Therefore an open session allows an application to register its use of the interface. |
| |
| As a result of calling open() the interface will be started if it is not connected/up yet. |
| Some platforms may not provide support for out-of-process sessions. On such platforms the session |
| counter ignores any sessions held by another process. The platform capabilities can be |
| detected via QNetworkConfigurationManager::capabilities(). |
| |
| Note that this call is asynchronous. Depending on the outcome of this call the results can be enquired |
| by connecting to the stateChanged(), opened() or error() signals. |
| |
| It is not a requirement to open a session in order to monitor the underlying network interface. |
| |
| \sa close(), stop(), isOpen() |
| */ |
| void QNetworkSession::open() |
| { |
| if (d) |
| d->open(); |
| else |
| emit error(InvalidConfigurationError); |
| } |
| |
| /*! |
| Waits until the session has been opened, up to \a msecs milliseconds. If the session has been opened, this |
| function returns \c true; otherwise it returns \c false. In the case where it returns \c false, you can call error() |
| to determine the cause of the error. |
| |
| The following example waits up to one second for the session to be opened: |
| |
| \snippet code/src_network_bearer_qnetworksession.cpp 0 |
| |
| If \a msecs is -1, this function will not time out. |
| |
| \sa open(), error() |
| */ |
| bool QNetworkSession::waitForOpened(int msecs) |
| { |
| if (!d) |
| return false; |
| |
| if (d->isOpen) |
| return true; |
| |
| if (!(d->state == Connecting || d->state == Connected)) { |
| return false; |
| } |
| |
| QEventLoop loop; |
| QObject::connect(d, SIGNAL(quitPendingWaitsForOpened()), &loop, SLOT(quit())); |
| QObject::connect(this, SIGNAL(error(QNetworkSession::SessionError)), &loop, SLOT(quit())); |
| |
| //final call |
| if (msecs >= 0) |
| QTimer::singleShot(msecs, &loop, SLOT(quit())); |
| |
| // enter the event loop and wait for opened/error/timeout |
| loop.exec(QEventLoop::ExcludeUserInputEvents | QEventLoop::WaitForMoreEvents); |
| |
| return d->isOpen; |
| } |
| |
| /*! |
| Decreases the session counter on the associated network configuration. If the session counter reaches zero |
| the active network interface is shut down. This also means that state() will only change from \l Connected to |
| \l Disconnected if the current session was the last open session. |
| |
| If the platform does not support out-of-process sessions calling this function does not stop the |
| interface. In this case \l{stop()} has to be used to force a shut down. |
| The platform capabilities can be detected via QNetworkConfigurationManager::capabilities(). |
| |
| Note that this call is asynchronous. Depending on the outcome of this call the results can be enquired |
| by connecting to the stateChanged(), opened() or error() signals. |
| |
| \sa open(), stop(), isOpen() |
| */ |
| void QNetworkSession::close() |
| { |
| if (d) |
| d->close(); |
| } |
| |
| /*! |
| Invalidates all open sessions against the network interface and therefore stops the |
| underlying network interface. This function always changes the session's state() flag to |
| \l Disconnected. |
| |
| \sa open(), close() |
| */ |
| void QNetworkSession::stop() |
| { |
| if (d) |
| d->stop(); |
| } |
| |
| /*! |
| Returns the QNetworkConfiguration that this network session object is based on. |
| |
| \sa QNetworkConfiguration |
| */ |
| QNetworkConfiguration QNetworkSession::configuration() const |
| { |
| return d ? d->publicConfig : QNetworkConfiguration(); |
| } |
| |
| #ifndef QT_NO_NETWORKINTERFACE |
| /*! |
| Returns the network interface that is used by this session. |
| |
| This function only returns a valid QNetworkInterface when this session is \l Connected. |
| |
| The returned interface may change as a result of a roaming process. |
| |
| \sa state() |
| */ |
| QNetworkInterface QNetworkSession::interface() const |
| { |
| return d ? d->currentInterface() : QNetworkInterface(); |
| } |
| #endif |
| |
| /*! |
| Returns \c true if this session is open. If the number of all open sessions is greater than |
| zero the underlying network interface will remain connected/up. |
| |
| The session can be controlled via open() and close(). |
| */ |
| bool QNetworkSession::isOpen() const |
| { |
| return d ? d->isOpen : false; |
| } |
| |
| /*! |
| Returns the state of the session. |
| |
| If the session is based on a single access point configuration the state of the |
| session is the same as the state of the associated network interface. Therefore |
| a network session object can be used to monitor network interfaces. |
| |
| A \l QNetworkConfiguration::ServiceNetwork based session summarizes the state of all its children |
| and therefore returns the \l Connected state if at least one of the service network's |
| \l {QNetworkConfiguration::children()}{children()} configurations is active. |
| |
| Note that it is not required to hold an open session in order to obtain the network interface state. |
| A connected but closed session may be used to monitor network interfaces whereas an open and connected |
| session object may prevent the network interface from being shut down. |
| |
| \sa error(), stateChanged() |
| */ |
| QNetworkSession::State QNetworkSession::state() const |
| { |
| return d ? d->state : QNetworkSession::Invalid; |
| } |
| |
| /*! |
| Returns the type of error that last occurred. |
| |
| \sa state(), errorString() |
| */ |
| QNetworkSession::SessionError QNetworkSession::error() const |
| { |
| return d ? d->error() : InvalidConfigurationError; |
| } |
| |
| /*! |
| Returns a human-readable description of the last device error that |
| occurred. |
| |
| \sa error() |
| */ |
| QString QNetworkSession::errorString() const |
| { |
| return d ? d->errorString() : tr("Invalid configuration."); |
| } |
| |
| /*! |
| Returns the value for property \a key. |
| |
| A network session can have properties attached which may describe the session in more details. |
| This function can be used to gain access to those properties. |
| |
| The following property keys are guaranteed to be specified on all platforms: |
| |
| \table 80% |
| \header |
| \li Key \li Description |
| \row |
| \li ActiveConfiguration |
| \li If the session \l isOpen() this property returns the identifier of the |
| QNetworkConfiguration that is used by this session; otherwise an empty string. |
| |
| The main purpose of this key is to determine which Internet access point is used |
| if the session is based on a \l{QNetworkConfiguration::ServiceNetwork}{ServiceNetwork}. |
| The following code snippet highlights the difference: |
| \snippet code/src_network_bearer_qnetworksession.cpp 1 |
| \row |
| \li UserChoiceConfiguration |
| \li If the session \l isOpen() and is bound to a QNetworkConfiguration of type |
| UserChoice, this property returns the identifier of the QNetworkConfiguration that the |
| configuration resolved to when \l open() was called; otherwise an empty string. |
| |
| The purpose of this key is to determine the real QNetworkConfiguration that the |
| session is using. This key is different from \e ActiveConfiguration in that |
| this key may return an identifier for either a |
| \l {QNetworkConfiguration::ServiceNetwork}{service network} or a |
| \l {QNetworkConfiguration::InternetAccessPoint}{Internet access points} configurations, |
| whereas \e ActiveConfiguration always returns identifiers to |
| \l {QNetworkConfiguration::InternetAccessPoint}{Internet access points} configurations. |
| \row |
| \li ConnectInBackground |
| \li Setting this property to \e true before calling \l open() implies that the connection attempt |
| is made but if no connection can be established, the user is not connsulted and asked to select |
| a suitable connection. This property is not set by default and support for it depends on the platform. |
| |
| \row |
| \li AutoCloseSessionTimeout |
| \li If the session requires polling to keep its state up to date, this property holds |
| the timeout in milliseconds before the session will automatically close. If the |
| value of this property is -1 the session will not automatically close. This property |
| is set to -1 by default. |
| |
| The purpose of this property is to minimize resource use on platforms that use |
| polling to update the state of the session. Applications can set the value of this |
| property to the desired timeout before the session is closed. In response to the |
| closed() signal the network session should be deleted to ensure that all polling is |
| stopped. The session can then be recreated once it is required again. This property |
| has no effect for sessions that do not require polling. |
| \endtable |
| */ |
| QVariant QNetworkSession::sessionProperty(const QString &key) const |
| { |
| if (!d || !d->publicConfig.isValid()) |
| return QVariant(); |
| |
| if (key == QLatin1String("ActiveConfiguration")) |
| return d->isOpen ? d->activeConfig.identifier() : QString(); |
| |
| if (key == QLatin1String("UserChoiceConfiguration")) { |
| if (!d->isOpen || d->publicConfig.type() != QNetworkConfiguration::UserChoice) |
| return QString(); |
| |
| if (d->serviceConfig.isValid()) |
| return d->serviceConfig.identifier(); |
| else |
| return d->activeConfig.identifier(); |
| } |
| |
| return d->sessionProperty(key); |
| } |
| |
| /*! |
| Sets the property \a value on the session. The property is identified using |
| \a key. Removing an already set property can be achieved by passing an |
| invalid QVariant. |
| |
| Note that the \e UserChoiceConfiguration and \e ActiveConfiguration |
| properties are read only and cannot be changed using this method. |
| */ |
| void QNetworkSession::setSessionProperty(const QString &key, const QVariant &value) |
| { |
| if (!d) |
| return; |
| |
| if (key == QLatin1String("ActiveConfiguration") || |
| key == QLatin1String("UserChoiceConfiguration")) { |
| return; |
| } |
| |
| d->setSessionProperty(key, value); |
| } |
| |
| /*! |
| Instructs the session to roam to the new access point. The old access point remains active |
| until the application calls accept(). |
| |
| The newConfigurationActivated() signal is emitted once roaming has been completed. |
| |
| \sa accept() |
| */ |
| void QNetworkSession::migrate() |
| { |
| if (d) |
| d->migrate(); |
| } |
| |
| /*! |
| This function indicates that the application does not wish to roam the session. |
| |
| \sa migrate() |
| */ |
| void QNetworkSession::ignore() |
| { |
| if (d) |
| d->ignore(); |
| } |
| |
| /*! |
| Instructs the session to permanently accept the new access point. Once this function |
| has been called the session may not return to the old access point. |
| |
| The old access point may be closed in the process if there are no other network sessions for it. |
| Therefore any open socket that still uses the old access point |
| may become unusable and should be closed before completing the migration. |
| */ |
| void QNetworkSession::accept() |
| { |
| if (d) |
| d->accept(); |
| } |
| |
| /*! |
| The new access point is not suitable for the application. By calling this function the |
| session returns to the previous access point/configuration. This action may invalidate |
| any socket that has been created via the not desired access point. |
| |
| \sa accept() |
| */ |
| void QNetworkSession::reject() |
| { |
| if (d) |
| d->reject(); |
| } |
| |
| |
| /*! |
| Returns the amount of data sent in bytes; otherwise 0. |
| |
| This field value includes the usage across all open network |
| sessions which use the same network interface. |
| |
| If the session is based on a service network configuration the number of |
| sent bytes across all active member configurations are returned. |
| |
| This function may not always be supported on all platforms and returns 0. |
| The platform capability can be detected via QNetworkConfigurationManager::DataStatistics. |
| |
| \note On some platforms this function may run the main event loop. |
| */ |
| quint64 QNetworkSession::bytesWritten() const |
| { |
| return d ? d->bytesWritten() : Q_UINT64_C(0); |
| } |
| |
| /*! |
| Returns the amount of data received in bytes; otherwise 0. |
| |
| This field value includes the usage across all open network |
| sessions which use the same network interface. |
| |
| If the session is based on a service network configuration the number of |
| sent bytes across all active member configurations are returned. |
| |
| This function may not always be supported on all platforms and returns 0. |
| The platform capability can be detected via QNetworkConfigurationManager::DataStatistics. |
| |
| \note On some platforms this function may run the main event loop. |
| */ |
| quint64 QNetworkSession::bytesReceived() const |
| { |
| return d ? d->bytesReceived() : Q_UINT64_C(0); |
| } |
| |
| /*! |
| Returns the number of seconds that the session has been active. |
| */ |
| quint64 QNetworkSession::activeTime() const |
| { |
| return d ? d->activeTime() : Q_UINT64_C(0); |
| } |
| |
| /*! |
| Returns the network usage policies currently in force by the system. |
| */ |
| QNetworkSession::UsagePolicies QNetworkSession::usagePolicies() const |
| { |
| return d ? d->usagePolicies() : QNetworkSession::NoPolicy; |
| } |
| |
| /*! |
| \internal |
| Change usage policies for unit testing. |
| In normal use, the policies are published by the bearer plugin |
| */ |
| void QNetworkSessionPrivate::setUsagePolicies(QNetworkSession &session, QNetworkSession::UsagePolicies policies) |
| { |
| if (!session.d) |
| return; |
| session.d->setUsagePolicies(policies); |
| } |
| |
| /*! |
| \internal |
| |
| This function is required to detect whether the client wants to control |
| the roaming process. If he connects to preferredConfigurationChanged() signal |
| he intends to influence it. Otherwise QNetworkSession always roams |
| without registering this session as a stakeholder in the roaming process. |
| |
| For more details check the Forced vs ALR roaming section in the QNetworkSession |
| class description. |
| */ |
| void QNetworkSession::connectNotify(const QMetaMethod &signal) |
| { |
| QObject::connectNotify(signal); |
| |
| if (!d) |
| return; |
| |
| //check for preferredConfigurationChanged() signal connect notification |
| //This is not required on all platforms |
| static const QMetaMethod preferredConfigurationChangedSignal = |
| QMetaMethod::fromSignal(&QNetworkSession::preferredConfigurationChanged); |
| if (signal == preferredConfigurationChangedSignal) |
| d->setALREnabled(true); |
| } |
| |
| /*! |
| \internal |
| |
| This function is called when the client disconnects from the |
| preferredConfigurationChanged() signal. |
| |
| \sa connectNotify() |
| */ |
| void QNetworkSession::disconnectNotify(const QMetaMethod &signal) |
| { |
| QObject::disconnectNotify(signal); |
| |
| if (!d) |
| return; |
| |
| //check for preferredConfigurationChanged() signal disconnect notification |
| //This is not required on all platforms |
| static const QMetaMethod preferredConfigurationChangedSignal = |
| QMetaMethod::fromSignal(&QNetworkSession::preferredConfigurationChanged); |
| if (signal == preferredConfigurationChangedSignal) |
| d->setALREnabled(false); |
| } |
| |
| QT_END_NAMESPACE |
| |
| #include "moc_qnetworksession.cpp" |
| |
| #endif // QT_NO_BEARERMANAGEMENT |