summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorQt Continuous Integration System <qt-info@nokia.com>2010-05-15 06:09:15 (GMT)
committerQt Continuous Integration System <qt-info@nokia.com>2010-05-15 06:09:15 (GMT)
commit0a6d0d1d9aba54890908ec0ec02e066c060360c3 (patch)
tree1e484868f13b5453bbb7d171220317e7d6126d2a /src
parent6100e83f3cbf40199da3078c1954a4dc1f77cb8f (diff)
parentb0f4dab4c825650c3a7a72b87508bf6f3e5ffd50 (diff)
downloadQt-0a6d0d1d9aba54890908ec0ec02e066c060360c3.zip
Qt-0a6d0d1d9aba54890908ec0ec02e066c060360c3.tar.gz
Qt-0a6d0d1d9aba54890908ec0ec02e066c060360c3.tar.bz2
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/oslo-staging-1 into 4.7-integration
* '4.7' of scm.dev.nokia.troll.no:qt/oslo-staging-1: Revert "More improvements to pixmap cache key generation" More improvements to pixmap cache key generation More 4.7 stuff. Fix for autotest failure in qwidget::saveRestoreGeometry() Optimized pixmapcache key generation for icons and styles doc: Another upgrade of the top page and overviews. Mac: restoreGeometry() [Regression] Build failure on Mac Carbon doc: Added some \briefs to how-to docs. Some 4.7 changes. Updated changelog. Cherry pick fix for MOBILITY-932 from Qt Mobility. Cherry pick fix for MOBILITY-962 from Qt Mobility. Cherry pick fix for MOBILITY-828 from Qt Mobility. Bearer management changes from Qt Mobility. Cherry pick fix for MOBILITY-828 from Qt Mobility. Added snippet labels to QML Dial example. Fixed documentation typo.
Diffstat (limited to 'src')
-rw-r--r--src/gui/image/qicon.cpp23
-rw-r--r--src/gui/kernel/qcocoawindowdelegate_mac.mm21
-rw-r--r--src/gui/kernel/qt_mac_p.h2
-rw-r--r--src/gui/kernel/qwidget.cpp22
-rw-r--r--src/gui/kernel/qwidget_p.h8
-rw-r--r--src/gui/styles/qgtkpainter.cpp16
-rw-r--r--src/gui/styles/qstylehelper.cpp74
-rw-r--r--src/plugins/bearer/symbian/qnetworksession_impl.cpp403
-rw-r--r--src/plugins/bearer/symbian/qnetworksession_impl.h15
-rw-r--r--src/plugins/bearer/symbian/symbianengine.cpp248
-rw-r--r--src/plugins/bearer/symbian/symbianengine.h27
11 files changed, 529 insertions, 330 deletions
diff --git a/src/gui/image/qicon.cpp b/src/gui/image/qicon.cpp
index 891b1db..9f1eea2 100644
--- a/src/gui/image/qicon.cpp
+++ b/src/gui/image/qicon.cpp
@@ -261,16 +261,19 @@ QPixmap QPixmapIconEngine::pixmap(const QSize &size, QIcon::Mode mode, QIcon::St
if (!actualSize.isNull() && (actualSize.width() > size.width() || actualSize.height() > size.height()))
actualSize.scale(size, Qt::KeepAspectRatio);
- QString key = QLatin1String("$qt_icon_")
- + QString::number(pm.cacheKey())
- + QString::number(pe->mode)
- + QString::number(QApplication::palette().cacheKey())
- + QLatin1Char('_')
- + QString::number(actualSize.width())
- + QLatin1Char('_')
- + QString::number(actualSize.height())
- + QLatin1Char('_');
-
+ int digits = sizeof(qint64)/sizeof(QChar);
+ quint64 tkey = pm.cacheKey(),
+ tmode = pe->mode,
+ tpalkey = QApplication::palette().cacheKey(),
+ twidth = actualSize.width(),
+ theight = actualSize.height();
+
+ QString key = QLatin1Literal("qt_")
+ % QString::fromRawData((QChar*)&tkey, digits)
+ % QString::fromRawData((QChar*)&tmode, digits)
+ % QString::fromRawData((QChar*)&tpalkey, digits)
+ % QString::fromRawData((QChar*)&twidth, digits)
+ % QString::fromRawData((QChar*)&theight, digits);
if (mode == QIcon::Active) {
if (QPixmapCache::find(key + QString::number(mode), pm))
diff --git a/src/gui/kernel/qcocoawindowdelegate_mac.mm b/src/gui/kernel/qcocoawindowdelegate_mac.mm
index 24498f8..2b9cf85 100644
--- a/src/gui/kernel/qcocoawindowdelegate_mac.mm
+++ b/src/gui/kernel/qcocoawindowdelegate_mac.mm
@@ -202,6 +202,11 @@ static void cleanupCocoaWindowDelegate()
QWindowStateChangeEvent e(Qt::WindowStates(widgetData->window_state
& ~Qt::WindowMaximized));
qt_sendSpontaneousEvent(qwidget, &e);
+ } else {
+ widgetData->window_state = widgetData->window_state & ~Qt::WindowMaximized;
+ QWindowStateChangeEvent e(Qt::WindowStates(widgetData->window_state
+ | Qt::WindowMaximized));
+ qt_sendSpontaneousEvent(qwidget, &e);
}
NSRect rect = [[window contentView] frame];
const QSize newSize(rect.size.width, rect.size.height);
@@ -305,9 +310,19 @@ static void cleanupCocoaWindowDelegate()
Q_UNUSED(newFrame);
// saving the current window geometry before the window is maximized
QWidget *qwidget = m_windowHash->value(window);
- if (qwidget->isWindow() && !(qwidget->windowState() & Qt::WindowMaximized)) {
- QWidgetPrivate *widgetPrivate = qt_widget_private(qwidget);
- widgetPrivate->topData()->normalGeometry = qwidget->geometry();
+ QWidgetPrivate *widgetPrivate = qt_widget_private(qwidget);
+ if (qwidget->isWindow()) {
+ if(qwidget->windowState() & Qt::WindowMaximized) {
+ // Restoring
+ widgetPrivate->topData()->wasMaximized = false;
+ } else {
+ // Maximizing
+ widgetPrivate->topData()->normalGeometry = qwidget->geometry();
+ // If the window was maximized we need to update the coordinates since now it will start at 0,0.
+ // We do this in a special field that is only used when not restoring but manually resizing the window.
+ // Since the coordinates are fixed we just set a boolean flag.
+ widgetPrivate->topData()->wasMaximized = true;
+ }
}
return YES;
}
diff --git a/src/gui/kernel/qt_mac_p.h b/src/gui/kernel/qt_mac_p.h
index 3341ce1..ca9541a 100644
--- a/src/gui/kernel/qt_mac_p.h
+++ b/src/gui/kernel/qt_mac_p.h
@@ -57,7 +57,9 @@
#ifdef __OBJC__
#include <Cocoa/Cocoa.h>
+#ifdef QT_MAC_USE_COCOA
#include <objc/runtime.h>
+#endif // QT_MAC_USE_COCOA
#endif
#include <CoreServices/CoreServices.h>
diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp
index 4a9fa94..1f2cd8c 100644
--- a/src/gui/kernel/qwidget.cpp
+++ b/src/gui/kernel/qwidget.cpp
@@ -1581,6 +1581,11 @@ void QWidgetPrivate::createTLExtra()
x->inTopLevelResize = false;
x->inRepaint = false;
x->embedded = 0;
+#ifdef Q_WS_MAC
+#ifdef QT_MAC_USE_COCOA
+ x->wasMaximized = false;
+#endif // QT_MAC_USE_COCOA
+#endif // Q_WS_MAC
createTLSysExtra();
#ifdef QWIDGET_EXTRA_DEBUG
static int count = 0;
@@ -6720,6 +6725,18 @@ void QWidget::setGeometry(const QRect &r)
*/
QByteArray QWidget::saveGeometry() const
{
+#ifdef QT_MAC_USE_COCOA
+ // We check if the window was maximized during this invocation. If so, we need to record the
+ // starting position as 0,0.
+ Q_D(const QWidget);
+ QRect newFramePosition = frameGeometry();
+ QRect newNormalPosition = normalGeometry();
+ if(d->topData()->wasMaximized && !(windowState() & Qt::WindowMaximized)) {
+ // Change the starting position
+ newFramePosition.moveTo(0, 0);
+ newNormalPosition.moveTo(0, 0);
+ }
+#endif // QT_MAC_USE_COCOA
QByteArray array;
QDataStream stream(&array, QIODevice::WriteOnly);
stream.setVersion(QDataStream::Qt_4_0);
@@ -6729,8 +6746,13 @@ QByteArray QWidget::saveGeometry() const
stream << magicNumber
<< majorVersion
<< minorVersion
+#ifdef QT_MAC_USE_COCOA
+ << newFramePosition
+ << newNormalPosition
+#else
<< frameGeometry()
<< normalGeometry()
+#endif // QT_MAC_USE_COCOA
<< qint32(QApplication::desktop()->screenNumber(this))
<< quint8(windowState() & Qt::WindowMaximized)
<< quint8(windowState() & Qt::WindowFullScreen);
diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h
index cad60b5..3f494d8 100644
--- a/src/gui/kernel/qwidget_p.h
+++ b/src/gui/kernel/qwidget_p.h
@@ -170,6 +170,14 @@ struct QTLWExtra {
WindowGroupRef group;
IconRef windowIcon; // the current window icon, if set with setWindowIcon_sys.
quint32 savedWindowAttributesFromMaximized; // Saved attributes from when the calling updateMaximizeButton_sys()
+#ifdef QT_MAC_USE_COCOA
+ // This value is just to make sure we maximize and restore to the right location, yet we allow apps to be maximized and
+ // manually resized.
+ // The name is misleading, since this is set when maximizing the window. It is a hint to saveGeometry(..) to record the
+ // starting position as 0,0 instead of the normal starting position.
+ bool wasMaximized;
+#endif // QT_MAC_USE_COCOA
+
#elif defined(Q_WS_QWS) // <--------------------------------------------------------- QWS
#ifndef QT_NO_QWS_MANAGER
QWSManager *qwsManager;
diff --git a/src/gui/styles/qgtkpainter.cpp b/src/gui/styles/qgtkpainter.cpp
index 1f68f2f..a6686e2 100644
--- a/src/gui/styles/qgtkpainter.cpp
+++ b/src/gui/styles/qgtkpainter.cpp
@@ -154,9 +154,21 @@ QGtkPainter::QGtkPainter(QPainter *_painter)
static QString uniqueName(const QString &key, GtkStateType state, GtkShadowType shadow,
const QSize &size, GtkWidget *widget = 0)
{
+
+ int digits = sizeof(qint64)/sizeof(QChar);
+ quint64 tstate= state,
+ tshadow = shadow,
+ twidth = size.width(),
+ theight = size.height(),
+ twidget = quint64(widget);
+
// Note the widget arg should ideally use the widget path, though would compromise performance
- QString tmp = QString(QLS("%0-%1-%2-%3x%4-%5")).arg(key).arg(uint(state)).arg(shadow)
- .arg(size.width()).arg(size.height()).arg(quintptr(widget));
+ QString tmp = key
+ % QString::fromRawData((QChar*)&tstate, digits)
+ % QString::fromRawData((QChar*)&tshadow, digits)
+ % QString::fromRawData((QChar*)&twidth, digits)
+ % QString::fromRawData((QChar*)&theight, digits)
+ % QString::fromRawData((QChar*)&twidget, digits);
return tmp;
}
diff --git a/src/gui/styles/qstylehelper.cpp b/src/gui/styles/qstylehelper.cpp
index 296c51c..22f2014 100644
--- a/src/gui/styles/qstylehelper.cpp
+++ b/src/gui/styles/qstylehelper.cpp
@@ -58,67 +58,35 @@
QT_BEGIN_NAMESPACE
-// internal helper. Converts an integer value to an unique string token
-template <typename T>
-struct HexString
-{
- inline HexString(const T t)
- : val(t)
- {}
-
- inline void write(QChar *&dest) const
- {
- const ushort hexChars[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
- const char *c = reinterpret_cast<const char *>(&val);
- for (uint i = 0; i < sizeof(T); ++i) {
- *dest++ = hexChars[*c & 0xf];
- *dest++ = hexChars[(*c & 0xf0) >> 4];
- ++c;
- }
- }
-
- const T val;
-};
-
-// specialization to enable fast concatenating of our string tokens to a string
-template <typename T>
-struct QConcatenable<HexString<T> >
-{
- typedef HexString<T> type;
- enum { ExactSize = true };
- static int size(const HexString<T> &str) { return sizeof(str.val) * 2; }
- static inline void appendTo(const HexString<T> &str, QChar *&out) { str.write(out); }
-};
-
namespace QStyleHelper {
QString uniqueName(const QString &key, const QStyleOption *option, const QSize &size)
{
const QStyleOptionComplex *complexOption = qstyleoption_cast<const QStyleOptionComplex *>(option);
-
- QString tmp = key
- % QLatin1Char('-')
- % HexString<uint>(option->state)
- % QLatin1Char('-')
- % HexString<uint>(option->direction)
- % QLatin1Char('-')
- % HexString<uint>(complexOption ? uint(complexOption->activeSubControls) : 0u)
- % QLatin1Char('-')
- % HexString<quint64>(option->palette.cacheKey())
- % QLatin1Char('-')
- % HexString<uint>(size.width())
- % QLatin1Char('x')
- % HexString<uint>(size.height());
+ int digits = sizeof(qint64)/sizeof(QChar);
+ quint64 state = option->state,
+ direction = option->direction,
+ subcontrols = (complexOption ? uint(complexOption->activeSubControls) : 0u),
+ palettekey = option->palette.cacheKey(),
+ width = size.width(),
+ height = size.height();
+
+ QString tmp = key % QString::fromRawData((QChar*)&state, digits)
+ % QString::fromRawData((QChar*)&direction, digits)
+ % QString::fromRawData((QChar*)&subcontrols, digits)
+ % QString::fromRawData((QChar*)&palettekey, digits)
+ % QString::fromRawData((QChar*)&width, digits)
+ % QString::fromRawData((QChar*)&height, digits);
#ifndef QT_NO_SPINBOX
if (const QStyleOptionSpinBox *spinBox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) {
- tmp = tmp
- % QLatin1Char('-')
- % HexString<uint>(spinBox->buttonSymbols)
- % QLatin1Char('-')
- % HexString<uint>(spinBox->stepEnabled)
- % QLatin1Char('-')
- % QLatin1Char(spinBox->frame ? '1' : '0');
+ quint64 buttonsymbols = spinBox->buttonSymbols,
+ stepEnabled = spinBox->stepEnabled,
+ frame = spinBox->frame;
+
+ tmp = tmp % QString::fromRawData((QChar*)&buttonsymbols, digits)
+ % QString::fromRawData((QChar*)&stepEnabled, digits)
+ % QString::fromRawData((QChar*)&frame, digits);
}
#endif // QT_NO_SPINBOX
return tmp;
diff --git a/src/plugins/bearer/symbian/qnetworksession_impl.cpp b/src/plugins/bearer/symbian/qnetworksession_impl.cpp
index 5fc0edb..3cd18fb 100644
--- a/src/plugins/bearer/symbian/qnetworksession_impl.cpp
+++ b/src/plugins/bearer/symbian/qnetworksession_impl.cpp
@@ -53,15 +53,17 @@
QT_BEGIN_NAMESPACE
QNetworkSessionPrivateImpl::QNetworkSessionPrivateImpl(SymbianEngine *engine)
- : CActive(CActive::EPriorityStandard), engine(engine), ipConnectionNotifier(0),
- iError(QNetworkSession::UnknownSessionError),
- iALREnabled(0), iConnectInBackground(false)
+ : CActive(CActive::EPriorityUserInput), engine(engine),
+ ipConnectionNotifier(0), iHandleStateNotificationsFromManager(false),
+ iFirstSync(true), iStoppedByUser(false), iClosedByUser(false), iDeprecatedConnectionId(0),
+ iError(QNetworkSession::UnknownSessionError), iALREnabled(0), iConnectInBackground(false)
{
CActiveScheduler::Add(this);
#ifdef SNAP_FUNCTIONALITY_AVAILABLE
iMobility = NULL;
#endif
+
TRAP_IGNORE(iConnectionMonitor.ConnectL());
}
@@ -90,18 +92,72 @@ QNetworkSessionPrivateImpl::~QNetworkSessionPrivateImpl()
// Close global 'Open C' RConnection
setdefaultif(0);
-
- iConnectionMonitor.CancelNotifications();
+
iConnectionMonitor.Close();
}
+void QNetworkSessionPrivateImpl::configurationStateChanged(TUint32 accessPointId, TUint32 connMonId, QNetworkSession::State newState)
+{
+ if (iHandleStateNotificationsFromManager) {
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNS this : " << QString::number((uint)this) << " - "
+ << "configurationStateChanged from manager for IAP : " << QString::number(accessPointId)
+ << "configurationStateChanged connMon ID : " << QString::number(connMonId)
+ << " : to a state: " << newState
+ << " whereas my current state is: " << state;
+#endif
+ if (connMonId == iDeprecatedConnectionId) {
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNS this : " << QString::number((uint)this) << " - "
+ << "however status update from manager ignored because it related to already closed connection.";
+#endif
+ return;
+ }
+ this->newState(newState, accessPointId);
+ }
+}
+
+void QNetworkSessionPrivateImpl::configurationRemoved(QNetworkConfigurationPrivatePointer config)
+{
+ if (!publicConfig.isValid())
+ return;
+
+ SymbianNetworkConfigurationPrivate *symbianConfig = toSymbianConfig(config);
+
+ symbianConfig->mutex.lock();
+ TUint32 configNumericId = symbianConfig->numericId;
+ symbianConfig->mutex.unlock();
+
+ symbianConfig = toSymbianConfig(privateConfiguration(publicConfig));
+
+ symbianConfig->mutex.lock();
+ TUint32 publicNumericId = symbianConfig->numericId;
+ symbianConfig->mutex.unlock();
+
+ if (configNumericId == publicNumericId) {
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNS this : " << QString::number((uint)this) << " - "
+ << "configurationRemoved IAP: " << QString::number(publicNumericId) << " : going to State: Invalid";
+#endif
+ this->newState(QNetworkSession::Invalid, publicNumericId);
+ }
+}
+
void QNetworkSessionPrivateImpl::syncStateWithInterface()
{
if (!publicConfig.isValid())
return;
- // Start monitoring changes in IAP states
- TRAP_IGNORE(iConnectionMonitor.NotifyEventL(*this));
+ if (iFirstSync && publicConfig.isValid()) {
+ QObject::connect(engine, SIGNAL(configurationStateChanged(TUint32, TUint32, QNetworkSession::State)),
+ this, SLOT(configurationStateChanged(TUint32, TUint32, QNetworkSession::State)));
+ // Listen to configuration removals, so that in case the configuration
+ // this session is based on is removed, session knows to enter Invalid -state.
+ QObject::connect(engine, SIGNAL(configurationRemoved(QNetworkConfigurationPrivatePointer)),
+ this, SLOT(configurationRemoved(QNetworkConfigurationPrivatePointer)));
+ }
+ // Start listening IAP state changes from QNetworkConfigurationManagerPrivate
+ iHandleStateNotificationsFromManager = true;
// Check open connections to see if there is already
// an open connection to selected IAP or SNAP
@@ -137,11 +193,8 @@ void QNetworkSessionPrivateImpl::syncStateWithInterface()
}
if (state != QNetworkSession::Connected) {
- // There were no open connections to used IAP or SNAP
- if (iError == QNetworkSession::InvalidConfigurationError) {
- newState(QNetworkSession::Invalid);
- } else if ((publicConfig.state() & QNetworkConfiguration::Discovered) ==
- QNetworkConfiguration::Discovered) {
+ if ((publicConfig.state() & QNetworkConfiguration::Discovered) ==
+ QNetworkConfiguration::Discovered) {
newState(QNetworkSession::Disconnected);
} else {
newState(QNetworkSession::NotAvailable);
@@ -245,13 +298,18 @@ QNetworkSession::SessionError QNetworkSessionPrivateImpl::error() const
void QNetworkSessionPrivateImpl::open()
{
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNS this : " << QString::number((uint)this) << " - "
+ << "open() called, session state is: " << state << " and isOpen is: "
+ << isOpen;
+#endif
if (isOpen || (state == QNetworkSession::Connecting)) {
return;
}
-
- // Cancel notifications from RConnectionMonitor
+
+ // Stop handling IAP state change signals from QNetworkConfigurationManagerPrivate
// => RConnection::ProgressNotification will be used for IAP/SNAP monitoring
- iConnectionMonitor.CancelNotifications();
+ iHandleStateNotificationsFromManager = false;
// Configuration may have been invalidated after session creation by platform
// (e.g. configuration has been deleted).
@@ -259,19 +317,25 @@ void QNetworkSessionPrivateImpl::open()
newState(QNetworkSession::Invalid);
iError = QNetworkSession::InvalidConfigurationError;
emit QNetworkSessionPrivate::error(iError);
- syncStateWithInterface();
return;
}
- // If opening a (un)defined configuration, session emits error and enters
- // NotAvailable -state.
- if (publicConfig.state() == QNetworkConfiguration::Undefined ||
- publicConfig.state() == QNetworkConfiguration::Defined) {
+ // If opening a undefined configuration, session emits error and enters
+ // NotAvailable -state. Note that we will try ones in 'defined' state to avoid excessive
+ // need for WLAN scans (via updateConfigurations()), because user may have walked
+ // into a WLAN range, but periodic background scan has not occurred yet -->
+ // we don't want to force application to make frequent updateConfigurations() calls
+ // to be able to try if e.g. home WLAN is available.
+ if (publicConfig.state() == QNetworkConfiguration::Undefined) {
newState(QNetworkSession::NotAvailable);
iError = QNetworkSession::InvalidConfigurationError;
emit QNetworkSessionPrivate::error(iError);
return;
}
-
+ // Clear possible previous states
+ iStoppedByUser = false;
+ iClosedByUser = false;
+ iDeprecatedConnectionId = 0;
+
TInt error = iSocketServ.Connect();
if (error != KErrNone) {
// Could not open RSocketServ
@@ -446,16 +510,18 @@ TUint QNetworkSessionPrivateImpl::iapClientCount(TUint aIAPId) const
void QNetworkSessionPrivateImpl::close(bool allowSignals)
{
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNS this : " << QString::number((uint)this) << " - "
+ << "close() called, session state is: " << state << " and isOpen is : "
+ << isOpen;
+#endif
if (!isOpen) {
return;
}
-
- SymbianNetworkConfigurationPrivate *symbianConfig =
- toSymbianConfig(privateConfiguration(activeConfig));
-
- symbianConfig->mutex.lock();
- TUint activeIap = symbianConfig->numericId;
- symbianConfig->mutex.unlock();
+ // Mark this session as closed-by-user so that we are able to report
+ // distinguish between stop() and close() state transitions
+ // when reporting.
+ iClosedByUser = true;
isOpen = false;
activeConfig = QNetworkConfiguration();
@@ -469,8 +535,10 @@ void QNetworkSessionPrivateImpl::close(bool allowSignals)
}
#endif
- if (ipConnectionNotifier) {
+ if (ipConnectionNotifier && !iHandleStateNotificationsFromManager) {
ipConnectionNotifier->StopNotifications();
+ // Start handling IAP state change signals from QNetworkConfigurationManagerPrivate
+ iHandleStateNotificationsFromManager = true;
}
iConnection.Close();
@@ -479,29 +547,31 @@ void QNetworkSessionPrivateImpl::close(bool allowSignals)
// Close global 'Open C' RConnection
setdefaultif(0);
-#ifdef Q_CC_NOKIAX86
- if ((allowSignals && iapClientCount(activeIap) <= 0) ||
-#else
- if ((allowSignals && iapClientCount(activeIap) <= 1) ||
-#endif
- (publicConfig.type() == QNetworkConfiguration::UserChoice)) {
+ if (publicConfig.type() == QNetworkConfiguration::UserChoice) {
newState(QNetworkSession::Closing);
+ newState(QNetworkSession::Disconnected);
}
- syncStateWithInterface();
if (allowSignals) {
- if (publicConfig.type() == QNetworkConfiguration::UserChoice) {
- newState(QNetworkSession::Disconnected);
- }
emit closed();
}
}
void QNetworkSessionPrivateImpl::stop()
{
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNS this : " << QString::number((uint)this) << " - "
+ << "stop() called, session state is: " << state << " and isOpen is : "
+ << isOpen;
+#endif
if (!isOpen &&
publicConfig.isValid() &&
publicConfig.type() == QNetworkConfiguration::InternetAccessPoint) {
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNS this : " << QString::number((uint)this) << " - "
+ << "since session is not open, using RConnectionMonitor to stop() the interface";
+#endif
+ iStoppedByUser = true;
// If the publicConfig is type of IAP, enumerate through connections at
// connection monitor. If publicConfig is active in that list, stop it.
// Otherwise there is nothing to stop. Note: because this QNetworkSession is not open,
@@ -515,7 +585,7 @@ void QNetworkSessionPrivateImpl::stop()
}
TUint numSubConnections; // Not used but needed by GetConnectionInfo i/f
TUint connectionId;
- for (TInt i = 1; i <= count; ++i) {
+ for (TUint i = 1; i <= count; ++i) {
// Get (connection monitor's assigned) connection ID
TInt ret = iConnectionMonitor.GetConnectionInfo(i, connectionId, numSubConnections);
if (ret == KErrNone) {
@@ -532,11 +602,25 @@ void QNetworkSessionPrivateImpl::stop()
ETrue);
}
}
+ // Enter disconnected state right away since the session is not even open.
+ // Symbian^3 connection monitor does not emit KLinkLayerClosed when
+ // connection is stopped via connection monitor.
+ newState(QNetworkSession::Disconnected);
}
} else if (isOpen) {
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNS this : " << QString::number((uint)this) << " - "
+ << "since session is open, using RConnection to stop() the interface";
+#endif
// Since we are open, use RConnection to stop the interface
isOpen = false;
+ iStoppedByUser = true;
newState(QNetworkSession::Closing);
+ if (ipConnectionNotifier) {
+ ipConnectionNotifier->StopNotifications();
+ // Start handling IAP state change signals from QNetworkConfigurationManagerPrivate
+ iHandleStateNotificationsFromManager = true;
+ }
iConnection.Stop(RConnection::EStopAuthoritative);
isOpen = true;
close(false);
@@ -654,6 +738,10 @@ void QNetworkSessionPrivateImpl::NewCarrierActive(TAccessPointInfo /*aNewAPInfo*
void QNetworkSessionPrivateImpl::Error(TInt /*aError*/)
{
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNS this : " << QString::number((uint)this) << " - "
+ << "roaming Error() occured";
+#endif
if (isOpen) {
isOpen = false;
activeConfig = QNetworkConfiguration();
@@ -671,6 +759,11 @@ void QNetworkSessionPrivateImpl::Error(TInt /*aError*/)
// changes immediately to Disconnected.
newState(QNetworkSession::Disconnected);
emit closed();
+ } else if (iStoppedByUser) {
+ // If the user of this session has called the stop() and
+ // configuration is based on internet SNAP, this needs to be
+ // done here because platform might roam.
+ newState(QNetworkSession::Disconnected);
}
}
#endif
@@ -975,7 +1068,12 @@ void QNetworkSessionPrivateImpl::RunL()
isOpen = false;
activeConfig = QNetworkConfiguration();
serviceConfig = QNetworkConfiguration();
- iError = QNetworkSession::UnknownSessionError;
+ if (publicConfig.state() == QNetworkConfiguration::Undefined ||
+ publicConfig.state() == QNetworkConfiguration::Defined) {
+ iError = QNetworkSession::InvalidConfigurationError;
+ } else {
+ iError = QNetworkSession::UnknownSessionError;
+ }
emit QNetworkSessionPrivate::error(iError);
Cancel();
if (ipConnectionNotifier) {
@@ -991,8 +1089,16 @@ void QNetworkSessionPrivateImpl::DoCancel()
iConnection.Close();
}
+// Enters newState if feasible according to current state.
+// AccessPointId may be given as parameter. If it is zero, state-change is assumed to
+// concern this session's configuration. If non-zero, the configuration is looked up
+// and checked if it matches the configuration this session is based on.
bool QNetworkSessionPrivateImpl::newState(QNetworkSession::State newState, TUint accessPointId)
{
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNS this : " << QString::number((uint)this) << " - "
+ << "NEW STATE, IAP ID : " << QString::number(accessPointId) << " , newState : " << QString::number(newState);
+#endif
// Make sure that activeConfig is always updated when SNAP is signaled to be
// connected.
if (isOpen && publicConfig.type() == QNetworkConfiguration::ServiceNetwork &&
@@ -1027,9 +1133,29 @@ bool QNetworkSessionPrivateImpl::newState(QNetworkSession::State newState, TUint
if (state == QNetworkSession::Roaming && newState == QNetworkSession::Connecting) {
return false;
}
+
+ // Make sure that Connected state is not reported when Connection is
+ // already Closing.
+ // Note: Stopping connection results sometimes KLinkLayerOpen
+ // to be reported first (just before KLinkLayerClosed).
+ if (state == QNetworkSession::Closing && newState == QNetworkSession::Connected) {
+ return false;
+ }
+
+ // Make sure that some lagging 'closing' state-changes do not overwrite
+ // if we are already disconnected or closed.
+ if (state == QNetworkSession::Disconnected && newState == QNetworkSession::Closing) {
+ return false;
+ }
bool emitSessionClosed = false;
- if (isOpen && state == QNetworkSession::Connected && newState == QNetworkSession::Disconnected) {
+
+ // If we abruptly go down and user hasn't closed the session, we've been aborted.
+ // Note that session may be in 'closing' state and not in 'connected' state, because
+ // depending on platform the platform may report KConfigDaemonStartingDeregistration
+ // event before KLinkLayerClosed
+ if ((isOpen && state == QNetworkSession::Connected && newState == QNetworkSession::Disconnected) ||
+ (isOpen && !iClosedByUser && newState == QNetworkSession::Disconnected)) {
// Active & Connected state should change directly to Disconnected state
// only when something forces connection to close (eg. when another
// application or session stops connection or when network drops
@@ -1043,14 +1169,17 @@ bool QNetworkSessionPrivateImpl::newState(QNetworkSession::State newState, TUint
if (ipConnectionNotifier) {
ipConnectionNotifier->StopNotifications();
}
- // Start monitoring changes in IAP states
- TRAP_IGNORE(iConnectionMonitor.NotifyEventL(*this));
+ // Start handling IAP state change signals from QNetworkConfigurationManagerPrivate
+ iHandleStateNotificationsFromManager = true;
emitSessionClosed = true; // Emit SessionClosed after state change has been reported
}
bool retVal = false;
if (accessPointId == 0) {
state = newState;
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNS this : " << QString::number((uint)this) << " - " << "===> EMIT State changed A to: " << state;
+#endif
emit stateChanged(state);
retVal = true;
} else {
@@ -1063,6 +1192,9 @@ bool QNetworkSessionPrivateImpl::newState(QNetworkSession::State newState, TUint
configLocker.unlock();
state = newState;
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNS this : " << QString::number((uint)this) << " - " << "===> EMIT State changed B to: " << state;
+#endif
emit stateChanged(state);
retVal = true;
}
@@ -1075,6 +1207,9 @@ bool QNetworkSessionPrivateImpl::newState(QNetworkSession::State newState, TUint
configLocker.unlock();
state = newState;
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNS this : " << QString::number((uint)this) << " - " << "===> EMIT State changed C to: " << state;
+#endif
emit stateChanged(state);
retVal = true;
}
@@ -1087,21 +1222,14 @@ bool QNetworkSessionPrivateImpl::newState(QNetworkSession::State newState, TUint
QMutexLocker configLocker(&symbianConfig->mutex);
if (symbianConfig->numericId == accessPointId) {
- if (newState == QNetworkSession::Connected) {
- // Make sure that when AccessPoint is reported to be Connected
- // also state of the related configuration changes to Active.
- symbianConfig->state = QNetworkConfiguration::Active;
- configLocker.unlock();
-
+ if (newState != QNetworkSession::Disconnected) {
state = newState;
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNS this : " << QString::number((uint)this) << " - " << "===> EMIT State changed D to: " << state;
+#endif
emit stateChanged(state);
retVal = true;
} else {
- if (newState == QNetworkSession::Disconnected) {
- // Make sure that when AccessPoint is reported to be disconnected
- // also state of the related configuration changes from Active to Defined.
- symbianConfig->state = QNetworkConfiguration::Defined;
- }
QNetworkConfiguration config = bestConfigFromSNAP(publicConfig);
if ((config.state() == QNetworkConfiguration::Defined) ||
(config.state() == QNetworkConfiguration::Discovered)) {
@@ -1109,8 +1237,21 @@ bool QNetworkSessionPrivateImpl::newState(QNetworkSession::State newState, TUint
configLocker.unlock();
state = newState;
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNS this : " << QString::number((uint)this) << " - " << "===> EMIT State changed E to: " << state;
+#endif
emit stateChanged(state);
retVal = true;
+ } else if (config.state() == QNetworkConfiguration::Active) {
+ // Connection to used IAP was closed, but there is another
+ // IAP that's active in used SNAP
+ // => Change state back to Connected
+ state = QNetworkSession::Connected;
+ emit stateChanged(state);
+ retVal = true;
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNS this : " << QString::number((uint)this) << " - " << "===> EMIT State changed F to: " << state;
+#endif
}
}
}
@@ -1121,6 +1262,19 @@ bool QNetworkSessionPrivateImpl::newState(QNetworkSession::State newState, TUint
if (emitSessionClosed) {
emit closed();
}
+ if (state == QNetworkSession::Disconnected) {
+ // The connection has gone down, and processing of status updates must be
+ // stopped. Depending on platform, there may come 'connecting/connected' states
+ // considerably later (almost a second). Connection id is an increasing
+ // number, so this does not affect next _real_ 'conneting/connected' states.
+
+ SymbianNetworkConfigurationPrivate *symbianConfig =
+ toSymbianConfig(privateConfiguration(publicConfig));
+
+ symbianConfig->mutex.lock();
+ iDeprecatedConnectionId = symbianConfig->connectionId;
+ symbianConfig->mutex.unlock();
+ }
return retVal;
}
@@ -1129,6 +1283,9 @@ void QNetworkSessionPrivateImpl::handleSymbianConnectionStatusChange(TInt aConne
TInt aError,
TUint accessPointId)
{
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNS this : " << QString::number((uint)this) << " - " << QString::number(accessPointId) << " , status : " << QString::number(aConnectionStatus);
+#endif
switch (aConnectionStatus)
{
// Connection unitialised
@@ -1167,6 +1324,7 @@ void QNetworkSessionPrivateImpl::handleSymbianConnectionStatusChange(TInt aConne
case KCsdGotLoginInfo:
break;
+ case KConfigDaemonStartingRegistration:
// Creating connection (e.g. GPRS activation)
case KCsdStartingConnect:
case KCsdFinishedConnect:
@@ -1193,6 +1351,7 @@ void QNetworkSessionPrivateImpl::handleSymbianConnectionStatusChange(TInt aConne
case KDataTransferTemporarilyBlocked:
break;
+ case KConfigDaemonStartingDeregistration:
// Hangup or GRPS deactivation
case KConnectionStartingClose:
newState(QNetworkSession::Closing,accessPointId);
@@ -1200,137 +1359,27 @@ void QNetworkSessionPrivateImpl::handleSymbianConnectionStatusChange(TInt aConne
// Connection closed
case KConnectionClosed:
- break;
-
case KLinkLayerClosed:
newState(QNetworkSession::Disconnected,accessPointId);
+ // Report manager about this to make sure this event
+ // is received by all interseted parties (mediated by
+ // manager because it does always receive all events from
+ // connection monitor).
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNS this : " << QString::number((uint)this) << " - " << "reporting disconnection to manager.";
+#endif
+ if (publicConfig.isValid()) {
+ engine->configurationStateChangeReport(toSymbianConfig(privateConfiguration(publicConfig))->numericId, QNetworkSession::Disconnected);
+ }
break;
-
// Unhandled state
default:
break;
}
}
-void QNetworkSessionPrivateImpl::EventL(const CConnMonEventBase& aEvent)
-{
- switch (aEvent.EventType())
- {
- case EConnMonConnectionStatusChange:
- {
- CConnMonConnectionStatusChange* realEvent;
- realEvent = (CConnMonConnectionStatusChange*) &aEvent;
-
- TUint connectionId = realEvent->ConnectionId();
- TInt connectionStatus = realEvent->ConnectionStatus();
-
- // Try to Find IAP Id using connection Id
- TUint apId = 0;
- if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) {
- QList<QNetworkConfiguration> subConfigurations = publicConfig.children();
- for (int i = 0; i < subConfigurations.count(); i++ ) {
- SymbianNetworkConfigurationPrivate *symbianConfig =
- toSymbianConfig(privateConfiguration(subConfigurations[i]));
-
- QMutexLocker configLocker(&symbianConfig->mutex);
-
- if (symbianConfig->connectionId == connectionId) {
- apId = symbianConfig->numericId;
- break;
- }
- }
- } else if (publicConfig.type() == QNetworkConfiguration::InternetAccessPoint) {
- SymbianNetworkConfigurationPrivate *symbianConfig =
- toSymbianConfig(privateConfiguration(publicConfig));
-
- symbianConfig->mutex.lock();
- if (symbianConfig->connectionId == connectionId)
- apId = symbianConfig->numericId;
- symbianConfig->mutex.unlock();
- }
-
- if (apId > 0) {
- handleSymbianConnectionStatusChange(connectionStatus, KErrNone, apId);
- }
- }
- break;
-
- case EConnMonCreateConnection:
- {
- CConnMonCreateConnection* realEvent;
- realEvent = (CConnMonCreateConnection*) &aEvent;
- TUint apId;
- TUint connectionId = realEvent->ConnectionId();
- TRequestStatus status;
- iConnectionMonitor.GetUintAttribute(connectionId, 0, KIAPId, apId, status);
- User::WaitForRequest(status);
- if (status.Int() == KErrNone) {
- // Store connection id to related AccessPoint Configuration
- if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) {
- QList<QNetworkConfiguration> subConfigurations = publicConfig.children();
- for (int i = 0; i < subConfigurations.count(); i++ ) {
- SymbianNetworkConfigurationPrivate *symbianConfig =
- toSymbianConfig(privateConfiguration(subConfigurations[i]));
-
- QMutexLocker configLocker(&symbianConfig->mutex);
-
- if (symbianConfig->numericId == apId) {
- symbianConfig->connectionId = connectionId;
- break;
- }
- }
- } else if (publicConfig.type() == QNetworkConfiguration::InternetAccessPoint) {
- SymbianNetworkConfigurationPrivate *symbianConfig =
- toSymbianConfig(privateConfiguration(publicConfig));
-
- symbianConfig->mutex.lock();
- if (symbianConfig->numericId == apId)
- symbianConfig->connectionId = connectionId;
- symbianConfig->mutex.unlock();
- }
- }
- }
- break;
-
- case EConnMonDeleteConnection:
- {
- CConnMonDeleteConnection* realEvent;
- realEvent = (CConnMonDeleteConnection*) &aEvent;
- TUint connectionId = realEvent->ConnectionId();
- // Remove connection id from related AccessPoint Configuration
- if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) {
- QList<QNetworkConfiguration> subConfigurations = publicConfig.children();
- for (int i = 0; i < subConfigurations.count(); i++ ) {
- SymbianNetworkConfigurationPrivate *symbianConfig =
- toSymbianConfig(privateConfiguration(subConfigurations[i]));
-
- QMutexLocker configLocker(&symbianConfig->mutex);
-
- if (symbianConfig->connectionId == connectionId) {
- symbianConfig->connectionId = 0;
- break;
- }
- }
- } else if (publicConfig.type() == QNetworkConfiguration::InternetAccessPoint) {
- SymbianNetworkConfigurationPrivate *symbianConfig =
- toSymbianConfig(privateConfiguration(publicConfig));
-
- symbianConfig->mutex.lock();
- if (symbianConfig->connectionId == connectionId)
- symbianConfig->connectionId = 0;
- symbianConfig->mutex.unlock();
- }
- }
- break;
-
- default:
- // For unrecognized events
- break;
- }
-}
-
-ConnectionProgressNotifier::ConnectionProgressNotifier(QNetworkSessionPrivateImpl &owner, RConnection &connection)
- : CActive(CActive::EPriorityStandard), iOwner(owner), iConnection(connection)
+ConnectionProgressNotifier::ConnectionProgressNotifier(QNetworkSessionPrivateImpl& owner, RConnection& connection)
+ : CActive(CActive::EPriorityUserInput), iOwner(owner), iConnection(connection)
{
CActiveScheduler::Add(this);
}
diff --git a/src/plugins/bearer/symbian/qnetworksession_impl.h b/src/plugins/bearer/symbian/qnetworksession_impl.h
index 7116519..9767293 100644
--- a/src/plugins/bearer/symbian/qnetworksession_impl.h
+++ b/src/plugins/bearer/symbian/qnetworksession_impl.h
@@ -75,9 +75,8 @@ class SymbianEngine;
class QNetworkSessionPrivateImpl : public QNetworkSessionPrivate, public CActive,
#ifdef SNAP_FUNCTIONALITY_AVAILABLE
- public MMobilityProtocolResp,
+ public MMobilityProtocolResp
#endif
- public MConnectionMonitorObserver
{
Q_OBJECT
public:
@@ -130,8 +129,9 @@ protected: // From CActive
void RunL();
void DoCancel();
-private: // MConnectionMonitorObserver
- void EventL(const CConnMonEventBase& aEvent);
+private Q_SLOTS:
+ void configurationStateChanged(TUint32 accessPointId, TUint32 connMonId, QNetworkSession::State newState);
+ void configurationRemoved(QNetworkConfigurationPrivatePointer config);
private:
TUint iapClientCount(TUint aIAPId) const;
@@ -157,6 +157,13 @@ private: // data
mutable RConnection iConnection;
mutable RConnectionMonitor iConnectionMonitor;
ConnectionProgressNotifier* ipConnectionNotifier;
+
+ bool iHandleStateNotificationsFromManager;
+ bool iFirstSync;
+ bool iStoppedByUser;
+ bool iClosedByUser;
+ TUint32 iDeprecatedConnectionId;
+
#ifdef SNAP_FUNCTIONALITY_AVAILABLE
CActiveCommsMobilityApiExt* iMobility;
#endif
diff --git a/src/plugins/bearer/symbian/symbianengine.cpp b/src/plugins/bearer/symbian/symbianengine.cpp
index 8e9675e..cea8b67 100644
--- a/src/plugins/bearer/symbian/symbianengine.cpp
+++ b/src/plugins/bearer/symbian/symbianengine.cpp
@@ -45,14 +45,14 @@
#include <commdb.h>
#include <cdbcols.h>
#include <d32dbms.h>
+#include <nifvar.h>
#include <QEventLoop>
#include <QTimer>
#include <QTime> // For randgen seeding
#include <QtCore> // For randgen seeding
-// #define QT_BEARERMGMT_CONFIGMGR_DEBUG
-#ifdef QT_BEARERMGMT_CONFIGMGR_DEBUG
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
#include <QDebug>
#endif
@@ -73,7 +73,9 @@
QT_BEGIN_NAMESPACE
-static const int KValueThatWillBeAddedToSNAPId = 1000;
+#ifdef SNAP_FUNCTIONALITY_AVAILABLE
+ static const int KValueThatWillBeAddedToSNAPId = 1000;
+#endif
static const int KUserChoiceIAPId = 0;
SymbianNetworkConfigurationPrivate::SymbianNetworkConfigurationPrivate()
@@ -657,26 +659,34 @@ void SymbianEngine::updateActiveAccessPoints()
iConnectionMonitor.GetConnectionCount(connectionCount, status);
User::WaitForRequest(status);
- // Go through all connections and set state of related IAPs to Active
+ // Go through all connections and set state of related IAPs to Active.
+ // Status needs to be checked carefully, because ConnMon lists also e.g.
+ // WLAN connections that are being currently tried --> we don't want to
+ // state these as active.
TUint connectionId;
TUint subConnectionCount;
TUint apId;
+ TInt connectionStatus;
if (status.Int() == KErrNone) {
for (TUint i = 1; i <= connectionCount; i++) {
iConnectionMonitor.GetConnectionInfo(i, connectionId, subConnectionCount);
iConnectionMonitor.GetUintAttribute(connectionId, subConnectionCount, KIAPId, apId, status);
User::WaitForRequest(status);
QString ident = QString::number(qHash(apId));
-
QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(ident);
if (ptr) {
- online = true;
- inactiveConfigs.removeOne(ident);
+ iConnectionMonitor.GetIntAttribute(connectionId, subConnectionCount, KConnectionStatus, connectionStatus, status);
+ User::WaitForRequest(status);
+ if (connectionStatus == KLinkLayerOpen) {
+ online = true;
+ inactiveConfigs.removeOne(ident);
- toSymbianConfig(ptr)->connectionId = connectionId;
+ QMutexLocker configLocker(&ptr->mutex);
+ toSymbianConfig(ptr)->connectionId = connectionId;
- // Configuration is Active
- changeConfigurationStateTo(ptr, QNetworkConfiguration::Active);
+ // Configuration is Active
+ changeConfigurationStateTo(ptr, QNetworkConfiguration::Active);
+ }
}
}
}
@@ -733,12 +743,12 @@ void SymbianEngine::accessPointScanningReady(TBool scanSuccessful, TConnMonIapIn
}
}
- // Make sure that state of rest of the IAPs won't be Discovered or Active
+ // Make sure that state of rest of the IAPs won't be Active
foreach (const QString &iface, unavailableConfigs) {
QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(iface);
if (ptr) {
// Configuration is Defined
- changeConfigurationStateAtMaxTo(ptr, QNetworkConfiguration::Defined);
+ changeConfigurationStateAtMaxTo(ptr, QNetworkConfiguration::Discovered);
}
}
}
@@ -894,21 +904,22 @@ void SymbianEngine::RunL()
QMutexLocker locker(&mutex);
if (iIgnoringUpdates) {
-#ifdef QT_BEARERMGMT_CONFIGMGR_DEBUG
- qDebug("CommsDB event handling postponed (postpone-timer running because IAPs/SNAPs were updated very recently).");
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug("QNCM CommsDB event handling postponed (postpone-timer running because IAPs/SNAPs were updated very recently).");
#endif
return;
}
if (iStatus != KErrCancel) {
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 */
-#ifdef QT_BEARERMGMT_CONFIGMGR_DEBUG
- qDebug("CommsDB event (of type RDbNotifier::TEvent) received: %d", iStatus.Int());
+#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,
@@ -957,73 +968,95 @@ void SymbianEngine::DoCancel()
ipCommsDB->CancelRequestNotification();
}
-
void SymbianEngine::EventL(const CConnMonEventBase& aEvent)
{
QMutexLocker locker(&mutex);
switch (aEvent.EventType()) {
- case EConnMonCreateConnection:
+ case EConnMonConnectionStatusChange:
{
- CConnMonCreateConnection* realEvent;
- realEvent = (CConnMonCreateConnection*) &aEvent;
- TUint subConnectionCount = 0;
- TUint apId;
- TUint connectionId = realEvent->ConnectionId();
- TRequestStatus status;
- iConnectionMonitor.GetUintAttribute(connectionId, subConnectionCount, KIAPId, apId, status);
- User::WaitForRequest(status);
- QString ident = QString::number(qHash(apId));
-
- QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(ident);
- if (ptr) {
- toSymbianConfig(ptr)->connectionId = connectionId;
- // Configuration is Active
- if (changeConfigurationStateTo(ptr, QNetworkConfiguration::Active))
- updateStatesToSnaps();
-
- if (!iOnline) {
- iOnline = true;
-
- locker.unlock();
- emit this->onlineStateChanged(iOnline);
- locker.relock();
+ CConnMonConnectionStatusChange* realEvent;
+ realEvent = (CConnMonConnectionStatusChange*) &aEvent;
+ TInt connectionStatus = realEvent->ConnectionStatus();
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNCM Connection status : " << QString::number(connectionStatus) << " , connection monitor Id : " << realEvent->ConnectionId();
+#endif
+ if (connectionStatus == KConfigDaemonStartingRegistration) {
+ TUint connectionId = realEvent->ConnectionId();
+ TUint subConnectionCount = 0;
+ TUint apId;
+ TRequestStatus status;
+ iConnectionMonitor.GetUintAttribute(connectionId, subConnectionCount, KIAPId, apId, status);
+ User::WaitForRequest(status);
+ QString ident = QString::number(qHash(apId));
+ QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(ident);
+ if (ptr) {
+ QMutexLocker configLocker(&ptr->mutex);
+ toSymbianConfig(ptr)->connectionId = connectionId;
+ emit this->configurationStateChanged(toSymbianConfig(ptr)->numericId, connectionId, QNetworkSession::Connecting);
}
- }
- }
- break;
-
- case EConnMonDeleteConnection:
- {
- CConnMonDeleteConnection* realEvent;
- realEvent = (CConnMonDeleteConnection*) &aEvent;
- TUint connectionId = realEvent->ConnectionId();
-
- QNetworkConfigurationPrivatePointer ptr = dataByConnectionId(connectionId);
- if (ptr) {
- toSymbianConfig(ptr)->connectionId = 0;
- // Configuration is either Defined or Discovered
- if (changeConfigurationStateAtMaxTo(ptr, QNetworkConfiguration::Discovered))
- updateStatesToSnaps();
- }
-
- bool online = false;
- foreach (const QString &iface, accessPointConfigurations.keys()) {
- QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(iface);
- if (ptr->state == QNetworkConfiguration::Active) {
- online = true;
- break;
+ } else if (connectionStatus == KLinkLayerOpen) {
+ // Connection has been successfully opened
+ TUint connectionId = realEvent->ConnectionId();
+ TUint subConnectionCount = 0;
+ TUint apId;
+ TRequestStatus status;
+ iConnectionMonitor.GetUintAttribute(connectionId, subConnectionCount, KIAPId, apId, status);
+ User::WaitForRequest(status);
+ QString ident = QString::number(qHash(apId));
+ QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(ident);
+ if (ptr) {
+ QMutexLocker configLocker(&ptr->mutex);
+ toSymbianConfig(ptr)->connectionId = connectionId;
+ // Configuration is Active
+ if (changeConfigurationStateTo(ptr, QNetworkConfiguration::Active)) {
+ updateStatesToSnaps();
+ }
+ emit this->configurationStateChanged(toSymbianConfig(ptr)->numericId, connectionId, QNetworkSession::Connected);
+ if (!iOnline) {
+ iOnline = true;
+ emit this->onlineStateChanged(iOnline);
+ }
}
- }
- if (iOnline != online) {
- iOnline = online;
+ } else if (connectionStatus == KConfigDaemonStartingDeregistration) {
+ TUint connectionId = realEvent->ConnectionId();
+ QNetworkConfigurationPrivatePointer ptr = dataByConnectionId(connectionId);
+ if (ptr) {
+ QMutexLocker configLocker(&ptr->mutex);
+ emit this->configurationStateChanged(toSymbianConfig(ptr)->numericId, connectionId, QNetworkSession::Closing);
+ }
+ } else if (connectionStatus == KLinkLayerClosed ||
+ connectionStatus == KConnectionClosed) {
+ // Connection has been closed. Which of the above events is reported, depends on the Symbian
+ // platform.
+ TUint connectionId = realEvent->ConnectionId();
+ QNetworkConfigurationPrivatePointer ptr = dataByConnectionId(connectionId);
+ if (ptr) {
+ // Configuration is either Defined or Discovered
+ if (changeConfigurationStateAtMaxTo(ptr, QNetworkConfiguration::Discovered)) {
+ updateStatesToSnaps();
+ }
- locker.unlock();
- emit this->onlineStateChanged(iOnline);
- locker.relock();
+ QMutexLocker configLocker(&ptr->mutex);
+ emit this->configurationStateChanged(toSymbianConfig(ptr)->numericId, connectionId, QNetworkSession::Disconnected);
+ }
+
+ bool online = false;
+ foreach (const QString &iface, accessPointConfigurations.keys()) {
+ QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(iface);
+ QMutexLocker configLocker(&ptr->mutex);
+ if (ptr->state == QNetworkConfiguration::Active) {
+ online = true;
+ break;
+ }
+ }
+ if (iOnline != online) {
+ iOnline = online;
+ emit this->onlineStateChanged(iOnline);
+ }
}
}
- break;
+ break;
case EConnMonIapAvailabilityChange:
{
@@ -1051,21 +1084,78 @@ void SymbianEngine::EventL(const CConnMonEventBase& aEvent)
}
break;
+ case EConnMonCreateConnection:
+ {
+ // This event is caught to keep connection monitor IDs up-to-date.
+ CConnMonCreateConnection* realEvent;
+ realEvent = (CConnMonCreateConnection*) &aEvent;
+ TUint subConnectionCount = 0;
+ TUint apId;
+ TUint connectionId = realEvent->ConnectionId();
+ TRequestStatus status;
+ iConnectionMonitor.GetUintAttribute(connectionId, subConnectionCount, KIAPId, apId, status);
+ User::WaitForRequest(status);
+ QString ident = QString::number(qHash(apId));
+ QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(ident);
+ if (ptr) {
+ QMutexLocker configLocker(&ptr->mutex);
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNCM updating connection monitor ID : from, to, whose: " << toSymbianConfig(ptr)->connectionId << connectionId << ptr->name;
+#endif
+ toSymbianConfig(ptr)->connectionId = connectionId;
+ }
+ }
+ break;
default:
// For unrecognized events
break;
}
}
-// Waits for 1..4 seconds.
+// Sessions may use this function to report configuration state changes,
+// because on some Symbian platforms (especially Symbian^3) all state changes are not
+// reported by the RConnectionMonitor, in particular in relation to stop() call,
+// whereas they _are_ reported on RConnection progress notifier used by sessions --> centralize
+// this data here so that other sessions may benefit from it too (not all sessions necessarily have
+// RConnection progress notifiers available but they relay on having e.g. disconnected information from
+// manager). Currently only 'Disconnected' state is of interest because it has proven to be troublesome.
+void SymbianEngine::configurationStateChangeReport(TUint32 accessPointId, QNetworkSession::State newState)
+{
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug() << "QNCM A session reported state change for IAP ID: " << accessPointId << " whose new state is: " << newState;
+#endif
+ switch (newState) {
+ case QNetworkSession::Disconnected:
+ {
+ QString ident = QString::number(qHash(accessPointId));
+ QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(ident);
+ if (ptr) {
+ // Configuration is either Defined or Discovered
+ if (changeConfigurationStateAtMaxTo(ptr, QNetworkConfiguration::Discovered)) {
+ updateStatesToSnaps();
+ }
+
+ QMutexLocker configLocker(&ptr->mutex);
+ emit this->configurationStateChanged(toSymbianConfig(ptr)->numericId,
+ toSymbianConfig(ptr)->connectionId,
+ QNetworkSession::Disconnected);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+// Waits for 2..6 seconds.
void SymbianEngine::waitRandomTime()
{
- iTimeToWait = (qAbs(qrand()) % 5) * 1000;
- if (iTimeToWait < 1000) {
- iTimeToWait = 1000;
+ iTimeToWait = (qAbs(qrand()) % 7) * 1000;
+ if (iTimeToWait < 2000) {
+ iTimeToWait = 2000;
}
-#ifdef QT_BEARERMGMT_CONFIGMGR_DEBUG
- qDebug("QNetworkConfigurationManager waiting random time: %d ms", iTimeToWait);
+#ifdef QT_BEARERMGMT_SYMBIAN_DEBUG
+ qDebug("QNCM waiting random time: %d ms", iTimeToWait);
#endif
QTimer::singleShot(iTimeToWait, iIgnoreEventLoop, SLOT(quit()));
iIgnoreEventLoop->exec();
@@ -1076,11 +1166,11 @@ QNetworkConfigurationPrivatePointer SymbianEngine::dataByConnectionId(TUint aCon
QMutexLocker locker(&mutex);
QNetworkConfiguration item;
-
QHash<QString, QNetworkConfigurationPrivatePointer>::const_iterator i =
accessPointConfigurations.constBegin();
while (i != accessPointConfigurations.constEnd()) {
QNetworkConfigurationPrivatePointer ptr = i.value();
+ QMutexLocker configLocker(&ptr->mutex);
if (toSymbianConfig(ptr)->connectionId == aConnectionId)
return ptr;
diff --git a/src/plugins/bearer/symbian/symbianengine.h b/src/plugins/bearer/symbian/symbianengine.h
index afb37de..7d565db 100644
--- a/src/plugins/bearer/symbian/symbianengine.h
+++ b/src/plugins/bearer/symbian/symbianengine.h
@@ -52,6 +52,9 @@
#include <cmmanager.h>
#endif
+// Uncomment and compile QtBearer to gain detailed state tracing
+// #define QT_BEARERMGMT_SYMBIAN_DEBUG
+
class CCommsDatabase;
class QEventLoop;
@@ -90,7 +93,18 @@ public:
Bearer bearer;
+ // So called IAP id from the platform. Remains constant as long as the
+ // platform is aware of the configuration ie. it is stored in the databases
+ // --> does not depend on whether connections are currently open or not.
+ // In practice is the same for the lifetime of the QNetworkConfiguration.
TUint32 numericId;
+ // So called connection id, or connection monitor ID. A dynamic ID assigned
+ // by RConnectionMonitor whenever a new connection is opened. ConnectionID and
+ // numericId/IAP id have 1-to-1 mapping during the lifetime of the connection at
+ // connection monitor. Notably however it changes whenever a new connection to
+ // a given IAP is created. In a sense it is constant during the time the
+ // configuration remains between states Discovered..Active..Discovered, do not
+ // however relay on this.
TUint connectionId;
};
@@ -124,6 +138,9 @@ public:
Q_SIGNALS:
void onlineStateChanged(bool isOnline);
+ void configurationStateChanged(TUint32 accessPointId, TUint32 connMonId,
+ QNetworkSession::State newState);
+
public Q_SLOTS:
void updateConfigurations();
@@ -157,12 +174,17 @@ private:
void startMonitoringIAPData(TUint32 aIapId);
QNetworkConfigurationPrivatePointer dataByConnectionId(TUint aConnectionId);
-protected: // From CActive
+protected:
+ // From CActive
void RunL();
void DoCancel();
-private: // MConnectionMonitorObserver
+private:
+ // MConnectionMonitorObserver
void EventL(const CConnMonEventBase& aEvent);
+ // For QNetworkSessionPrivate to indicate about state changes
+ void configurationStateChangeReport(TUint32 accessPointId,
+ QNetworkSession::State newState);
private: // Data
bool iFirstUpdate;
@@ -181,6 +203,7 @@ private: // Data
friend class QNetworkSessionPrivate;
friend class AccessPointsAvailabilityScanner;
+ friend class QNetworkSessionPrivateImpl;
#ifdef SNAP_FUNCTIONALITY_AVAILABLE
RCmManager iCmManager;