From 91ff19ea3233310f5db542e880661d1efe0151e2 Mon Sep 17 00:00:00 2001 From: Aaron McCarthy Date: Thu, 10 Jun 2010 14:31:01 +1000 Subject: Cherry pick fix for MOBILITY-938 from Qt Mobility. 216f4016d1b447d51630086afca179df11fd6997 --- src/plugins/bearer/symbian/symbianengine.cpp | 98 ++++++++-------- src/plugins/bearer/symbian/symbianengine.h | 5 +- tests/manual/bearerex/bearerex.cpp | 90 ++++++++------ tests/manual/bearerex/bearerex.h | 15 ++- tests/manual/bearerex/bearerex.pro | 6 +- tests/manual/bearerex/sessiondialog.ui | 168 +++++++++++++++++---------- 6 files changed, 223 insertions(+), 159 deletions(-) diff --git a/src/plugins/bearer/symbian/symbianengine.cpp b/src/plugins/bearer/symbian/symbianengine.cpp index 3d462ee..8780218 100644 --- a/src/plugins/bearer/symbian/symbianengine.cpp +++ b/src/plugins/bearer/symbian/symbianengine.cpp @@ -46,7 +46,6 @@ #include #include #include -#include #include #include // For randgen seeding #include // For randgen seeding @@ -115,7 +114,7 @@ QString SymbianNetworkConfigurationPrivate::bearerName() const SymbianEngine::SymbianEngine(QObject *parent) : QBearerEngine(parent), CActive(CActive::EPriorityIdle), iFirstUpdate(true), iInitOk(true), - iIgnoringUpdates(false) + iUpdatePending(false) { } @@ -190,6 +189,28 @@ SymbianEngine::~SymbianEngine() delete cleanup; } +void SymbianEngine::delayedConfigurationUpdate() +{ + QMutexLocker locker(&mutex); + + if (iUpdatePending) { +#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG + qDebug("QNCM delayed configuration update (ECommit or ERecover occurred)."); +#endif + TRAPD(error, updateConfigurationsL()); + if (error == KErrNone) { + updateStatesToSnaps(); + } + iUpdatePending = false; + // Start monitoring again. + if (!IsActive()) { + SetActive(); + // Start waiting for new notification + ipCommsDB->RequestNotification(iStatus); + } + } +} + bool SymbianEngine::hasIdentifier(const QString &id) { QMutexLocker locker(&mutex); @@ -872,55 +893,30 @@ void SymbianEngine::RunL() { QMutexLocker locker(&mutex); - if (iIgnoringUpdates) { -#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG - qDebug("QNCM CommsDB event handling postponed (postpone-timer running because IAPs/SNAPs were updated very recently)."); -#endif - return; - } - - RDbNotifier::TEvent event = STATIC_CAST(RDbNotifier::TEvent, iStatus.Int()); - - switch (event) { - case RDbNotifier::EUnlock: /** All read locks have been removed. */ - case RDbNotifier::ECommit: /** A transaction has been committed. */ - case RDbNotifier::ERollback: /** A transaction has been rolled back */ - case RDbNotifier::ERecover: /** The database has been recovered */ + if (iStatus != KErrCancel) { #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG qDebug("QNCM CommsDB event (of type RDbNotifier::TEvent) received: %d", iStatus.Int()); #endif - iIgnoringUpdates = true; - // Other events than ECommit get lower priority. In practice with those events, - // we delay_before_updating methods, whereas - // with ECommit we _update_before_delaying the reaction to next event. - // Few important notes: 1) listening to only ECommit does not seem to be adequate, - // but updates will be missed. Hence other events are reacted upon too. - // 2) RDbNotifier records the most significant event, and that will be returned once - // we issue new RequestNotification, and hence updates will not be missed even - // when we are 'not reacting to them' for few seconds. - if (event == RDbNotifier::ECommit) { - TRAPD(error, updateConfigurationsL()); - if (error == KErrNone) { - QT_TRYCATCH_LEAVING(updateStatesToSnaps()); - } - locker.unlock(); - waitRandomTime(); - locker.relock(); - } else { - locker.unlock(); - waitRandomTime(); - locker.relock(); - TRAPD(error, updateConfigurationsL()); - if (error == KErrNone) { - QT_TRYCATCH_LEAVING(updateStatesToSnaps()); + // By default, start relistening notifications. Stop only if interesting event occured. + iWaitingCommsDatabaseNotifications = true; + RDbNotifier::TEvent event = STATIC_CAST(RDbNotifier::TEvent, iStatus.Int()); + switch (event) { + case RDbNotifier::ECommit: /** A transaction has been committed. */ + case RDbNotifier::ERecover: /** The database has been recovered */ + // Mark that there is update pending. No need to ask more events, + // as we know we will be updating anyway when the timer expires. + if (!iUpdatePending) { + iUpdatePending = true; + iWaitingCommsDatabaseNotifications = false; + // Update after random time, so that many processes won't + // start updating simultaneously + updateConfigurationsAfterRandomTime(); } + break; + default: + // Do nothing + break; } - iIgnoringUpdates = false; // Wait time done, allow updating again - iWaitingCommsDatabaseNotifications = true; - break; - default: - // Do nothing - break; } if (iWaitingCommsDatabaseNotifications) { @@ -1135,15 +1131,13 @@ void SymbianEngine::configurationStateChangeReport(TUint32 accessPointId, QNetwo } // Waits for 2..6 seconds. -void SymbianEngine::waitRandomTime() +void SymbianEngine::updateConfigurationsAfterRandomTime() { - int iTimeToWait = qMax(2000, (qAbs(qrand()) % 7) * 1000); + int iTimeToWait = qMax(1000, (qAbs(qrand()) % 68) * 100); #ifdef QT_BEARERMGMT_SYMBIAN_DEBUG qDebug("QNCM waiting random time: %d ms", iTimeToWait); #endif - QEventLoop loop; - QTimer::singleShot(iTimeToWait, &loop, SLOT(quit())); - loop.exec(); + QTimer::singleShot(iTimeToWait, this, SLOT(delayedConfigurationUpdate())); } QNetworkConfigurationPrivatePointer SymbianEngine::dataByConnectionId(TUint aConnectionId) @@ -1164,7 +1158,7 @@ QNetworkConfigurationPrivatePointer SymbianEngine::dataByConnectionId(TUint aCon AccessPointsAvailabilityScanner::AccessPointsAvailabilityScanner(SymbianEngine& owner, RConnectionMonitor& connectionMonitor) - : CActive(CActive::EPriorityStandard), iOwner(owner), iConnectionMonitor(connectionMonitor) + : CActive(CActive::EPriorityHigh), iOwner(owner), iConnectionMonitor(connectionMonitor) { CActiveScheduler::Add(this); } diff --git a/src/plugins/bearer/symbian/symbianengine.h b/src/plugins/bearer/symbian/symbianengine.h index 18fd249..27f3db4 100644 --- a/src/plugins/bearer/symbian/symbianengine.h +++ b/src/plugins/bearer/symbian/symbianengine.h @@ -159,6 +159,7 @@ Q_SIGNALS: public Q_SLOTS: void updateConfigurations(); + void delayedConfigurationUpdate(); private: void updateStatesToSnaps(); @@ -183,7 +184,7 @@ private: void accessPointScanningReady(TBool scanSuccessful, TConnMonIapInfo iapInfo); void startCommsDatabaseNotifications(); void stopCommsDatabaseNotifications(); - void waitRandomTime(); + void updateConfigurationsAfterRandomTime(); QNetworkConfigurationPrivatePointer defaultConfigurationL(); TBool GetS60PlatformVersion(TUint& aMajor, TUint& aMinor) const; @@ -211,7 +212,7 @@ private: // Data TBool iOnline; TBool iInitOk; TBool iUpdateGoingOn; - TBool iIgnoringUpdates; + TBool iUpdatePending; AccessPointsAvailabilityScanner* ipAccessPointsAvailabilityScanner; diff --git a/tests/manual/bearerex/bearerex.cpp b/tests/manual/bearerex/bearerex.cpp index bf60dd1..00cb481 100644 --- a/tests/manual/bearerex/bearerex.cpp +++ b/tests/manual/bearerex/bearerex.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** @@ -40,6 +40,7 @@ ****************************************************************************/ #include "bearerex.h" +#include "datatransferer.h" #include @@ -261,8 +262,8 @@ SessionTab::SessionTab(QNetworkConfiguration* apNetworkConfiguration, QListWidget* eventListWidget, int index, BearerEx * parent) - : QWidget(parent), m_http(0), m_eventListWidget(eventListWidget), - m_index(index), m_httpRequestOngoing(false), m_alrEnabled (false) + : QWidget(parent), m_dataTransferer(0), m_eventListWidget(eventListWidget), + m_index(index), m_alrEnabled (false) { setupUi(this); @@ -300,41 +301,46 @@ SessionTab::SessionTab(QNetworkConfiguration* apNetworkConfiguration, SessionTab::~SessionTab() { - // Need to be nulled, because modal dialogs may return after destruction of this object and - // use already released resources. - delete m_NetworkSession; - m_NetworkSession = NULL; - delete m_http; - m_http = NULL; + delete m_NetworkSession; m_NetworkSession = 0; + delete m_dataTransferer; m_dataTransferer = 0; } -void SessionTab::on_createQHttpButton_clicked() +void SessionTab::on_createQNetworkAccessManagerButton_clicked() { - if (m_httpRequestOngoing) { - return; + if (m_dataTransferer) { + disconnect(m_dataTransferer, 0, 0, 0); + delete m_dataTransferer; + m_dataTransferer = 0; } - - if (m_http) { - disconnect(m_http, 0, 0, 0); - delete m_http; + // Create new object according to current selection + QString type(comboBox->currentText()); + if (type == "QNAM") { + m_dataTransferer = new DataTransfererQNam(this); + } else if (type == "QTcpSocket") { + m_dataTransferer = new DataTransfererQTcp(this); + } else if (type == "QHttp") { + m_dataTransferer = new DataTransfererQHttp(this); + } else { + qDebug("BearerEx Warning, unknown data transfer object requested, not creating anything."); + return; } - m_http = new QHttp(this); - createQHttpButton->setText("Recreate QHttp"); - connect(m_http, SIGNAL(done(bool)), this, SLOT(done(bool))); + createQNetworkAccessManagerButton->setText("Recreate"); + connect(m_dataTransferer, SIGNAL(finished(quint32, qint64, QString)), this, SLOT(finished(quint32, qint64, QString))); } void SessionTab::on_sendRequestButton_clicked() { - if (m_http) { - QString urlstring("http://www.google.com"); - QUrl url(urlstring); - m_http->setHost(url.host(), QHttp::ConnectionModeHttp, url.port() == -1 ? 0 : url.port()); - m_http->get(urlstring); - m_httpRequestOngoing = true; + if (m_dataTransferer) { + if (!m_dataTransferer->transferData()) { + QMessageBox msgBox; + msgBox.setStandardButtons(QMessageBox::Close); + msgBox.setText("Data transfer not started. \nVery likely data transfer ongoing."); + msgBox.exec(); + } } else { QMessageBox msgBox; msgBox.setStandardButtons(QMessageBox::Close); - msgBox.setText("QHttp not created.\nCreate QHttp First."); + msgBox.setText("Data object not created.\nCreate data object first."); msgBox.exec(); } } @@ -419,7 +425,7 @@ void SessionTab::opened() listItem->setText(QString("S")+QString::number(m_index)+QString(" - ")+QString("Opened")); m_eventListWidget->addItem(listItem); - QVariant identifier = m_NetworkSession->property("ActiveConfiguration"); + QVariant identifier = m_NetworkSession->sessionProperty("ActiveConfiguration"); if (!identifier.isNull()) { QString configId = identifier.toString(); QNetworkConfiguration config = m_ConfigManager->configurationFromIdentifier(configId); @@ -429,7 +435,7 @@ void SessionTab::opened() } if (m_NetworkSession->configuration().type() == QNetworkConfiguration::UserChoice) { - QVariant identifier = m_NetworkSession->property("UserChoiceConfiguration"); + QVariant identifier = m_NetworkSession->sessionProperty("UserChoiceConfiguration"); if (!identifier.isNull()) { QString configId = identifier.toString(); QNetworkConfiguration config = m_ConfigManager->configurationFromIdentifier(configId); @@ -480,6 +486,18 @@ QString SessionTab::stateString(QNetworkSession::State state) return stateString; } +void SessionTab::on_dataObjectChanged(const QString &newObjectType) +{ + qDebug() << "BearerEx SessionTab dataObjectChanged to: " << newObjectType; + if (m_dataTransferer) { + disconnect(m_dataTransferer, 0, 0, 0); + delete m_dataTransferer; m_dataTransferer = 0; + qDebug() << "BearerEx SessionTab, previous data object deleted."; + } + createQNetworkAccessManagerButton->setText("Create"); +} + + void SessionTab::stateChanged(QNetworkSession::State state) { newState(state); @@ -491,7 +509,7 @@ void SessionTab::stateChanged(QNetworkSession::State state) void SessionTab::newState(QNetworkSession::State state) { - QVariant identifier = m_NetworkSession->property("ActiveConfiguration"); + QVariant identifier = m_NetworkSession->sessionProperty("ActiveConfiguration"); if (state == QNetworkSession::Connected && !identifier.isNull()) { QString configId = identifier.toString(); QNetworkConfiguration config = m_ConfigManager->configurationFromIdentifier(configId); @@ -542,18 +560,14 @@ void SessionTab::error(QNetworkSession::SessionError error) msgBox.exec(); } -void SessionTab::done(bool error) +void SessionTab::finished(quint32 errorCode, qint64 dataReceived, QString errorType) { - m_httpRequestOngoing = false; - QMessageBox msgBox; msgBox.setStandardButtons(QMessageBox::Close); - if (error) { - msgBox.setText("HTTP request failed."); - } else { - QString result(m_http->readAll()); - msgBox.setText(QString("HTTP request finished successfully.\nReceived ")+QString::number(result.length())+QString(" bytes.")); - } + msgBox.setText(QString("Data transfer completed. \nError code: ") + QString::number(errorCode) + + "\nError type: " + errorType + + "\nBytes received: " + + QString::number(dataReceived)); msgBox.exec(); // Check if the networksession still exists - it may have gone after returning from // the modal dialog (in the case that app has been closed, and deleting QHttp will diff --git a/tests/manual/bearerex/bearerex.h b/tests/manual/bearerex/bearerex.h index 6bcb3e5..b81d486 100644 --- a/tests/manual/bearerex/bearerex.h +++ b/tests/manual/bearerex/bearerex.h @@ -55,13 +55,16 @@ #endif #include "qnetworkconfigmanager.h" #include "qnetworksession.h" +#include "datatransferer.h" #include "xqlistwidget.h" QT_BEGIN_NAMESPACE -class QHttp; +class QNetworkAccessManager; +class QNetworkReply; QT_END_NAMESPACE class SessionTab; +class DataTransferer; QT_USE_NAMESPACE @@ -113,14 +116,15 @@ public: QString stateString(QNetworkSession::State state); private Q_SLOTS: - void on_createQHttpButton_clicked(); + void on_createQNetworkAccessManagerButton_clicked(); void on_sendRequestButton_clicked(); void on_openSessionButton_clicked(); void on_closeSessionButton_clicked(); void on_stopConnectionButton_clicked(); void on_deleteSessionButton_clicked(); + void on_dataObjectChanged(const QString& newObjectType); void on_alrButton_clicked(); - void done(bool error); + void finished(quint32 errorCode, qint64 dataReceived, QString errorType); void newConfigurationActivated(); void preferredConfigurationChanged(const QNetworkConfiguration& config, bool isSeamless); @@ -131,13 +135,14 @@ private Q_SLOTS: void error(QNetworkSession::SessionError error); private: //data - QHttp* m_http; + // QNetworkAccessManager* m_networkAccessManager; + DataTransferer* m_dataTransferer; QNetworkSession* m_NetworkSession; QNetworkConfigurationManager* m_ConfigManager; QListWidget* m_eventListWidget; QNetworkConfiguration m_config; int m_index; - bool m_httpRequestOngoing; + bool m_dataTransferOngoing; bool m_alrEnabled; }; diff --git a/tests/manual/bearerex/bearerex.pro b/tests/manual/bearerex/bearerex.pro index 7b21183..df39c85 100644 --- a/tests/manual/bearerex/bearerex.pro +++ b/tests/manual/bearerex/bearerex.pro @@ -17,10 +17,12 @@ maemo5|maemo6 { # Example headers and sources HEADERS += bearerex.h \ - xqlistwidget.h + xqlistwidget.h \ + datatransferer.h SOURCES += bearerex.cpp \ main.cpp \ - xqlistwidget.cpp + xqlistwidget.cpp \ + datatransferer.cpp symbian:TARGET.CAPABILITY = NetworkServices NetworkControl ReadUserData diff --git a/tests/manual/bearerex/sessiondialog.ui b/tests/manual/bearerex/sessiondialog.ui index fcf2136..c50af70 100644 --- a/tests/manual/bearerex/sessiondialog.ui +++ b/tests/manual/bearerex/sessiondialog.ui @@ -1,78 +1,87 @@ - + + SessionTab - - + + + + 0 + 0 + 192 + 262 + + + - - - - + + + + SNAP - - - + + + true - - - + + + IAP - - - + + + true - + true - - - + + + Bearer - - - + + + true - - - + + + Sent/Rec. - - - + + + true - - - + + + State - - - + + + true @@ -80,52 +89,71 @@ - - - - + + + + Open Session - - - + + + Close Session - - - + + + Stop Conn. - - - - Create QHttp + + + + Enable ALR - - - + + + Send Test Req. - - - - Enable ALR + + + + Create - - - + + + + + QNAM + + + + + QTcpSocket + + + + + QHttp + + + + + + + Delete Session @@ -135,5 +163,25 @@ - + + + comboBox + currentIndexChanged(QString) + SessionTab + on_dataObjectChanged(QString) + + + 40 + 211 + + + 10 + 258 + + + + + + on_dataObjectChanged(QString) + -- cgit v0.12