netwerk/system/qt/nsQtNetworkManager.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 #include "nsQtNetworkManager.h"
     7 #include "nsCOMPtr.h"
     8 #include "nsThreadUtils.h"
     9 #include "nsINetworkLinkService.h"
    10 #include "nsIOService.h"
    11 #include "nsIObserverService.h"
    12 #include "nsIOService.h"
    14 #include <QHostInfo>
    15 #include <QHostAddress>
    16 #include <QTime>
    18 nsQtNetworkManager* nsQtNetworkManager::gQtNetworkManager = nullptr;
    20 void nsQtNetworkManager::create()
    21 {
    22     if (!gQtNetworkManager) {
    23         gQtNetworkManager = new nsQtNetworkManager();
    24         connect(gQtNetworkManager, SIGNAL(openConnectionSignal()),
    25                 gQtNetworkManager, SLOT(openSession()),
    26                 Qt::BlockingQueuedConnection);
    27         connect(&gQtNetworkManager->networkConfigurationManager,
    28                 SIGNAL(onlineStateChanged(bool)), gQtNetworkManager,
    29                 SLOT(onlineStateChanged(bool)));
    30     }
    31 }
    33 void nsQtNetworkManager::destroy()
    34 {
    35     delete gQtNetworkManager;
    36     gQtNetworkManager = nullptr;
    37 }
    39 nsQtNetworkManager::nsQtNetworkManager(QObject* parent)
    40   : QObject(parent), networkSession(0)
    41 {
    42     mOnline = networkConfigurationManager.isOnline();
    43     NS_ASSERTION(NS_IsMainThread(), "nsQtNetworkManager can only initiated in Main Thread");
    44 }
    46 nsQtNetworkManager::~nsQtNetworkManager()
    47 {
    48     closeSession();
    49     networkSession->deleteLater();
    50 }
    52 bool
    53 nsQtNetworkManager::isOnline()
    54 {
    55     static bool sForceOnlineUSB = getenv("MOZ_MEEGO_NET_ONLINE") != 0;
    56     return sForceOnlineUSB || mOnline;
    57 }
    59 void
    60 nsQtNetworkManager::onlineStateChanged(bool online)
    61 {
    62     mOnline = online;
    63 }
    65 /*
    66   This function is called from different threads, we need to make sure that
    67   the attempt to create a network connection is done in the mainthread
    69   In case this function is called by another thread than the mainthread
    70   we emit a signal which is connected through "BlockingQueue"-Connection Type.
    72   This cause that the current thread is blocked and waiting for the result.
    74   Of course, in case this gets called from the mainthread we must not emit the signal,
    75   but call the slot directly.
    76 */
    78 bool
    79 nsQtNetworkManager::openConnection(const QString& host)
    80 {
    81     // we are already online -> return true.
    82     if (isOnline()) {
    83         return true;
    84     }
    86     if (NS_IsMainThread()) {
    87         openSession();
    88     } else {
    89         // jump to mainthread and do the work there
    90         Q_EMIT openConnectionSignal();
    91     }
    93     // if its claiming its online -> send one resolve request ahead.
    94     // this is important because on mobile the first request can take up to 10 seconds
    95     // sending here one will help to avoid trouble and timeouts later
    96     if (isOnline()) {
    97         QHostInfo::fromName(host);
    98     }
   100     return isOnline();
   101 }
   103 void
   104 nsQtNetworkManager::openSession()
   105 {
   106     if (mBlockTimer.isActive()) {
   107         // if openSession is called within 200 ms again, we forget this attempt since
   108         // its mostlike an automatic connection attempt which was not successful or canceled 200ms ago.
   109         // we reset the timer and start it again.
   111         // As example: Go in firefox mobile into AwesomeView, see that the icons are not always cached and
   112         // get loaded on the fly. Not having the 200 ms rule here would mean that instantly
   113         // after the user dismissed the one connection dialog once another
   114         // would get opened. The user will never be able to close / leave the view until each such attempt is gone through.
   116         // Basically 200 ms are working fine, its huge enough for automatic attempts to get covered and small enough to
   117         // still be able to react on direct user request.
   119         mBlockTimer.stop();
   120         mBlockTimer.setSingleShot(true);
   121         mBlockTimer.start(200);
   122         return;
   123     }
   125     if (isOnline()) {
   126         return;
   127     }
   129     // this only means we did not shutdown before...
   130     // renew Session every time
   131     // fix/workaround for prestart bug
   132     if (networkSession) {
   133         networkSession->close();
   134         networkSession->deleteLater();
   135     }
   137     // renew always to react on changed Configurations
   138     networkConfigurationManager.updateConfigurations();
   139     // go always with default configuration
   140     networkConfiguration = networkConfigurationManager.defaultConfiguration();
   141     networkSession = new QNetworkSession(networkConfiguration);
   143     networkSession->open();
   144     QTime current;
   145     current.start();
   146     networkSession->waitForOpened(-1);
   148     if (current.elapsed() < 1000) {
   149         NS_WARNING("Connection Creation was to fast, something is not right.");
   150     }
   152     mBlockTimer.setSingleShot(true);
   153     mBlockTimer.start(200);
   154 }
   156 void
   157 nsQtNetworkManager::closeSession()
   158 {
   159     if (networkSession) {
   160         networkSession->close();
   161     }
   162 }

mercurial