зеркало из https://github.com/mozilla/gecko-dev.git
163 строки
4.7 KiB
C++
163 строки
4.7 KiB
C++
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#include "nsQtNetworkManager.h"
|
|
|
|
#include "nsCOMPtr.h"
|
|
#include "nsThreadUtils.h"
|
|
#include "nsINetworkLinkService.h"
|
|
#include "nsIOService.h"
|
|
#include "nsIObserverService.h"
|
|
#include "nsIOService.h"
|
|
|
|
#include <QHostInfo>
|
|
#include <QHostAddress>
|
|
#include <QTime>
|
|
|
|
nsQtNetworkManager* nsQtNetworkManager::gQtNetworkManager = nsnull;
|
|
|
|
void nsQtNetworkManager::create()
|
|
{
|
|
if (!gQtNetworkManager) {
|
|
gQtNetworkManager = new nsQtNetworkManager();
|
|
connect(gQtNetworkManager, SIGNAL(openConnectionSignal()),
|
|
gQtNetworkManager, SLOT(openSession()),
|
|
Qt::BlockingQueuedConnection);
|
|
connect(&gQtNetworkManager->networkConfigurationManager,
|
|
SIGNAL(onlineStateChanged(bool)), gQtNetworkManager,
|
|
SLOT(onlineStateChanged(bool)));
|
|
}
|
|
}
|
|
|
|
void nsQtNetworkManager::destroy()
|
|
{
|
|
delete gQtNetworkManager;
|
|
gQtNetworkManager = nsnull;
|
|
}
|
|
|
|
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();
|
|
}
|
|
|
|
bool
|
|
nsQtNetworkManager::isOnline()
|
|
{
|
|
static bool sForceOnlineUSB = getenv("MOZ_MEEGO_NET_ONLINE") != 0;
|
|
return sForceOnlineUSB || mOnline;
|
|
}
|
|
|
|
void
|
|
nsQtNetworkManager::onlineStateChanged(bool online)
|
|
{
|
|
mOnline = online;
|
|
}
|
|
|
|
/*
|
|
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.
|
|
*/
|
|
|
|
bool
|
|
nsQtNetworkManager::openConnection(const QString& host)
|
|
{
|
|
// we are already online -> return true.
|
|
if (isOnline()) {
|
|
return true;
|
|
}
|
|
|
|
if (NS_IsMainThread()) {
|
|
openSession();
|
|
} else {
|
|
// jump to mainthread and do the work there
|
|
emit openConnectionSignal();
|
|
}
|
|
|
|
// 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::openSession()
|
|
{
|
|
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();
|
|
}
|
|
}
|