author | Jeremias Bosch <jeremias.bosch@gmail.com> |
Fri, 08 Apr 2011 11:51:32 -0700 | |
changeset 67672 | 4f957dd3f9f79e175d7cb78faaf59a4e74fc10bd |
parent 67671 | 0f077c086750bdf13fadb05f1efd08a0d18cbdcf |
child 67673 | 272a7b90280dd5771684342f73f6c6e23893f90d |
child 67705 | 877127eae177507f65bc689347f26e28789524bb |
push id | 19409 |
push user | romaxa@gmail.com |
push date | Fri, 08 Apr 2011 18:58:35 +0000 |
treeherder | mozilla-central@4f957dd3f9f7 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | romaxa |
bugs | 646396 |
milestone | 2.2a1pre |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/netwerk/base/src/Makefile.in +++ b/netwerk/base/src/Makefile.in @@ -117,16 +117,17 @@ ifdef MOZ_PLATFORM_MAEMO CPPSRCS += nsNativeConnectionHelper.cpp ifdef MOZ_ENABLE_LIBCONIC CPPSRCS += nsAutodialMaemo.cpp LOCAL_INCLUDES += -I$(srcdir)/../../system/maemo endif ifdef MOZ_ENABLE_QTNETWORK CPPSRCS += nsAutodialQt.cpp LOCAL_INCLUDES += -I$(srcdir)/../../system/qt + OS_INCLUDES += $(MOZ_QT_CFLAGS) endif endif EXTRA_COMPONENTS = \ $(srcdir)/nsProxyAutoConfig.js \ $(srcdir)/nsProxyAutoConfig.manifest \ $(NULL)
--- a/netwerk/base/src/nsAutodialQt.cpp +++ b/netwerk/base/src/nsAutodialQt.cpp @@ -30,23 +30,23 @@ * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ +#include "nsQtNetworkManager.h" #include "nsAutodialQt.h" #include "nsNetCID.h" #include "nsCOMPtr.h" #include "nsIPrefBranch.h" #include "nsIPrefService.h" #include "nsIServiceManager.h" -#include "nsQtNetworkManager.h" nsAutodial::nsAutodial() { } nsAutodial::~nsAutodial() { @@ -56,22 +56,24 @@ nsresult nsAutodial::Init() { return NS_OK; } nsresult nsAutodial::DialDefault(const PRUnichar* hostName) { - if (nsQtNetworkManager::OpenConnectionSync()) + if (gQtNetworkManager->openConnection(QString::fromUtf16(hostName))) { return NS_OK; + } return NS_ERROR_FAILURE; } PRBool nsAutodial::ShouldDialOnNetworkError() { - if (nsQtNetworkManager::IsConnected()) + if (gQtNetworkManager->isOnline()) { return PR_FALSE; + } return PR_TRUE; }
--- a/netwerk/system/qt/Makefile.in +++ b/netwerk/system/qt/Makefile.in @@ -43,20 +43,24 @@ VPATH = @srcdir@ include $(DEPTH)/config/autoconf.mk MODULE = necko LIBRARY_NAME = neckosystem_s LIBXUL_LIBRARY = 1 FORCE_STATIC_LIB = 1 +MOCSRCS = \ + moc_nsQtNetworkManager.cpp \ + $(NULL) CPPSRCS += \ + $(MOCSRCS) \ nsQtNetworkLinkService.cpp \ nsQtNetworkManager.cpp \ $(NULL) include $(topsrcdir)/config/rules.mk DEFINES += -DIMPL_NS_NET -OS_INCLUDES += $(GLIB_CFLAGS) $(MOZ_QT_CFLAGS) +OS_INCLUDES += $(MOZ_QT_CFLAGS) LOCAL_INCLUDES += -I$(srcdir)/../../base/src
--- a/netwerk/system/qt/nsQtNetworkLinkService.cpp +++ b/netwerk/system/qt/nsQtNetworkLinkService.cpp @@ -30,77 +30,93 @@ * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ +#include "nsQtNetworkManager.h" #include "nsQtNetworkLinkService.h" #include "nsCOMPtr.h" #include "nsIObserverService.h" #include "nsServiceManagerUtils.h" #include "nsString.h" -#include "nsQtNetworkManager.h" #include "mozilla/Services.h" NS_IMPL_ISUPPORTS2(nsQtNetworkLinkService, nsINetworkLinkService, nsIObserver) nsQtNetworkLinkService::nsQtNetworkLinkService() { } nsQtNetworkLinkService::~nsQtNetworkLinkService() { } NS_IMETHODIMP -nsQtNetworkLinkService::GetIsLinkUp(PRBool *aIsUp) +nsQtNetworkLinkService::GetIsLinkUp(PRBool* aIsUp) { - *aIsUp = nsQtNetworkManager::IsConnected(); + *aIsUp = gQtNetworkManager->isOnline(); return NS_OK; } NS_IMETHODIMP -nsQtNetworkLinkService::GetLinkStatusKnown(PRBool *aIsKnown) +nsQtNetworkLinkService::GetLinkStatusKnown(PRBool* aIsKnown) { - *aIsKnown = nsQtNetworkManager::GetLinkStatusKnown(); + *aIsKnown = gQtNetworkManager->isOnline(); return NS_OK; } NS_IMETHODIMP nsQtNetworkLinkService::Observe(nsISupports* aSubject, const char* aTopic, const PRUnichar* aData) { - if (!strcmp(aTopic, "xpcom-shutdown")) + if (!strcmp(aTopic, "xpcom-shutdown")) { Shutdown(); + delete gQtNetworkManager; + gQtNetworkManager = 0; + } + + if (!strcmp(aTopic, "browser-lastwindow-close-granted")) { + Shutdown(); + } return NS_OK; } nsresult nsQtNetworkLinkService::Init(void) { nsCOMPtr<nsIObserverService> observerService = mozilla::services::GetObserverService(); - if (!observerService) + if (!observerService) { return NS_ERROR_FAILURE; + } + + delete gQtNetworkManager; + gQtNetworkManager = new nsQtNetworkManager(); + nsresult rv; - nsresult rv = observerService->AddObserver(this, "xpcom-shutdown", PR_FALSE); - if (NS_FAILED(rv)) + rv = observerService->AddObserver(this, "xpcom-shutdown", PR_FALSE); + if (NS_FAILED(rv)) { return NS_ERROR_FAILURE; + } - if (!nsQtNetworkManager::Startup()) + rv = observerService->AddObserver(this, "browser-lastwindow-close-granted", PR_FALSE); + if (NS_FAILED(rv)) { return NS_ERROR_FAILURE; + } + return NS_OK; } nsresult nsQtNetworkLinkService::Shutdown() { - nsQtNetworkManager::Shutdown(); + gQtNetworkManager->closeSession(); return NS_OK; }
--- a/netwerk/system/qt/nsQtNetworkManager.cpp +++ b/netwerk/system/qt/nsQtNetworkManager.cpp @@ -30,108 +30,145 @@ * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ -//order is important - mozilla redefine qt macros -#include <QNetworkConfigurationManager> -#include <QNetworkConfiguration> -#include <QNetworkSession> - #include "nsQtNetworkManager.h" #include "nsCOMPtr.h" #include "nsThreadUtils.h" - #include "nsINetworkLinkService.h" - #include "nsIOService.h" #include "nsIObserverService.h" #include "nsIOService.h" -#include "nsINetworkLinkService.h" +#include <QHostInfo> +#include <QHostAddress> +#include <QTime> -static QNetworkConfigurationManager* sNetworkConfig = 0; +nsQtNetworkManager::nsQtNetworkManager(QObject* parent) + : QObject(parent), networkSession(0) +{ + mOnline = networkConfigurationManager.isOnline(); + NS_ASSERTION(NS_IsMainThread(), "nsQtNetworkManager can only initiated in Main Thread"); +} + +nsQtNetworkManager::~nsQtNetworkManager() +{ + closeSession(); + networkSession->deleteLater(); +} PRBool -nsQtNetworkManager::OpenConnectionSync() +nsQtNetworkManager::isOnline() { - if (!sNetworkConfig) - return PR_FALSE; - - //do not request when we are online... - if (sNetworkConfig->isOnline()) - return PR_FALSE; - - if (!(sNetworkConfig->capabilities() & QNetworkConfigurationManager::CanStartAndStopInterfaces)) - return PR_FALSE; - - // Is there default access point, use it - QNetworkConfiguration default_cfg = sNetworkConfig->defaultConfiguration(); - - if (!default_cfg.isValid()) - { - NS_WARNING("default configuration is not valid. Looking for any other:"); - foreach (QNetworkConfiguration cfg, sNetworkConfig->allConfigurations()) - { - if (cfg.isValid()) - default_cfg = cfg; - } - - if (!default_cfg.isValid()) - { - NS_WARNING("No valid configuration found. Giving up."); - return PR_FALSE; - } - } - - //do use pointer here, it will be deleted after connected! - //Creation on stack cause appearing issues and segfaults of the connectivity dialog - QNetworkSession* session = new QNetworkSession(default_cfg); - QObject::connect(session, SIGNAL(opened()), - session, SLOT(deleteLater())); - QObject::connect(session, SIGNAL(error(QNetworkSession::SessionError)), - session, SLOT(deleteLater())); - session->open(); - return session->waitForOpened(-1); + static PRBool sForceOnlineUSB = getenv("MOZ_MEEGO_NET_ONLINE") != 0; + return sForceOnlineUSB || mOnline; } void -nsQtNetworkManager::CloseConnection() +nsQtNetworkManager::onlineStateChanged(bool online) { - NS_WARNING("nsQtNetworkManager::CloseConnection() Not implemented by QtNetwork."); + mOnline = online; } -PRBool -nsQtNetworkManager::IsConnected() -{ - NS_ASSERTION(sNetworkConfig, "Network not initialized"); - return sNetworkConfig->isOnline(); -} +/* + This function is called from different threads, we need to make sure that + the attempt to create a network connection is done in the mainthread + + In case this function is called by another thread than the mainthread + we emit a signal which is connected through "BlockingQueue"-Connection Type. + + This cause that the current thread is blocked and waiting for the result. + + Of course, in case this gets called from the mainthread we must not emit the signal, + but call the slot directly. +*/ PRBool -nsQtNetworkManager::GetLinkStatusKnown() -{ - return IsConnected(); -} - -PRBool -nsQtNetworkManager::Startup() +nsQtNetworkManager::openConnection(const QString& host) { - //Dont do it if already there - if (sNetworkConfig) - return PR_FALSE; + // we are already online -> return true. + if (isOnline()) { + return true; + } - sNetworkConfig = new QNetworkConfigurationManager(); + if (NS_IsMainThread()) { + openSession(); + } else { + // jump to mainthread and do the work there + emit openConnectionSignal(); + } - return PR_TRUE; + // if its claiming its online -> send one resolve request ahead. + // this is important because on mobile the first request can take up to 10 seconds + // sending here one will help to avoid trouble and timeouts later + if (isOnline()) { + QHostInfo::fromName(host); + } + + return isOnline(); } void -nsQtNetworkManager::Shutdown() +nsQtNetworkManager::openSession() { - delete sNetworkConfig; - sNetworkConfig = nsnull; + if (mBlockTimer.isActive()) { + // if openSession is called within 200 ms again, we forget this attempt since + // its mostlike an automatic connection attempt which was not successful or canceled 200ms ago. + // we reset the timer and start it again. + + // As example: Go in firefox mobile into AwesomeView, see that the icons are not always cached and + // get loaded on the fly. Not having the 200 ms rule here would mean that instantly + // after the user dismissed the one connection dialog once another + // would get opened. The user will never be able to close / leave the view until each such attempt is gone through. + + // Basically 200 ms are working fine, its huge enough for automatic attempts to get covered and small enough to + // still be able to react on direct user request. + + mBlockTimer.stop(); + mBlockTimer.setSingleShot(true); + mBlockTimer.start(200); + return; + } + + if (isOnline()) { + return; + } + + // this only means we did not shutdown before... + // renew Session every time + // fix/workaround for prestart bug + if (!networkSession) { + networkSession->close(); + networkSession->deleteLater(); + } + + // renew always to react on changed Configurations + networkConfigurationManager.updateConfigurations(); + // go always with default configuration + networkConfiguration = networkConfigurationManager.defaultConfiguration(); + networkSession = new QNetworkSession(networkConfiguration); + + networkSession->open(); + QTime current; + current.start(); + networkSession->waitForOpened(-1); + + if (current.elapsed() < 1000) { + NS_WARNING("Connection Creation was to fast, something is not right."); + } + + mBlockTimer.setSingleShot(true); + mBlockTimer.start(200); } + +void +nsQtNetworkManager::closeSession() +{ + if (!networkSession) { + networkSession->close(); + } +}
--- a/netwerk/system/qt/nsQtNetworkManager.h +++ b/netwerk/system/qt/nsQtNetworkManager.h @@ -33,26 +33,52 @@ * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ #ifndef NSQTNETWORKMANAGER_H_ #define NSQTNETWORKMANAGER_H_ +#include <QNetworkConfigurationManager> +#include <QObject> +#include <QTimer> +#include <QNetworkConfiguration> +#include <QNetworkSession> #include "nscore.h" -class nsQtNetworkManager +class nsQtNetworkManager; + +static nsQtNetworkManager* gQtNetworkManager = nsnull; + +class nsQtNetworkManager : public QObject { -public: - // Can be called from any thread, most likely the socket transport thread - static PRBool OpenConnectionSync(); - static void CloseConnection(); + Q_OBJECT + public: + explicit nsQtNetworkManager(QObject* parent = 0); + + virtual ~nsQtNetworkManager(); - static PRBool IsConnected(); - static PRBool GetLinkStatusKnown(); + static PRBool IsConnected(); + static PRBool GetLinkStatusKnown(); + static void enableInstance(); + PRBool openConnection(const QString&); + PRBool isOnline(); + signals: + void openConnectionSignal(); - // Called from the nsQtNetworkLinkService (main thread only) - static PRBool Startup(); - static void Shutdown(); + public slots: + void closeSession(); + void onlineStateChanged(bool); + + private slots: + void openSession(); + + private: + QNetworkSession* networkSession; + QNetworkConfiguration networkConfiguration; + QNetworkConfigurationManager networkConfigurationManager; + QTimer mBlockTimer; + bool mOnline; }; #endif /* NSQTNETWORKMANAGER_H_ */ +