1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtNetwork module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include <QtNetwork/private/qtnetworkglobal_p.h>
41
42#include "qnetworksession.h"
43#include "qnetworksession_p.h"
44#include "qbearerengine_p.h"
45
46#include <QEventLoop>
47#include <QMetaMethod>
48#include <QTimer>
49#include <QThread>
50
51#include "qnetworkconfigmanager_p.h"
52
53// for QNetworkSession::interface
54#ifdef interface
55# undef interface
56#endif
57
58#ifndef QT_NO_BEARERMANAGEMENT
59
60QT_BEGIN_NAMESPACE
61
62/*!
63 \class QNetworkSession
64 \obsolete
65
66 \brief The QNetworkSession class provides control over the system's access points
67 and enables session management for cases when multiple clients access the same access point.
68
69 \since 4.7
70
71 \inmodule QtNetwork
72 \ingroup network
73
74 A QNetworkSession enables control over the system's network interfaces. The session's configuration
75 parameter are determined via the QNetworkConfiguration object to which it is bound. Depending on the
76 type of the session (single access point or service network) a session may be linked to one or more
77 network interfaces. By means of \l{open()}{opening} and \l{close()}{closing} of network sessions
78 a developer can start and stop the systems network interfaces. If the configuration represents
79 multiple access points (see \l QNetworkConfiguration::ServiceNetwork) more advanced features such as roaming may be supported.
80
81 QNetworkSession supports session management within the same process and depending on the platform's
82 capabilities may support out-of-process sessions. If the same
83 network configuration is used by multiple open sessions the underlying network interface is only terminated once
84 the last session has been closed.
85
86 \section1 Roaming
87
88 Applications may connect to the preferredConfigurationChanged() signal in order to
89 receive notifications when a more suitable access point becomes available.
90 In response to this signal the application must either initiate the roaming via migrate()
91 or ignore() the new access point. Once the session has roamed the
92 newConfigurationActivated() signal is emitted. The application may now test the
93 carrier and must either accept() or reject() it. The session will return to the previous
94 access point if the roaming was rejected. The subsequent state diagram depicts the required
95 state transitions.
96
97 \image roaming-states.png
98
99 Some platforms may distinguish forced roaming and application level roaming (ALR).
100 ALR implies that the application controls (via migrate(), ignore(), accept() and reject())
101 whether a network session can roam from one access point to the next. Such control is useful
102 if the application maintains stateful socket connections and wants to control the transition from
103 one interface to the next. Forced roaming implies that the system automatically roams to the next network without
104 consulting the application. This has the advantage that the application can make use of roaming features
105 without actually being aware of it. It is expected that the application detects that the underlying
106 socket is broken and automatically reconnects via the new network link.
107
108 If the platform supports both modes of roaming, an application indicates its preference
109 by connecting to the preferredConfigurationChanged() signal. Connecting to this signal means that
110 the application wants to take control over the roaming behavior and therefore implies application
111 level roaming. If the client does not connect to the preferredConfigurationChanged(), forced roaming
112 is used. If forced roaming is not supported the network session will not roam by default.
113
114 Some applications may want to suppress any form of roaming altogether. Possible use cases may be
115 high priority downloads or remote services which cannot handle a roaming enabled client. Clients
116 can suppress roaming by connecting to the preferredConfigurationChanged() signal and answer each
117 signal emission with ignore().
118
119 \sa QNetworkConfiguration, QNetworkConfigurationManager
120*/
121
122/*!
123 \enum QNetworkSession::State
124
125 This enum describes the connectivity state of the session. If the session is based on a
126 single access point configuration the state of the session is the same as the state of the
127 associated network interface.
128
129 \value Invalid The session is invalid due to an invalid configuration. This may
130 happen due to a removed access point or a configuration that was
131 invalid to begin with.
132 \value NotAvailable The session is based on a defined but not yet discovered QNetworkConfiguration
133 (see \l QNetworkConfiguration::StateFlag).
134 \value Connecting The network session is being established.
135 \value Connected The network session is connected. If the current process wishes to use this session
136 it has to register its interest by calling open(). A network session
137 is considered to be ready for socket operations if it isOpen() and connected.
138 \value Closing The network session is in the process of being shut down.
139 \value Disconnected The network session is not connected. The associated QNetworkConfiguration
140 has the state QNetworkConfiguration::Discovered.
141 \value Roaming The network session is roaming from one access point to another
142 access point.
143*/
144
145/*!
146 \enum QNetworkSession::SessionError
147
148 This enum describes the session errors that can occur.
149
150 \value UnknownSessionError An unidentified error occurred.
151 \value SessionAbortedError The session was aborted by the user or system.
152 \value RoamingError The session cannot roam to a new configuration.
153 \value OperationNotSupportedError The operation is not supported for current configuration.
154 \value InvalidConfigurationError The operation cannot currently be performed for the
155 current configuration.
156*/
157
158/*!
159 \enum QNetworkSession::UsagePolicy
160 \since 5.0
161
162 These flags allow the system to inform the application of network usage restrictions that
163 may be in place.
164
165 \value NoPolicy No policy in force, usage is unrestricted.
166 \value NoBackgroundTrafficPolicy Background network traffic (not user initiated) should be avoided
167 for example to save battery or data charges
168*/
169
170/*!
171 \fn void QNetworkSession::stateChanged(QNetworkSession::State state)
172
173 This signal is emitted whenever the state of the network session changes.
174 The \a state parameter is the new state.
175
176 \sa state()
177*/
178
179/*!
180 \fn void QNetworkSession::error(QNetworkSession::SessionError error)
181
182 This signal is emitted after an error occurred. The \a error parameter
183 describes the error that occurred.
184
185 \sa error(), errorString()
186*/
187
188/*!
189 \fn void QNetworkSession::preferredConfigurationChanged(const QNetworkConfiguration &config, bool isSeamless)
190
191 This signal is emitted when the preferred configuration/access point for the
192 session changes. Only sessions which are based on service network configurations
193 may emit this signal. \a config can be used to determine access point specific
194 details such as proxy settings and \a isSeamless indicates whether roaming will
195 break the sessions IP address.
196
197 As a consequence to this signal the application must either start the roaming process
198 by calling migrate() or choose to ignore() the new access point.
199
200 If the roaming process is non-seamless the IP address will change which means that
201 a socket becomes invalid. However seamless mobility can ensure that the local IP address
202 does not change. This is achieved by using a virtual IP address which is bound to the actual
203 link address. During the roaming process the virtual address is attached to the new link
204 address.
205
206 Some platforms may support the concept of Forced Roaming and Application Level Roaming (ALR).
207 Forced roaming implies that the platform may simply roam to a new configuration without
208 consulting applications. It is up to the application to detect the link layer loss and reestablish
209 its sockets. In contrast ALR provides the opportunity to prevent the system from roaming.
210 If this session is based on a configuration that supports roaming the application can choose
211 whether it wants to be consulted (ALR use case) by connecting to this signal. For as long as this signal
212 connection remains the session remains registered as a roaming stakeholder; otherwise roaming will
213 be enforced by the platform.
214
215 \sa migrate(), ignore(), QNetworkConfiguration::isRoamingAvailable()
216*/
217
218/*!
219 \fn void QNetworkSession::newConfigurationActivated()
220
221 This signal is emitted once the session has roamed to the new access point.
222 The application may reopen its socket and test the suitability of the new network link.
223 Subsequently it must either accept() or reject() the new access point.
224
225 \sa accept(), reject()
226*/
227
228/*!
229 \fn void QNetworkSession::opened()
230
231 This signal is emitted when the network session has been opened.
232
233 The underlying network interface will not be shut down as long as the session remains open.
234 Note that this feature is dependent on \l{QNetworkConfigurationManager::SystemSessionSupport}{system wide session support}.
235*/
236
237/*!
238 \fn void QNetworkSession::closed()
239
240 This signal is emitted when the network session has been closed.
241*/
242
243/*!
244 \fn void QNetworkSession::usagePoliciesChanged(QNetworkSession::UsagePolicies usagePolicies)
245 \since 5.0
246
247 This signal is emitted when the \a usagePolicies in force are changed by the system.
248*/
249
250/*!
251 Constructs a session based on \a connectionConfig with the given \a parent.
252
253 \sa QNetworkConfiguration
254*/
255QNetworkSession::QNetworkSession(const QNetworkConfiguration &connectionConfig, QObject *parent)
256 : QObject(parent), d(nullptr)
257{
258 qRegisterMetaType<QNetworkSession::State>();
259 qRegisterMetaType<QNetworkSession::SessionError>();
260 qRegisterMetaType<QNetworkSession::UsagePolicies>();
261
262 // invalid configuration
263 if (!connectionConfig.identifier().isEmpty()) {
264 auto priv = qNetworkConfigurationManagerPrivate();
265 const auto engines = priv ? priv->engines() : QList<QBearerEngine *>();
266 for (QBearerEngine *engine : engines) {
267 if (engine->hasIdentifier(id: connectionConfig.identifier())) {
268 d = engine->createSessionBackend();
269 d->q = this;
270 d->publicConfig = connectionConfig;
271 d->syncStateWithInterface();
272 connect(sender: d, SIGNAL(quitPendingWaitsForOpened()), receiver: this, SIGNAL(opened()));
273 connect(sender: d, SIGNAL(error(QNetworkSession::SessionError)),
274 receiver: this, SIGNAL(error(QNetworkSession::SessionError)));
275 connect(sender: d, SIGNAL(stateChanged(QNetworkSession::State)),
276 receiver: this, SIGNAL(stateChanged(QNetworkSession::State)));
277 connect(sender: d, SIGNAL(closed()), receiver: this, SIGNAL(closed()));
278 connect(sender: d, SIGNAL(preferredConfigurationChanged(QNetworkConfiguration,bool)),
279 receiver: this, SIGNAL(preferredConfigurationChanged(QNetworkConfiguration,bool)));
280 connect(sender: d, SIGNAL(newConfigurationActivated()),
281 receiver: this, SIGNAL(newConfigurationActivated()));
282 connect(sender: d, SIGNAL(usagePoliciesChanged(QNetworkSession::UsagePolicies)),
283 receiver: this, SIGNAL(usagePoliciesChanged(QNetworkSession::UsagePolicies)));
284 break;
285 }
286 }
287 }
288}
289
290/*!
291 Frees the resources associated with the QNetworkSession object.
292*/
293QNetworkSession::~QNetworkSession()
294{
295 delete d;
296}
297
298/*!
299 Creates an open session which increases the session counter on the underlying network interface.
300 The system will not terminate a network interface until the session reference counter reaches zero.
301 Therefore an open session allows an application to register its use of the interface.
302
303 As a result of calling open() the interface will be started if it is not connected/up yet.
304 Some platforms may not provide support for out-of-process sessions. On such platforms the session
305 counter ignores any sessions held by another process. The platform capabilities can be
306 detected via QNetworkConfigurationManager::capabilities().
307
308 Note that this call is asynchronous. Depending on the outcome of this call the results can be enquired
309 by connecting to the stateChanged(), opened() or error() signals.
310
311 It is not a requirement to open a session in order to monitor the underlying network interface.
312
313 \sa close(), stop(), isOpen()
314*/
315void QNetworkSession::open()
316{
317 if (d)
318 d->open();
319 else
320 emit error(InvalidConfigurationError);
321}
322
323/*!
324 Waits until the session has been opened, up to \a msecs milliseconds. If the session has been opened, this
325 function returns \c true; otherwise it returns \c false. In the case where it returns \c false, you can call error()
326 to determine the cause of the error.
327
328 The following example waits up to one second for the session to be opened:
329
330 \snippet code/src_network_bearer_qnetworksession.cpp 0
331
332 If \a msecs is -1, this function will not time out.
333
334 \sa open(), error()
335*/
336bool QNetworkSession::waitForOpened(int msecs)
337{
338 if (!d)
339 return false;
340
341 if (d->isOpen)
342 return true;
343
344 if (!(d->state == Connecting || d->state == Connected)) {
345 return false;
346 }
347
348 QEventLoop loop;
349 QObject::connect(sender: d, SIGNAL(quitPendingWaitsForOpened()), receiver: &loop, SLOT(quit()));
350 QObject::connect(sender: this, SIGNAL(error(QNetworkSession::SessionError)), receiver: &loop, SLOT(quit()));
351
352 //final call
353 if (msecs >= 0)
354 QTimer::singleShot(msec: msecs, receiver: &loop, SLOT(quit()));
355
356 // enter the event loop and wait for opened/error/timeout
357 loop.exec(flags: QEventLoop::ExcludeUserInputEvents | QEventLoop::WaitForMoreEvents);
358
359 return d->isOpen;
360}
361
362/*!
363 Decreases the session counter on the associated network configuration. If the session counter reaches zero
364 the active network interface is shut down. This also means that state() will only change from \l Connected to
365 \l Disconnected if the current session was the last open session.
366
367 If the platform does not support out-of-process sessions calling this function does not stop the
368 interface. In this case \l{stop()} has to be used to force a shut down.
369 The platform capabilities can be detected via QNetworkConfigurationManager::capabilities().
370
371 Note that this call is asynchronous. Depending on the outcome of this call the results can be enquired
372 by connecting to the stateChanged(), opened() or error() signals.
373
374 \sa open(), stop(), isOpen()
375*/
376void QNetworkSession::close()
377{
378 if (d)
379 d->close();
380}
381
382/*!
383 Invalidates all open sessions against the network interface and therefore stops the
384 underlying network interface. This function always changes the session's state() flag to
385 \l Disconnected.
386
387 \sa open(), close()
388*/
389void QNetworkSession::stop()
390{
391 if (d)
392 d->stop();
393}
394
395/*!
396 Returns the QNetworkConfiguration that this network session object is based on.
397
398 \sa QNetworkConfiguration
399*/
400QNetworkConfiguration QNetworkSession::configuration() const
401{
402 return d ? d->publicConfig : QNetworkConfiguration();
403}
404
405#ifndef QT_NO_NETWORKINTERFACE
406/*!
407 Returns the network interface that is used by this session.
408
409 This function only returns a valid QNetworkInterface when this session is \l Connected.
410
411 The returned interface may change as a result of a roaming process.
412
413 \sa state()
414*/
415QNetworkInterface QNetworkSession::interface() const
416{
417 return d ? d->currentInterface() : QNetworkInterface();
418}
419#endif
420
421/*!
422 Returns \c true if this session is open. If the number of all open sessions is greater than
423 zero the underlying network interface will remain connected/up.
424
425 The session can be controlled via open() and close().
426*/
427bool QNetworkSession::isOpen() const
428{
429 return d ? d->isOpen : false;
430}
431
432/*!
433 Returns the state of the session.
434
435 If the session is based on a single access point configuration the state of the
436 session is the same as the state of the associated network interface. Therefore
437 a network session object can be used to monitor network interfaces.
438
439 A \l QNetworkConfiguration::ServiceNetwork based session summarizes the state of all its children
440 and therefore returns the \l Connected state if at least one of the service network's
441 \l {QNetworkConfiguration::children()}{children()} configurations is active.
442
443 Note that it is not required to hold an open session in order to obtain the network interface state.
444 A connected but closed session may be used to monitor network interfaces whereas an open and connected
445 session object may prevent the network interface from being shut down.
446
447 \sa error(), stateChanged()
448*/
449QNetworkSession::State QNetworkSession::state() const
450{
451 return d ? d->state : QNetworkSession::Invalid;
452}
453
454/*!
455 Returns the type of error that last occurred.
456
457 \sa state(), errorString()
458*/
459QNetworkSession::SessionError QNetworkSession::error() const
460{
461 return d ? d->error() : InvalidConfigurationError;
462}
463
464/*!
465 Returns a human-readable description of the last device error that
466 occurred.
467
468 \sa error()
469*/
470QString QNetworkSession::errorString() const
471{
472 return d ? d->errorString() : tr(s: "Invalid configuration.");
473}
474
475/*!
476 Returns the value for property \a key.
477
478 A network session can have properties attached which may describe the session in more details.
479 This function can be used to gain access to those properties.
480
481 The following property keys are guaranteed to be specified on all platforms:
482
483 \table 80%
484 \header
485 \li Key \li Description
486 \row
487 \li ActiveConfiguration
488 \li If the session \l isOpen() this property returns the identifier of the
489 QNetworkConfiguration that is used by this session; otherwise an empty string.
490
491 The main purpose of this key is to determine which Internet access point is used
492 if the session is based on a \l{QNetworkConfiguration::ServiceNetwork}{ServiceNetwork}.
493 The following code snippet highlights the difference:
494 \snippet code/src_network_bearer_qnetworksession.cpp 1
495 \row
496 \li UserChoiceConfiguration
497 \li If the session \l isOpen() and is bound to a QNetworkConfiguration of type
498 UserChoice, this property returns the identifier of the QNetworkConfiguration that the
499 configuration resolved to when \l open() was called; otherwise an empty string.
500
501 The purpose of this key is to determine the real QNetworkConfiguration that the
502 session is using. This key is different from \e ActiveConfiguration in that
503 this key may return an identifier for either a
504 \l {QNetworkConfiguration::ServiceNetwork}{service network} or a
505 \l {QNetworkConfiguration::InternetAccessPoint}{Internet access points} configurations,
506 whereas \e ActiveConfiguration always returns identifiers to
507 \l {QNetworkConfiguration::InternetAccessPoint}{Internet access points} configurations.
508 \row
509 \li ConnectInBackground
510 \li Setting this property to \e true before calling \l open() implies that the connection attempt
511 is made but if no connection can be established, the user is not connsulted and asked to select
512 a suitable connection. This property is not set by default and support for it depends on the platform.
513
514 \row
515 \li AutoCloseSessionTimeout
516 \li If the session requires polling to keep its state up to date, this property holds
517 the timeout in milliseconds before the session will automatically close. If the
518 value of this property is -1 the session will not automatically close. This property
519 is set to -1 by default.
520
521 The purpose of this property is to minimize resource use on platforms that use
522 polling to update the state of the session. Applications can set the value of this
523 property to the desired timeout before the session is closed. In response to the
524 closed() signal the network session should be deleted to ensure that all polling is
525 stopped. The session can then be recreated once it is required again. This property
526 has no effect for sessions that do not require polling.
527 \endtable
528*/
529QVariant QNetworkSession::sessionProperty(const QString &key) const
530{
531 if (!d || !d->publicConfig.isValid())
532 return QVariant();
533
534 if (key == QLatin1String("ActiveConfiguration"))
535 return d->isOpen ? d->activeConfig.identifier() : QString();
536
537 if (key == QLatin1String("UserChoiceConfiguration")) {
538 if (!d->isOpen || d->publicConfig.type() != QNetworkConfiguration::UserChoice)
539 return QString();
540
541 if (d->serviceConfig.isValid())
542 return d->serviceConfig.identifier();
543 else
544 return d->activeConfig.identifier();
545 }
546
547 return d->sessionProperty(key);
548}
549
550/*!
551 Sets the property \a value on the session. The property is identified using
552 \a key. Removing an already set property can be achieved by passing an
553 invalid QVariant.
554
555 Note that the \e UserChoiceConfiguration and \e ActiveConfiguration
556 properties are read only and cannot be changed using this method.
557*/
558void QNetworkSession::setSessionProperty(const QString &key, const QVariant &value)
559{
560 if (!d)
561 return;
562
563 if (key == QLatin1String("ActiveConfiguration") ||
564 key == QLatin1String("UserChoiceConfiguration")) {
565 return;
566 }
567
568 d->setSessionProperty(key, value);
569}
570
571/*!
572 Instructs the session to roam to the new access point. The old access point remains active
573 until the application calls accept().
574
575 The newConfigurationActivated() signal is emitted once roaming has been completed.
576
577 \sa accept()
578*/
579void QNetworkSession::migrate()
580{
581 if (d)
582 d->migrate();
583}
584
585/*!
586 This function indicates that the application does not wish to roam the session.
587
588 \sa migrate()
589*/
590void QNetworkSession::ignore()
591{
592 if (d)
593 d->ignore();
594}
595
596/*!
597 Instructs the session to permanently accept the new access point. Once this function
598 has been called the session may not return to the old access point.
599
600 The old access point may be closed in the process if there are no other network sessions for it.
601 Therefore any open socket that still uses the old access point
602 may become unusable and should be closed before completing the migration.
603*/
604void QNetworkSession::accept()
605{
606 if (d)
607 d->accept();
608}
609
610/*!
611 The new access point is not suitable for the application. By calling this function the
612 session returns to the previous access point/configuration. This action may invalidate
613 any socket that has been created via the not desired access point.
614
615 \sa accept()
616*/
617void QNetworkSession::reject()
618{
619 if (d)
620 d->reject();
621}
622
623
624/*!
625 Returns the amount of data sent in bytes; otherwise 0.
626
627 This field value includes the usage across all open network
628 sessions which use the same network interface.
629
630 If the session is based on a service network configuration the number of
631 sent bytes across all active member configurations are returned.
632
633 This function may not always be supported on all platforms and returns 0.
634 The platform capability can be detected via QNetworkConfigurationManager::DataStatistics.
635
636 \note On some platforms this function may run the main event loop.
637*/
638quint64 QNetworkSession::bytesWritten() const
639{
640 return d ? d->bytesWritten() : Q_UINT64_C(0);
641}
642
643/*!
644 Returns the amount of data received in bytes; otherwise 0.
645
646 This field value includes the usage across all open network
647 sessions which use the same network interface.
648
649 If the session is based on a service network configuration the number of
650 sent bytes across all active member configurations are returned.
651
652 This function may not always be supported on all platforms and returns 0.
653 The platform capability can be detected via QNetworkConfigurationManager::DataStatistics.
654
655 \note On some platforms this function may run the main event loop.
656*/
657quint64 QNetworkSession::bytesReceived() const
658{
659 return d ? d->bytesReceived() : Q_UINT64_C(0);
660}
661
662/*!
663 Returns the number of seconds that the session has been active.
664*/
665quint64 QNetworkSession::activeTime() const
666{
667 return d ? d->activeTime() : Q_UINT64_C(0);
668}
669
670/*!
671 Returns the network usage policies currently in force by the system.
672*/
673QNetworkSession::UsagePolicies QNetworkSession::usagePolicies() const
674{
675 return d ? d->usagePolicies() : QNetworkSession::NoPolicy;
676}
677
678/*!
679 \internal
680 Change usage policies for unit testing.
681 In normal use, the policies are published by the bearer plugin
682*/
683void QNetworkSessionPrivate::setUsagePolicies(QNetworkSession &session, QNetworkSession::UsagePolicies policies)
684{
685 if (!session.d)
686 return;
687 session.d->setUsagePolicies(policies);
688}
689
690/*!
691 \internal
692
693 This function is required to detect whether the client wants to control
694 the roaming process. If he connects to preferredConfigurationChanged() signal
695 he intends to influence it. Otherwise QNetworkSession always roams
696 without registering this session as a stakeholder in the roaming process.
697
698 For more details check the Forced vs ALR roaming section in the QNetworkSession
699 class description.
700*/
701void QNetworkSession::connectNotify(const QMetaMethod &signal)
702{
703 QObject::connectNotify(signal);
704
705 if (!d)
706 return;
707
708 //check for preferredConfigurationChanged() signal connect notification
709 //This is not required on all platforms
710 static const QMetaMethod preferredConfigurationChangedSignal =
711 QMetaMethod::fromSignal(signal: &QNetworkSession::preferredConfigurationChanged);
712 if (signal == preferredConfigurationChangedSignal)
713 d->setALREnabled(true);
714}
715
716/*!
717 \internal
718
719 This function is called when the client disconnects from the
720 preferredConfigurationChanged() signal.
721
722 \sa connectNotify()
723*/
724void QNetworkSession::disconnectNotify(const QMetaMethod &signal)
725{
726 QObject::disconnectNotify(signal);
727
728 if (!d)
729 return;
730
731 //check for preferredConfigurationChanged() signal disconnect notification
732 //This is not required on all platforms
733 static const QMetaMethod preferredConfigurationChangedSignal =
734 QMetaMethod::fromSignal(signal: &QNetworkSession::preferredConfigurationChanged);
735 if (signal == preferredConfigurationChangedSignal)
736 d->setALREnabled(false);
737}
738
739QT_END_NAMESPACE
740
741#include "moc_qnetworksession.cpp"
742
743#endif // QT_NO_BEARERMANAGEMENT
744

source code of qtbase/src/network/bearer/qnetworksession.cpp