1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/netwerk/system/qt/nsQtNetworkManager.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,162 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +#include "nsQtNetworkManager.h" 1.9 + 1.10 +#include "nsCOMPtr.h" 1.11 +#include "nsThreadUtils.h" 1.12 +#include "nsINetworkLinkService.h" 1.13 +#include "nsIOService.h" 1.14 +#include "nsIObserverService.h" 1.15 +#include "nsIOService.h" 1.16 + 1.17 +#include <QHostInfo> 1.18 +#include <QHostAddress> 1.19 +#include <QTime> 1.20 + 1.21 +nsQtNetworkManager* nsQtNetworkManager::gQtNetworkManager = nullptr; 1.22 + 1.23 +void nsQtNetworkManager::create() 1.24 +{ 1.25 + if (!gQtNetworkManager) { 1.26 + gQtNetworkManager = new nsQtNetworkManager(); 1.27 + connect(gQtNetworkManager, SIGNAL(openConnectionSignal()), 1.28 + gQtNetworkManager, SLOT(openSession()), 1.29 + Qt::BlockingQueuedConnection); 1.30 + connect(&gQtNetworkManager->networkConfigurationManager, 1.31 + SIGNAL(onlineStateChanged(bool)), gQtNetworkManager, 1.32 + SLOT(onlineStateChanged(bool))); 1.33 + } 1.34 +} 1.35 + 1.36 +void nsQtNetworkManager::destroy() 1.37 +{ 1.38 + delete gQtNetworkManager; 1.39 + gQtNetworkManager = nullptr; 1.40 +} 1.41 + 1.42 +nsQtNetworkManager::nsQtNetworkManager(QObject* parent) 1.43 + : QObject(parent), networkSession(0) 1.44 +{ 1.45 + mOnline = networkConfigurationManager.isOnline(); 1.46 + NS_ASSERTION(NS_IsMainThread(), "nsQtNetworkManager can only initiated in Main Thread"); 1.47 +} 1.48 + 1.49 +nsQtNetworkManager::~nsQtNetworkManager() 1.50 +{ 1.51 + closeSession(); 1.52 + networkSession->deleteLater(); 1.53 +} 1.54 + 1.55 +bool 1.56 +nsQtNetworkManager::isOnline() 1.57 +{ 1.58 + static bool sForceOnlineUSB = getenv("MOZ_MEEGO_NET_ONLINE") != 0; 1.59 + return sForceOnlineUSB || mOnline; 1.60 +} 1.61 + 1.62 +void 1.63 +nsQtNetworkManager::onlineStateChanged(bool online) 1.64 +{ 1.65 + mOnline = online; 1.66 +} 1.67 + 1.68 +/* 1.69 + This function is called from different threads, we need to make sure that 1.70 + the attempt to create a network connection is done in the mainthread 1.71 + 1.72 + In case this function is called by another thread than the mainthread 1.73 + we emit a signal which is connected through "BlockingQueue"-Connection Type. 1.74 + 1.75 + This cause that the current thread is blocked and waiting for the result. 1.76 + 1.77 + Of course, in case this gets called from the mainthread we must not emit the signal, 1.78 + but call the slot directly. 1.79 +*/ 1.80 + 1.81 +bool 1.82 +nsQtNetworkManager::openConnection(const QString& host) 1.83 +{ 1.84 + // we are already online -> return true. 1.85 + if (isOnline()) { 1.86 + return true; 1.87 + } 1.88 + 1.89 + if (NS_IsMainThread()) { 1.90 + openSession(); 1.91 + } else { 1.92 + // jump to mainthread and do the work there 1.93 + Q_EMIT openConnectionSignal(); 1.94 + } 1.95 + 1.96 + // if its claiming its online -> send one resolve request ahead. 1.97 + // this is important because on mobile the first request can take up to 10 seconds 1.98 + // sending here one will help to avoid trouble and timeouts later 1.99 + if (isOnline()) { 1.100 + QHostInfo::fromName(host); 1.101 + } 1.102 + 1.103 + return isOnline(); 1.104 +} 1.105 + 1.106 +void 1.107 +nsQtNetworkManager::openSession() 1.108 +{ 1.109 + if (mBlockTimer.isActive()) { 1.110 + // if openSession is called within 200 ms again, we forget this attempt since 1.111 + // its mostlike an automatic connection attempt which was not successful or canceled 200ms ago. 1.112 + // we reset the timer and start it again. 1.113 + 1.114 + // As example: Go in firefox mobile into AwesomeView, see that the icons are not always cached and 1.115 + // get loaded on the fly. Not having the 200 ms rule here would mean that instantly 1.116 + // after the user dismissed the one connection dialog once another 1.117 + // would get opened. The user will never be able to close / leave the view until each such attempt is gone through. 1.118 + 1.119 + // Basically 200 ms are working fine, its huge enough for automatic attempts to get covered and small enough to 1.120 + // still be able to react on direct user request. 1.121 + 1.122 + mBlockTimer.stop(); 1.123 + mBlockTimer.setSingleShot(true); 1.124 + mBlockTimer.start(200); 1.125 + return; 1.126 + } 1.127 + 1.128 + if (isOnline()) { 1.129 + return; 1.130 + } 1.131 + 1.132 + // this only means we did not shutdown before... 1.133 + // renew Session every time 1.134 + // fix/workaround for prestart bug 1.135 + if (networkSession) { 1.136 + networkSession->close(); 1.137 + networkSession->deleteLater(); 1.138 + } 1.139 + 1.140 + // renew always to react on changed Configurations 1.141 + networkConfigurationManager.updateConfigurations(); 1.142 + // go always with default configuration 1.143 + networkConfiguration = networkConfigurationManager.defaultConfiguration(); 1.144 + networkSession = new QNetworkSession(networkConfiguration); 1.145 + 1.146 + networkSession->open(); 1.147 + QTime current; 1.148 + current.start(); 1.149 + networkSession->waitForOpened(-1); 1.150 + 1.151 + if (current.elapsed() < 1000) { 1.152 + NS_WARNING("Connection Creation was to fast, something is not right."); 1.153 + } 1.154 + 1.155 + mBlockTimer.setSingleShot(true); 1.156 + mBlockTimer.start(200); 1.157 +} 1.158 + 1.159 +void 1.160 +nsQtNetworkManager::closeSession() 1.161 +{ 1.162 + if (networkSession) { 1.163 + networkSession->close(); 1.164 + } 1.165 +}