summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQt Continuous Integration System <qt-info@nokia.com>2010-05-17 00:30:12 (GMT)
committerQt Continuous Integration System <qt-info@nokia.com>2010-05-17 00:30:12 (GMT)
commitbdbe09ad2c01ae11d10511b51f8d7a3dfb27b17c (patch)
treefbe4f71381c380f295a959fac6c5ce72a62ba20c
parent6100e83f3cbf40199da3078c1954a4dc1f77cb8f (diff)
parent040ad2dc679ebfb3dec7685edf617fc57bb66ccf (diff)
downloadQt-bdbe09ad2c01ae11d10511b51f8d7a3dfb27b17c.zip
Qt-bdbe09ad2c01ae11d10511b51f8d7a3dfb27b17c.tar.gz
Qt-bdbe09ad2c01ae11d10511b51f8d7a3dfb27b17c.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: (24 commits) Empty commit to trigger a rebuild in the CI system Use case-insensitive comparison for the "data" scheme in URLs tst_bic: Fix building on Mac 64 Fix building of tst_QTcpSocket Autotest: some improvements to timeout testing of tst_QTcpSocket Revert "Optimized pixmapcache key generation for icons and styles" 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. ...
-rw-r--r--dist/changes-4.7.028
-rw-r--r--doc/src/development/developing-on-mac.qdoc5
-rw-r--r--doc/src/frameworks-technologies/accessible.qdoc3
-rw-r--r--doc/src/frameworks-technologies/dbus-adaptors.qdoc3
-rw-r--r--doc/src/frameworks-technologies/phonon.qdoc2
-rw-r--r--doc/src/getting-started/known-issues.qdoc10
-rw-r--r--doc/src/howtos/HWacceleration.qdoc15
-rw-r--r--doc/src/howtos/accelerators.qdoc1
-rw-r--r--doc/src/howtos/appicon.qdoc1
-rw-r--r--doc/src/howtos/guibooks.qdoc1
-rw-r--r--doc/src/howtos/qtdesigner.qdoc1
-rw-r--r--doc/src/howtos/restoring-geometry.qdoc2
-rw-r--r--doc/src/howtos/session.qdoc2
-rw-r--r--doc/src/howtos/sharedlibrary.qdoc2
-rw-r--r--doc/src/howtos/timers.qdoc2
-rw-r--r--doc/src/overviews.qdoc19
-rw-r--r--doc/src/platforms/platform-notes.qdoc2
-rw-r--r--doc/src/sql-programming/qsqldatatype-table.qdoc21
-rw-r--r--doc/src/sql-programming/sql-driver.qdoc2
-rw-r--r--doc/src/sql-programming/sql-programming.qdoc6
-rw-r--r--doc/src/widgets-and-layouts/styles.qdoc12
-rw-r--r--doc/src/widgets-and-layouts/widgets.qdoc202
-rw-r--r--doc/src/windows-and-dialogs/mainwindow.qdoc14
-rw-r--r--examples/declarative/dial/content/Dial.qml6
-rw-r--r--examples/declarative/dial/dial-example.qml10
-rw-r--r--examples/network/bearermonitor/bearermonitor.cpp3
-rw-r--r--examples/network/bearermonitor/sessionwidget.cpp12
-rw-r--r--examples/network/bearermonitor/sessionwidget.h5
-rw-r--r--examples/network/bearermonitor/sessionwidget.ui2
-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/text/qtextdocument.cpp2
-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
-rw-r--r--tests/auto/bic/tst_bic.cpp2
-rw-r--r--tests/auto/qnetworkconfiguration/tst_qnetworkconfiguration.cpp7
-rw-r--r--tests/auto/qnetworksession/lackey/main.cpp24
-rw-r--r--tests/auto/qnetworksession/test/tst_qnetworksession.cpp391
-rw-r--r--tests/auto/qtcpsocket/tst_qtcpsocket.cpp26
-rw-r--r--tests/manual/bearerex/bearerex.cpp18
44 files changed, 1020 insertions, 590 deletions
diff --git a/dist/changes-4.7.0 b/dist/changes-4.7.0
index 6bf7ea5..1e3a69c 100644
--- a/dist/changes-4.7.0
+++ b/dist/changes-4.7.0
@@ -33,7 +33,6 @@ New features
- QNetworkSession, QNetworkConfiguration, QNetworkConfigurationManager
* New bearer management classes added.
-
Third party components
----------------------
@@ -68,6 +67,9 @@ QtGui
functions, and replaced them with setCopyCount(), copyCount() and
supportsMultipleCopies().
+ - QPrintDialog/QPrinter
+ * Added support for printing the current page.
+
- QCommonStyle
* Fixed a bug that led to missing text pixels in QTabBar when using
small font sizes. (QTBUG-7137)
@@ -76,12 +78,30 @@ QtGui
* Fixed rendering bugs when scrolling graphics items with drop
shadows.
+ - QGraphicsItem
+ * [QTBUG-8112] itemChange() is now called when transformation
+ properties change (setRotation, setScale, setTransformOriginPoint).
+
+ - QGraphicsTextItem
+ * [QTBUG-7333] Fixed keyboard shortcuts not being triggered when the
+ the item has focus and something else has the same shortcut sequence.
+
+ - QGraphicsView
+ * [QTBUG-7438] Fixed viewport cursor getting reset when releasing
+ the mouse.
+
- QImage
- * [QTBUG-9640] Prevented unneccessary copy in
- QImage::setAlphaChannel().
- * Added QImage::bitPlaneCount(). (QTBUG-7982)
+ * [QTBUG-9640] Prevented unneccessary copy in QImage::setAlphaChannel().
+ * [QTBUG-7982] Added QImage::bitPlaneCount().
+
+ - QPicture
+ * [QTBUG-4974] Printing QPictures containing text to a high resolution
+ QPrinter would in many cases cause incorrect character spacing.
- QPainter
+ * Added QPainter::drawPixmapFragments(), which makes it possible to draw
+ pixmaps, or sub-rectangles of pixmaps, at various positions with
+ different scale, opacity and rotation.
* [QTBUG-10018] Fixed image drawing inconsistencies when drawing
1x1 source rects with rotating / shear / perspective transforms.
* Optimized various blending and rendering operations for ARM
diff --git a/doc/src/development/developing-on-mac.qdoc b/doc/src/development/developing-on-mac.qdoc
index 785858f..0c0af79 100644
--- a/doc/src/development/developing-on-mac.qdoc
+++ b/doc/src/development/developing-on-mac.qdoc
@@ -41,9 +41,8 @@
/*!
\page developing-on-mac.html
- \title Developing Qt Applications on Mac OS X
- \brief A overview of items to be aware of when developing Qt applications
- on Mac OS X
+ \title Developing Qt Applications for Mac OS X
+ \brief Information for developing Qt applications for Mac OS X
\ingroup platform-specific
\tableofcontents
diff --git a/doc/src/frameworks-technologies/accessible.qdoc b/doc/src/frameworks-technologies/accessible.qdoc
index 35f1c75..0aff214 100644
--- a/doc/src/frameworks-technologies/accessible.qdoc
+++ b/doc/src/frameworks-technologies/accessible.qdoc
@@ -47,7 +47,10 @@
/*!
\page accessible.html
\title Accessibility
+ \brief How to make your applications accessible to those with disabilities.
+
\ingroup technology-apis
+ \ingroup best-practices
\tableofcontents
diff --git a/doc/src/frameworks-technologies/dbus-adaptors.qdoc b/doc/src/frameworks-technologies/dbus-adaptors.qdoc
index 11c5998..3dd0e4d 100644
--- a/doc/src/frameworks-technologies/dbus-adaptors.qdoc
+++ b/doc/src/frameworks-technologies/dbus-adaptors.qdoc
@@ -42,8 +42,9 @@
/*!
\page usingadaptors.html
\title Using QtDBus Adaptors
- \ingroup technology-apis
+ \brief How to create and use DBus adaptors in Qt.
+ \ingroup technology-apis
\ingroup best-practices
Adaptors are special classes that are attached to any QObject-derived class
diff --git a/doc/src/frameworks-technologies/phonon.qdoc b/doc/src/frameworks-technologies/phonon.qdoc
index 61d7926..61b906e 100644
--- a/doc/src/frameworks-technologies/phonon.qdoc
+++ b/doc/src/frameworks-technologies/phonon.qdoc
@@ -42,7 +42,9 @@
/*!
\page phonon-overview.html
\title Phonon multimedia framework
+ \brief Using the Phonon multimedia framework in Qt.
\ingroup technology-apis
+ \ingroup best-practices
\tableofcontents
diff --git a/doc/src/getting-started/known-issues.qdoc b/doc/src/getting-started/known-issues.qdoc
index b73e15d..cedebf9 100644
--- a/doc/src/getting-started/known-issues.qdoc
+++ b/doc/src/getting-started/known-issues.qdoc
@@ -41,15 +41,15 @@
/*!
\page known-issues.html
- \title Known Issues in %VERSION%
+ \title Known Issues in this Qt Version
\ingroup platform-specific
- \brief A summary of known issues in Qt %VERSION% at the time of release.
+ \brief A summary of known issues in this Qt version at the time of release.
- An up-to-date list of known issues with Qt %VERSION% can be found via the
+ An up-to-date list of known issues can be found at
\l{http://bugreports.qt.nokia.com/}{Qt Bug Tracker}.
- For a list list of known bugs in Qt %VERSION%, see the \l{Task Tracker}
- on the Qt website.
+ For a list list of known bugs, see the \l{Task Tracker} at the Qt
+ website.
An overview of known issues may also be found at:
\l{http://qt.gitorious.org/qt/pages/QtKnownIssues}
diff --git a/doc/src/howtos/HWacceleration.qdoc b/doc/src/howtos/HWacceleration.qdoc
index fbc657c..c7b1a72 100644
--- a/doc/src/howtos/HWacceleration.qdoc
+++ b/doc/src/howtos/HWacceleration.qdoc
@@ -41,17 +41,20 @@
/*!
\page HWAcc_rendering.html
- \title Using hardware acceleration on embedded platforms.
+ \title Hardware Acceleration &amp Embedded Platforms.
+ \brief How to use hardware acceleration for fast rendering.
\ingroup best-practices
\section1 Abstract
+
This document describes how to use hardware acceleration for fast
- rendering on embedded platforms supported by Qt. In short, it explains
- how the graphics pipeline works. Since there might be differences to
- how the APIs are being used on different embedded platforms, a table
- links to documentation dedicated to platform specific documentation
- for each supported hardware acceleration API.
+ rendering on embedded platforms supported by Qt. In short, it
+ explains how the graphics pipeline works. Since there might be
+ differences to how the APIs are being used on different embedded
+ platforms, a table links to documentation dedicated to platform
+ specific documentation for each supported hardware acceleration
+ API.
\input platforms/emb-hardwareacceleration.qdocinc
diff --git a/doc/src/howtos/accelerators.qdoc b/doc/src/howtos/accelerators.qdoc
index 65f1def..b6ef5c2 100644
--- a/doc/src/howtos/accelerators.qdoc
+++ b/doc/src/howtos/accelerators.qdoc
@@ -42,6 +42,7 @@
/*!
\page accelerators.html
\title Standard Accelerator Keys
+ \brief Recommended accelerator keys.
\ingroup best-practices
diff --git a/doc/src/howtos/appicon.qdoc b/doc/src/howtos/appicon.qdoc
index dd39509..9377961 100644
--- a/doc/src/howtos/appicon.qdoc
+++ b/doc/src/howtos/appicon.qdoc
@@ -42,6 +42,7 @@
/*!
\page appicon.html
\title Setting the Application Icon
+ \brief How to set your application's icon.
\ingroup best-practices
diff --git a/doc/src/howtos/guibooks.qdoc b/doc/src/howtos/guibooks.qdoc
index 1a70670..bccfbe6 100644
--- a/doc/src/howtos/guibooks.qdoc
+++ b/doc/src/howtos/guibooks.qdoc
@@ -43,6 +43,7 @@
\page guibooks.html
\title Books about GUI Design
\ingroup best-practices
+ \brief Some recommended books about GUI design.
This is not a comprehensive list -- there are many other books worth
buying. Here we mention just a few user interface books that don't
diff --git a/doc/src/howtos/qtdesigner.qdoc b/doc/src/howtos/qtdesigner.qdoc
index 2dd7fcf..92041f0 100644
--- a/doc/src/howtos/qtdesigner.qdoc
+++ b/doc/src/howtos/qtdesigner.qdoc
@@ -42,6 +42,7 @@
/*!
\page qtdesigner-components.html
\title Creating and Using Components for Qt Designer
+ \brief How to create and use custom widget plugins.
\ingroup best-practices
\tableofcontents
diff --git a/doc/src/howtos/restoring-geometry.qdoc b/doc/src/howtos/restoring-geometry.qdoc
index 36c5e4f..e72b993 100644
--- a/doc/src/howtos/restoring-geometry.qdoc
+++ b/doc/src/howtos/restoring-geometry.qdoc
@@ -42,7 +42,7 @@
/*!
\page restoring-geometry.html
\title Restoring a Window's Geometry
-
+ \brief How to save &amp restore window geometry.
\ingroup best-practices
This document describes how to save and restore a \l{Window
diff --git a/doc/src/howtos/session.qdoc b/doc/src/howtos/session.qdoc
index e2e87a8..f53af04 100644
--- a/doc/src/howtos/session.qdoc
+++ b/doc/src/howtos/session.qdoc
@@ -42,7 +42,7 @@
/*!
\page session.html
\title Session Management
-
+ \brief How to do session management with Qt.
\ingroup best-practices
A \e session is a group of running applications, each of which has a
diff --git a/doc/src/howtos/sharedlibrary.qdoc b/doc/src/howtos/sharedlibrary.qdoc
index 70fc4db..ed803ed 100644
--- a/doc/src/howtos/sharedlibrary.qdoc
+++ b/doc/src/howtos/sharedlibrary.qdoc
@@ -42,7 +42,7 @@
/*!
\page sharedlibrary.html
\title Creating Shared Libraries
-
+ \brief How to create shared libraries.
\ingroup best-practices
The following sections list certain things that should be taken into
diff --git a/doc/src/howtos/timers.qdoc b/doc/src/howtos/timers.qdoc
index cfc2fb4..b001916 100644
--- a/doc/src/howtos/timers.qdoc
+++ b/doc/src/howtos/timers.qdoc
@@ -42,7 +42,7 @@
/*!
\page timers.html
\title Timers
- \brief How to use timers in your application.
+ \brief How to use Qt timers in your application.
\ingroup best-practices
diff --git a/doc/src/overviews.qdoc b/doc/src/overviews.qdoc
index 0b82388..c3c59af 100644
--- a/doc/src/overviews.qdoc
+++ b/doc/src/overviews.qdoc
@@ -117,13 +117,28 @@
*/
/*!
+ \group qt-sql
+ \title Using SQL in Qt
+ \brief Qt API's for using SQL.
+ \ingroup technology-apis
+ \ingroup best-practices
+
+ These pages document Qt's API's for using SQL database systems
+ in Qt applications.
+
+ \generatelist{related}
+*/
+
+/*!
\group best-practices
\title How-To's and Best Practices
\brief How-To Guides and Best Practices
- These documents provide guidelines and best practices explaining
- how to use Qt to solve specific technical problems.
+ These documents provide guidelines and best practices for using Qt
+ to solve specific technical problems. They are listed
+ alphabetically by the first word in the title, so scan the entire
+ list to find what you want.
\generatelist{related}
*/
diff --git a/doc/src/platforms/platform-notes.qdoc b/doc/src/platforms/platform-notes.qdoc
index 8f5b6a5..16e0c0f 100644
--- a/doc/src/platforms/platform-notes.qdoc
+++ b/doc/src/platforms/platform-notes.qdoc
@@ -517,7 +517,7 @@
Note that some modules rely on other modules. If your application uses
QtXmlPatterns, QtWebkit or QtScript it may still require \c NetworkServices
- \o as these modules rely on QtNetwork to go online.
+ as these modules rely on QtNetwork to go online.
For more information see the documentation of the individual Qt classes. If
a class does not mention Symbian capabilities, it requires none.
diff --git a/doc/src/sql-programming/qsqldatatype-table.qdoc b/doc/src/sql-programming/qsqldatatype-table.qdoc
index fc961f5..fb5fb49 100644
--- a/doc/src/sql-programming/qsqldatatype-table.qdoc
+++ b/doc/src/sql-programming/qsqldatatype-table.qdoc
@@ -41,19 +41,20 @@
/*!
\page sql-types.html
- \title Recommended Use of Data Types in Databases
+ \title Data Types for Qt-supported Database Systems
+ \brief Recommended data types for database systems
- \ingroup best-practices
+ \ingroup qt-sql
- \section1 Recommended Use of Types in Qt Supported Databases
+ \section1 Data Types for Qt Supported Database Systems
- This table shows the recommended data types used when extracting data
- from the databases supported in Qt. It is important to note that the
- types used in Qt are not necessarily valid as input to the specific
- database. One example could be that a double would work perfectly as
- input for floating point records in a database, but not necessarily
- as a storage format for output from the database since it would be stored
- with 64-bit precision in C++.
+ This table shows the recommended data types for extracting data from
+ the databases supported in Qt. Note that types used in Qt are not
+ necessarily valid as input types to a specific database
+ system. e.g., A double might work perfectly as input for floating
+ point records in a particular database, but not necessarily as a
+ storage format for output from that database, because it would be
+ stored with 64-bit precision in C++.
\tableofcontents
diff --git a/doc/src/sql-programming/sql-driver.qdoc b/doc/src/sql-programming/sql-driver.qdoc
index 6bccd83..f0e4e52 100644
--- a/doc/src/sql-programming/sql-driver.qdoc
+++ b/doc/src/sql-programming/sql-driver.qdoc
@@ -44,7 +44,7 @@
\title SQL Database Drivers
\brief How to configure and install QtSql drivers for supported databases.
- \ingroup best-practices
+ \ingroup qt-sql
The QtSql module uses driver \l{How to Create Qt
Plugins}{plugins} to communicate with the different database
diff --git a/doc/src/sql-programming/sql-programming.qdoc b/doc/src/sql-programming/sql-programming.qdoc
index f1f3e5e..b34810c 100644
--- a/doc/src/sql-programming/sql-programming.qdoc
+++ b/doc/src/sql-programming/sql-programming.qdoc
@@ -49,6 +49,7 @@
/*!
\page sql-programming.html
\title SQL Programming
+ \ingroup qt-sql
\nextpage Connecting to Databases
\brief Database integration for Qt applications.
@@ -118,6 +119,7 @@
/*!
\page sql-connecting.html
\title Connecting to Databases
+ \ingroup qt-sql
\contentspage SQL Programming
\previouspage SQL Programming
@@ -187,6 +189,7 @@
/*!
\page sql-sqlstatements.html
\title Executing SQL Statements
+ \ingroup qt-sql
\previouspage Connecting to Databases
\contentspage SQL Programming
@@ -337,6 +340,7 @@
/*!
\page sql-model.html
\title Using the SQL Model Classes
+ \ingroup qt-sql
\previouspage Executing SQL Statements
\contentspage SQL Programming
@@ -483,6 +487,7 @@
/*!
\page sql-presenting.html
\title Presenting Data in a Table View
+ \ingroup qt-sql
\previouspage Using the SQL Model Classes
\contentspage SQL Programming
@@ -587,6 +592,7 @@
/*!
\page sql-forms.html
\title Creating Data-Aware Forms
+ \ingroup qt-sql
\previouspage Presenting Data in a Table View
\contentspage SQL Programming
diff --git a/doc/src/widgets-and-layouts/styles.qdoc b/doc/src/widgets-and-layouts/styles.qdoc
index b4bec8c..31dfe40 100644
--- a/doc/src/widgets-and-layouts/styles.qdoc
+++ b/doc/src/widgets-and-layouts/styles.qdoc
@@ -47,15 +47,9 @@
/*!
\page style-reference.html
- \title Implementing Styles and Style Aware Widgets
+ \title Styles and Style Aware Widgets
\ingroup qt-gui-concepts
- \brief An overview of styles and the styling of widgets.
-
- \ingroup frameworks-technologies
-
- \previouspage Widget Classes
- \contentspage Widgets and Layouts
- \nextpage {Qt Style Sheets}{Style sheets}
+ \brief Styles and the styling of widgets.
Styles (classes that inherit QStyle) draw on behalf of widgets
and encapsulate the look and feel of a GUI. The QStyle class is
@@ -91,8 +85,6 @@
current style. This document shows how widgets draw themselves
and which possibilities the style gives them.
- \tableofcontents
-
\section1 Classes for Widget Styling
These classes are used to customize an application's appearance and
diff --git a/doc/src/widgets-and-layouts/widgets.qdoc b/doc/src/widgets-and-layouts/widgets.qdoc
index ac0bf77..9fe2d69 100644
--- a/doc/src/widgets-and-layouts/widgets.qdoc
+++ b/doc/src/widgets-and-layouts/widgets.qdoc
@@ -40,131 +40,121 @@
****************************************************************************/
/*!
- \page widgets-and-layouts.html
- \title Widgets and Layouts
- \ingroup qt-gui-concepts
-
- \ingroup frameworks-technologies
-
- \nextpage Widget Classes
-
- The primary elements for designing user interfaces in Qt are widgets and layouts.
-
- \section1 Widgets
-
- \l{Widget Classes}{Widgets} can display data and status information, receive
- user input, and provide a container for other widgets that should be grouped
- together. A widget that is not embedded in a parent widget is called a
- \l{Application Windows and Dialogs}{window}.
-
- \image parent-child-widgets.png A parent widget containing various child widgets.
-
- The QWidget class provides the basic capability to render to the screen, and to
- handle user input events. All UI elements that Qt provides are either subclasses
- of QWidget, or are used in connection with a QWidget subclass. Creating custom
- widgets is done by subclassing QWidget or a suitable subclass and reimplementing
- the virtual event handlers.
-
- \section1 Layouts
-
- \l{Layout Management}{Layouts} are an elegant and flexible way to automatically
- arrange child widgets within their container. Each widget reports its size requirements
- to the layout through the \l{QWidget::}{sizeHint} and \l{QWidget::}{sizePolicy}
- properties, and the layout distributes the available space accordingly.
-
- \table
- \row
- \o \image qgridlayout-with-5-children.png
- \o \image qformlayout-with-6-children.png
- \endtable
-
- \l{Qt Designer Manual}{\QD} is a powerful tool for interactively creating and
- arranging widgets in layouts.
-
- \section1 Widget Styles
-
- \l{Implementing Styles and Style Aware Widgets}{Styles} draw on behalf of widgets
- and encapsulate the look and feel of a GUI. Qt's built-in widgets use the QStyle
- class to perform nearly all of their drawing, ensuring that they look exactly like
- the equivalent native widgets.
+ \page widgets-and-layouts.html
+ \title Widgets and Layouts
+ \ingroup qt-gui-concepts
+ \brief The primary elements for designing user interfaces in Qt.
+
+ \section1 Widgets
+
+ Widgets are the primary elements for creating user interfaces in Qt.
+ \l{Widget Classes}{Widgets} can display data and status information,
+ receive user input, and provide a container for other widgets that
+ should be grouped together. A widget that is not embedded in a
+ parent widget is called a \l{Application Windows and
+ Dialogs}{window}.
+
+ \image parent-child-widgets.png A parent widget containing various child widgets.
+
+ The QWidget class provides the basic capability to render to the
+ screen, and to handle user input events. All UI elements that Qt
+ provides are either subclasses of QWidget, or are used in connection
+ with a QWidget subclass. Creating custom widgets is done by
+ subclassing QWidget or a suitable subclass and reimplementing the
+ virtual event handlers.
+
+ \section1 Layouts
+
+ \l{Layout Management}{Layouts} are an elegant and flexible way to
+ automatically arrange child widgets within their container. Each
+ widget reports its size requirements to the layout through the
+ \l{QWidget::}{sizeHint} and \l{QWidget::}{sizePolicy} properties,
+ and the layout distributes the available space accordingly.
+
+ \table
+ \row
+ \o \image qgridlayout-with-5-children.png
+ \o \image qformlayout-with-6-children.png
+ \endtable
+
+ \l{Qt Designer Manual}{\QD} is a powerful tool for interactively creating and
+ arranging widgets in layouts.
+
+ \section1 Widget Styles
+
+ \l{Implementing Styles and Style Aware Widgets}{Styles} draw on
+ behalf of widgets and encapsulate the look and feel of a GUI. Qt's
+ built-in widgets use the QStyle class to perform nearly all of their
+ drawing, ensuring that they look exactly like the equivalent native
+ widgets.
- \table
- \row
- \o \image windowsxp-tabwidget.png
- \o \image plastique-tabwidget.png
- \o \image macintosh-tabwidget.png
- \endtable
-
- \l{Qt Style Sheets} are a powerful mechanism that allows you to customize the
- appearance of widgets, in addition to what is already possible by subclassing QStyle.
-*/
-
-/*!
- \page widget-classes.html
- \title Widget Classes
+ \table
+ \row
+ \o \image windowsxp-tabwidget.png
+ \o \image plastique-tabwidget.png
+ \o \image macintosh-tabwidget.png
+ \endtable
- \contentspage Widgets and Layouts
- \nextpage Layout Management
+ \l{Qt Style Sheets} are a powerful mechanism that allows you to customize the
+ appearance of widgets, in addition to what is already possible by subclassing QStyle.
- Below you find a list of all widget classes in Qt. You can also browse the
- widget classes Qt provides in the various supported styles in the
- \l{Qt Widget Gallery}.
+ \section1 The Widget Classes
- \tableofcontents
+ The following sections list the widget classes. See the \l{Qt Widget
+ Gallery} for some examples.
- \section1 Basic Widgets
+ \section2 Basic Widgets
- These basic widgets (controls), such as buttons, comboboxes and scroll bars, are
- designed for direct use.
+ These basic widgets (controls), e.g. buttons, comboboxes and
+ scroll bars, are designed for direct use.
- \table
- \row
- \o \image windows-label.png
- \o \image windowsvista-pushbutton.png
- \o \image gtk-progressbar.png
- \row
- \o \image plastique-combobox.png
- \o \image macintosh-radiobutton.png
- \o \image cde-lineedit.png
- \endtable
+ \table
+ \row
+ \o \image windows-label.png
+ \o \image windowsvista-pushbutton.png
+ \o \image gtk-progressbar.png
+ \row
+ \o \image plastique-combobox.png
+ \o \image macintosh-radiobutton.png
+ \o \image cde-lineedit.png
+ \endtable
- \annotatedlist basicwidgets
+ \annotatedlist basicwidgets
- \section1 Advanced Widgets
+ \section2 Advanced Widgets
- Advanced GUI widgets such as tab widgets and progress bars provide more
- complex user interface controls.
+ Advanced GUI widgets, e.g. tab widgets and progress bars, provide
+ more complex user interface controls.
- \table
- \row
- \o \image windowsxp-treeview.png
- \o \image gtk-calendarwidget.png
- \o \image qundoview.png
- \endtable
+ \table
+ \row
+ \o \image windowsxp-treeview.png
+ \o \image gtk-calendarwidget.png
+ \o \image qundoview.png
+ \endtable
- \annotatedlist advanced
+ \annotatedlist advanced
- \table
- \row
- \o \image windowsvista-tabwidget.png
- \o \image macintosh-groupbox.png
- \endtable
+ \table
+ \row
+ \o \image windowsvista-tabwidget.png
+ \o \image macintosh-groupbox.png
+ \endtable
- \section1 Organizer Widgets
+ \section2 Organizer Widgets
- Classes like splitters, tab bars, button groups, etc are used to
- organize and group GUI primitives into more complex applications or
- dialogs.
+ Classes like splitters, tab bars, button groups, etc are used for
+ organizing and grouping GUI primitives into more complex
+ applications and dialogs.
- \annotatedlist organizers
+ \annotatedlist organizers
- \section1 Abstract Widget Classes
+ \section2 Abstract Widget Classes
- Abstract widget classes usable through subclassing. They are generally
- not usable in themselves, but provide functionality that can be used
- by inheriting these classes.
+ The abstract widget classes are base classes. They are not usable as
+ standalone classes but provide functionality when they are subclassed.
- \annotatedlist abstractwidgets
+ \annotatedlist abstractwidgets
*/
/*!
diff --git a/doc/src/windows-and-dialogs/mainwindow.qdoc b/doc/src/windows-and-dialogs/mainwindow.qdoc
index b282dab..c1e66d9 100644
--- a/doc/src/windows-and-dialogs/mainwindow.qdoc
+++ b/doc/src/windows-and-dialogs/mainwindow.qdoc
@@ -46,12 +46,11 @@
/*!
\page application-windows.html
- \title Application Windows and Dialogs
+ \title Window and Dialog Widgets
+ \brief Windows and Dialogs in Qt.
\ingroup qt-gui-concepts
\ingroup frameworks-technologies
- \nextpage The Application Main Window
-
A \l{Widgets Tutorial}{widget} that is not embedded in a parent widget is called a window.
Usually, windows have a frame and a title bar, although it is also possible to create
windows without such decoration using suitable window flags). In Qt, QMainWindow
@@ -165,12 +164,9 @@
/*!
\page mainwindow.html
- \title The Application Main Window
- \brief Everything you need for a typical modern main application window,
- including menus, toolbars, workspace, etc.
-
- \contentspage Application Windows and Dialogs
- \nextpage Dialog Windows
+ \title Application Main Window
+ \ingroup qt-gui-concepts
+ \brief Creating the application window.
\tableofcontents
diff --git a/examples/declarative/dial/content/Dial.qml b/examples/declarative/dial/content/Dial.qml
index f9ab3e3..6f24801 100644
--- a/examples/declarative/dial/content/Dial.qml
+++ b/examples/declarative/dial/content/Dial.qml
@@ -8,6 +8,7 @@ Item {
Image { source: "background.png" }
+//! [needle_shadow]
Image {
x: 93
y: 35
@@ -17,6 +18,8 @@ Item {
angle: needleRotation.angle
}
}
+//! [needle_shadow]
+//! [needle]
Image {
id: needle
x: 95; y: 33
@@ -33,5 +36,8 @@ Item {
}
}
}
+//! [needle]
+//! [overlay]
Image { x: 21; y: 18; source: "overlay.png" }
+//! [overlay]
}
diff --git a/examples/declarative/dial/dial-example.qml b/examples/declarative/dial/dial-example.qml
index 2e102b0..900954f 100644
--- a/examples/declarative/dial/dial-example.qml
+++ b/examples/declarative/dial/dial-example.qml
@@ -1,6 +1,7 @@
import Qt 4.7
import "content"
+//! [0]
Rectangle {
color: "#545454"
width: 300; height: 300
@@ -14,7 +15,10 @@ Rectangle {
Rectangle {
id: container
- anchors { bottom: parent.bottom; left: parent.left; right: parent.right; leftMargin: 20; rightMargin: 20; bottomMargin: 10 }
+ anchors { bottom: parent.bottom; left: parent.left
+ right: parent.right; leftMargin: 20; rightMargin: 20
+ bottomMargin: 10
+ }
height: 16
radius: 8
@@ -37,8 +41,10 @@ Rectangle {
MouseArea {
anchors.fill: parent
- drag.target: parent; drag.axis: Drag.XAxis; drag.minimumX: 2; drag.maximumX: container.width - 32
+ drag.target: parent; drag.axis: Drag.XAxis
+ drag.minimumX: 2; drag.maximumX: container.width - 32
}
}
}
}
+//! [0] \ No newline at end of file
diff --git a/examples/network/bearermonitor/bearermonitor.cpp b/examples/network/bearermonitor/bearermonitor.cpp
index 4a6c6ff..0d98eff 100644
--- a/examples/network/bearermonitor/bearermonitor.cpp
+++ b/examples/network/bearermonitor/bearermonitor.cpp
@@ -255,6 +255,7 @@ void BearerMonitor::onlineStateChanged(bool isOnline)
void BearerMonitor::registerNetwork()
{
QTreeWidgetItem *item = treeWidget->currentItem();
+ if (!item) return;
QNetworkConfiguration configuration =
manager.configurationFromIdentifier(item->data(0, Qt::UserRole).toString());
@@ -276,6 +277,7 @@ void BearerMonitor::registerNetwork()
void BearerMonitor::unregisterNetwork()
{
QTreeWidgetItem *item = treeWidget->currentItem();
+ if (!item) return;
QNetworkConfiguration configuration =
manager.configurationFromIdentifier(item->data(0, Qt::UserRole).toString());
@@ -384,6 +386,7 @@ void BearerMonitor::createSessionFor(QTreeWidgetItem *item)
void BearerMonitor::createNewSession()
{
QTreeWidgetItem *item = treeWidget->currentItem();
+ if (!item) return;
createSessionFor(item);
}
diff --git a/examples/network/bearermonitor/sessionwidget.cpp b/examples/network/bearermonitor/sessionwidget.cpp
index 443f4b2..3a8e5ea 100644
--- a/examples/network/bearermonitor/sessionwidget.cpp
+++ b/examples/network/bearermonitor/sessionwidget.cpp
@@ -59,7 +59,7 @@ SessionWidget::SessionWidget(const QNetworkConfiguration &config, QWidget *paren
connect(session, SIGNAL(stateChanged(QNetworkSession::State)),
this, SLOT(updateSession()));
connect(session, SIGNAL(error(QNetworkSession::SessionError)),
- this, SLOT(updateSession()));
+ this, SLOT(updateSessionError(QNetworkSession::SessionError)));
updateSession();
@@ -105,7 +105,6 @@ void SessionWidget::deleteSession()
void SessionWidget::updateSession()
{
updateSessionState(session->state());
- updateSessionError(session->error());
if (session->state() == QNetworkSession::Connected)
statsTimer = startTimer(1000);
@@ -128,12 +127,14 @@ void SessionWidget::updateSession()
void SessionWidget::openSession()
{
+ clearError();
session->open();
updateSession();
}
void SessionWidget::openSyncSession()
{
+ clearError();
session->open();
session->waitForOpened();
updateSession();
@@ -141,12 +142,14 @@ void SessionWidget::openSyncSession()
void SessionWidget::closeSession()
{
+ clearError();
session->close();
updateSession();
}
void SessionWidget::stopSession()
{
+ clearError();
session->stop();
updateSession();
}
@@ -195,3 +198,8 @@ void SessionWidget::updateSessionError(QNetworkSession::SessionError error)
errorString->setText(session->errorString());
}
+void SessionWidget::clearError()
+{
+ lastError->clear();
+ errorString->clear();
+}
diff --git a/examples/network/bearermonitor/sessionwidget.h b/examples/network/bearermonitor/sessionwidget.h
index 5e9d62c..b299b47 100644
--- a/examples/network/bearermonitor/sessionwidget.h
+++ b/examples/network/bearermonitor/sessionwidget.h
@@ -63,7 +63,7 @@ public:
private:
void updateSessionState(QNetworkSession::State state);
- void updateSessionError(QNetworkSession::SessionError error);
+ void clearError();
private Q_SLOTS:
void openSession();
@@ -71,9 +71,12 @@ private Q_SLOTS:
void closeSession();
void stopSession();
void updateSession();
+ void updateSessionError(QNetworkSession::SessionError error);
#if defined(Q_WS_MAEMO_5) || defined(Q_WS_MAEMO_6)
void deleteSession();
#endif
+
+
private:
QNetworkSession *session;
int statsTimer;
diff --git a/examples/network/bearermonitor/sessionwidget.ui b/examples/network/bearermonitor/sessionwidget.ui
index 45135f5..56a2d0e 100644
--- a/examples/network/bearermonitor/sessionwidget.ui
+++ b/examples/network/bearermonitor/sessionwidget.ui
@@ -195,7 +195,7 @@
<item>
<widget class="QLabel" name="errorStringLabel">
<property name="text">
- <string>Error String</string>
+ <string>Error String:</string>
</property>
</widget>
</item>
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/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp
index afba678..c7a9756 100644
--- a/src/gui/text/qtextdocument.cpp
+++ b/src/gui/text/qtextdocument.cpp
@@ -1947,7 +1947,7 @@ QVariant QTextDocument::loadResource(int type, const QUrl &name)
#endif
// handle data: URLs
- if (r.isNull() && name.scheme() == QLatin1String("data"))
+ if (r.isNull() && name.scheme().compare(QLatin1String("data"), Qt::CaseInsensitive) == 0)
r = qDecodeDataUrl(name).second;
// if resource was not loaded try to load it here
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;
diff --git a/tests/auto/bic/tst_bic.cpp b/tests/auto/bic/tst_bic.cpp
index 010965c..400fcc1 100644
--- a/tests/auto/bic/tst_bic.cpp
+++ b/tests/auto/bic/tst_bic.cpp
@@ -191,7 +191,7 @@ void tst_Bic::sizesAndVTables_data()
#elif defined Q_OS_MAC && defined(__i386__)
# define FILESUFFIX "macx-gcc-ia32"
#elif defined Q_OS_MAC && defined(__amd64__)
-# define FILESUFFIX "macx-gcc-amd64";
+# define FILESUFFIX "macx-gcc-amd64"
#elif defined Q_OS_WIN && defined Q_CC_GNU
# define FILESUFFIX "win32-gcc-ia32"
#else
diff --git a/tests/auto/qnetworkconfiguration/tst_qnetworkconfiguration.cpp b/tests/auto/qnetworkconfiguration/tst_qnetworkconfiguration.cpp
index ce3acb7..a3cccb2 100644
--- a/tests/auto/qnetworkconfiguration/tst_qnetworkconfiguration.cpp
+++ b/tests/auto/qnetworkconfiguration/tst_qnetworkconfiguration.cpp
@@ -45,6 +45,13 @@
#include <QtNetwork/qnetworkconfiguration.h>
#include <QtNetwork/qnetworkconfigmanager.h>
+/*
+ Although this unit test doesn't use QNetworkAccessManager
+ this include is used to ensure that bearer continues to compile against
+ Qt 4.7+ which has a QNetworkConfiguration enabled QNetworkAccessManager
+*/
+#include <QNetworkAccessManager>
+
#if defined(Q_WS_MAEMO_6) || defined(Q_WS_MAEMO_5)
#include <stdio.h>
#include <iapconf.h>
diff --git a/tests/auto/qnetworksession/lackey/main.cpp b/tests/auto/qnetworksession/lackey/main.cpp
index 8759b52..ec2fad9 100644
--- a/tests/auto/qnetworksession/lackey/main.cpp
+++ b/tests/auto/qnetworksession/lackey/main.cpp
@@ -47,6 +47,8 @@
#include <QtNetwork/qnetworkconfigmanager.h>
#include <QtNetwork/qnetworksession.h>
+#include <QEventLoop>
+#include <QTimer>
#include <QDebug>
QT_USE_NAMESPACE
@@ -60,15 +62,14 @@ int main(int argc, char** argv)
{
QCoreApplication app(argc, argv);
- // Cannot read/write to processes on WinCE or Symbian.
- // Easiest alternative is to use sockets for IPC.
-
- QLocalSocket oopSocket;
-
- oopSocket.connectToServer("tst_qnetworksession");
- oopSocket.waitForConnected(-1);
-
+ // Update configurations so that everything is up to date for this process too.
+ // Event loop is used to wait for awhile.
QNetworkConfigurationManager manager;
+ manager.updateConfigurations();
+ QEventLoop iIgnoreEventLoop;
+ QTimer::singleShot(3000, &iIgnoreEventLoop, SLOT(quit()));
+ iIgnoreEventLoop.exec();
+
QList<QNetworkConfiguration> discovered =
manager.allConfigurations(QNetworkConfiguration::Discovered);
@@ -82,6 +83,13 @@ int main(int argc, char** argv)
return NO_DISCOVERED_CONFIGURATIONS_ERROR;
}
+ // Cannot read/write to processes on WinCE or Symbian.
+ // Easiest alternative is to use sockets for IPC.
+ QLocalSocket oopSocket;
+
+ oopSocket.connectToServer("tst_qnetworksession");
+ oopSocket.waitForConnected(-1);
+
qDebug() << "Lackey started";
QNetworkSession *session = 0;
diff --git a/tests/auto/qnetworksession/test/tst_qnetworksession.cpp b/tests/auto/qnetworksession/test/tst_qnetworksession.cpp
index 23cdc6a..934a50e 100644
--- a/tests/auto/qnetworksession/test/tst_qnetworksession.cpp
+++ b/tests/auto/qnetworksession/test/tst_qnetworksession.cpp
@@ -100,6 +100,7 @@ private slots:
private:
QNetworkConfigurationManager manager;
+ QMap<QString, bool> testsToRun;
int inProcessSessionManagementCount;
@@ -117,6 +118,7 @@ private:
bool openSession(QNetworkSession *session);
bool closeSession(QNetworkSession *session, bool lastSessionOnConfiguration = true);
void updateConfigurations();
+void printConfigurations();
QNetworkConfiguration suitableConfiguration(QString bearerType, QNetworkConfiguration::Type configType);
void tst_QNetworkSession::initTestCase()
@@ -125,7 +127,19 @@ void tst_QNetworkSession::initTestCase()
qRegisterMetaType<QNetworkSession::SessionError>("QNetworkSession::SessionError");
qRegisterMetaType<QNetworkConfiguration>("QNetworkConfiguration");
qRegisterMetaType<QNetworkConfiguration::Type>("QNetworkConfiguration::Type");
-
+
+ // If you wish to skip tests, set value as false. This is often very convinient because tests are so lengthy.
+ // Better way still would be to make this readable from a file.
+ testsToRun["robustnessBombing"] = true;
+ testsToRun["outOfProcessSession"] = true;
+ testsToRun["invalidSession"] = true;
+ testsToRun["repeatedOpenClose"] = true;
+ testsToRun["roamingErrorCodes"] = true;
+ testsToRun["sessionStop"] = true;
+ testsToRun["sessionProperties"] = true;
+ testsToRun["userChoiceSession"] = true;
+ testsToRun["sessionOpenCloseStop"] = true;
+
#if defined(Q_WS_MAEMO_6) || defined(Q_WS_MAEMO_5)
iapconf = new Maemo::IAPConf("007");
iapconf->setValue("ipv4_type", "AUTO");
@@ -238,6 +252,10 @@ void tst_QNetworkSession::cleanupTestCase()
// Robustness test for calling interfaces in nonsense order / with nonsense parameters
void tst_QNetworkSession::robustnessBombing()
{
+ if (!testsToRun["robustnessBombing"]) {
+ QSKIP("Temporary skip due to value set false (or it is missing) in testsToRun map", SkipAll);
+ }
+
QNetworkConfigurationManager mgr;
QNetworkSession testSession(mgr.defaultConfiguration());
// Should not reset even session is not opened
@@ -245,15 +263,14 @@ void tst_QNetworkSession::robustnessBombing()
testSession.accept();
testSession.ignore();
testSession.reject();
- quint64 temp;
- temp = testSession.bytesWritten();
- temp = testSession.bytesReceived();
- temp = testSession.activeTime();
}
void tst_QNetworkSession::invalidSession()
-{
+{
+ if (!testsToRun["invalidSession"]) {
+ QSKIP("Temporary skip due to value set false (or it is missing) in testsToRun map", SkipAll);
+ }
// 1. Verify that session created with invalid configuration remains in invalid state
QNetworkSession session(QNetworkConfiguration(), 0);
QVERIFY(!session.isOpen());
@@ -270,11 +287,24 @@ void tst_QNetworkSession::invalidSession()
QVERIFY(error == QNetworkSession::InvalidConfigurationError);
QVERIFY(session.error() == QNetworkSession::InvalidConfigurationError);
QVERIFY(session.state() == QNetworkSession::Invalid);
-
+
#ifdef QNETWORKSESSION_MANUAL_TESTS
+
+ QNetworkConfiguration invalidatedConfig = suitableConfiguration("WLAN",QNetworkConfiguration::InternetAccessPoint);
+ if (invalidatedConfig.isValid()) {
+ // 3. Verify that invalidating a session after its successfully configured works
+ QNetworkSession invalidatedSession(invalidatedConfig);
+ qDebug() << "Delete the WLAN IAP from phone now (waiting 60 seconds): " << invalidatedConfig.name();
+ QTest::qWait(60000);
+ QVERIFY(!invalidatedConfig.isValid());
+ QVERIFY(invalidatedSession.state() == QNetworkSession::Invalid);
+ qDebug() << "Add the WLAN IAP back (waiting 60 seconds): " << invalidatedConfig.name();
+ QTest::qWait(60000);
+ }
+
QNetworkConfiguration definedConfig = suitableConfiguration("WLAN",QNetworkConfiguration::InternetAccessPoint);
if (definedConfig.isValid()) {
- // 3. Verify that opening a session with defined configuration emits error and enters notavailable-state
+ // 4. Verify that opening a session with defined configuration emits error and enters notavailable-state
// TODO these timer waits should be changed to waiting appropriate signals, now these wait excessively
qDebug() << "Shutdown WLAN IAP (waiting 60 seconds): " << definedConfig.name();
QTest::qWait(60000);
@@ -283,43 +313,27 @@ void tst_QNetworkSession::invalidSession()
QNetworkSession definedSession(definedConfig);
QSignalSpy errorSpy(&definedSession, SIGNAL(error(QNetworkSession::SessionError)));
QNetworkSession::SessionError sessionError;
+ updateConfigurations();
definedSession.open();
+#ifdef Q_OS_SYMBIAN
+ // On symbian, the connection opening is tried even with defined state.
+ qDebug("Waiting for 10 seconds to all signals to propagate.");
+ QTest::qWait(10000);
+#endif
+ updateConfigurations();
QVERIFY(definedConfig.isValid()); // Session remains valid
QVERIFY(definedSession.state() == QNetworkSession::NotAvailable); // State is not available because WLAN is not in coverage
QVERIFY(!errorSpy.isEmpty()); // Session tells with error about invalidated configuration
sessionError = qvariant_cast<QNetworkSession::SessionError> (errorSpy.first().at(0));
- qDebug() << "Error code is: " << sessionError;
QVERIFY(sessionError == QNetworkSession::InvalidConfigurationError);
-
qDebug() << "Turn the WLAN IAP back on (waiting 60 seconds): " << definedConfig.name();
QTest::qWait(60000);
- updateConfigurations();
-
+ updateConfigurations();
QVERIFY(definedConfig.state() == QNetworkConfiguration::Discovered);
}
-
- QNetworkConfiguration invalidatedConfig = suitableConfiguration("WLAN",QNetworkConfiguration::InternetAccessPoint);
- if (invalidatedConfig.isValid()) {
- // 4. Verify that invalidating a session after its successfully configured works
- QNetworkSession invalidatedSession(invalidatedConfig);
- QSignalSpy errorSpy(&invalidatedSession, SIGNAL(error(QNetworkSession::SessionError)));
- QNetworkSession::SessionError sessionError;
-
- qDebug() << "Delete the WLAN IAP from phone now (waiting 60 seconds): " << invalidatedConfig.name();
- QTest::qWait(60000);
-
- invalidatedSession.open();
- QVERIFY(!invalidatedConfig.isValid());
- QVERIFY(invalidatedSession.state() == QNetworkSession::Invalid);
- QVERIFY(!errorSpy.isEmpty());
-
- sessionError = qvariant_cast<QNetworkSession::SessionError> (errorSpy.first().at(0));
- QVERIFY(sessionError == QNetworkSession::InvalidConfigurationError);
- qDebug() << "Add the WLAN IAP back (waiting 60 seconds): " << invalidatedConfig.name();
- QTest::qWait(60000);
- }
+
#endif
}
@@ -337,12 +351,12 @@ void tst_QNetworkSession::sessionProperties_data()
void tst_QNetworkSession::sessionProperties()
{
+ if (!testsToRun["sessionProperties"]) {
+ QSKIP("Temporary skip due to value set false (or it is missing) in testsToRun map", SkipAll);
+ }
QFETCH(QNetworkConfiguration, configuration);
-
QNetworkSession session(configuration);
-
QVERIFY(session.configuration() == configuration);
-
QStringList validBearerNames = QStringList() << QLatin1String("Unknown")
<< QLatin1String("Ethernet")
<< QLatin1String("WLAN")
@@ -356,9 +370,6 @@ void tst_QNetworkSession::sessionProperties()
if (!configuration.isValid()) {
QVERIFY(configuration.bearerName().isEmpty());
} else {
- qDebug() << "Type:" << configuration.type()
- << "Bearer:" << configuration.bearerName();
-
switch (configuration.type())
{
case QNetworkConfiguration::ServiceNetwork:
@@ -374,9 +385,7 @@ void tst_QNetworkSession::sessionProperties()
// QNetworkSession::interface() should return an invalid interface unless
// session is in the connected state.
- qDebug() << "Session state:" << session.state();
#ifndef QT_NO_NETWORKINTERFACE
- qDebug() << "Session iface:" << session.interface().isValid() << session.interface().name();
#if !(defined(Q_OS_SYMBIAN) && defined(__WINS__))
// On Symbian emulator, the support for data bearers is limited
QCOMPARE(session.state() == QNetworkSession::Connected, session.interface().isValid());
@@ -420,7 +429,12 @@ void tst_QNetworkSession::repeatedOpenClose_data() {
}
// Tests repeated-open close.
-void tst_QNetworkSession::repeatedOpenClose() {
+void tst_QNetworkSession::repeatedOpenClose()
+{
+ if (!testsToRun["repeatedOpenClose"]) {
+ QSKIP("Temporary skip due to value set false (or it is missing) in testsToRun map", SkipAll);
+ }
+
QFETCH(QString, bearerType);
QFETCH(QNetworkConfiguration::Type, configurationType);
QFETCH(int, repeatTimes);
@@ -436,13 +450,20 @@ void tst_QNetworkSession::repeatedOpenClose() {
!closeSession(&permanentSession)) {
QSKIP("Unable to open/close session, skipping this round of repeated open-close test.", SkipSingle);
}
- for (int i = repeatTimes; i > 0; i--) {
+ for (int i = 0; i < repeatTimes; i++) {
+ qDebug() << "Opening, loop number " << i;
QVERIFY(openSession(&permanentSession));
+ qDebug() << "Closing, loop number, then waiting 5 seconds: " << i;
QVERIFY(closeSession(&permanentSession));
+ QTest::qWait(5000);
}
}
-void tst_QNetworkSession::roamingErrorCodes() {
+void tst_QNetworkSession::roamingErrorCodes()
+{
+ if (!testsToRun["roamingErrorCodes"]) {
+ QSKIP("Temporary skip due to value set false (or it is missing) in testsToRun map", SkipAll);
+ }
#ifndef Q_OS_SYMBIAN
QSKIP("Roaming supported on Symbian.", SkipAll);
#else
@@ -466,41 +487,11 @@ void tst_QNetworkSession::roamingErrorCodes() {
adminIapSession.stop(); // requires NetworkControl capabilities
QTRY_VERIFY(!errorSpy.isEmpty()); // wait for error signals
QNetworkSession::SessionError error = qvariant_cast<QNetworkSession::SessionError>(errorSpy.first().at(0));
+ QTest::qWait(2000); // Wait for a moment to all platform signals to propagate
QVERIFY(error == QNetworkSession::SessionAbortedError);
QVERIFY(iapSession.state() == QNetworkSession::Disconnected);
QVERIFY(adminIapSession.state() == QNetworkSession::Disconnected);
#endif // Q_OS_SYMBIAN
-
-#ifdef QNETWORKSESSION_MANUAL_TESTS
- // Check for roaming error.
- // Case requires that you have controllable WLAN in Internet SNAP (only).
- QNetworkConfiguration snapConfig = suitableConfiguration("bearer_not_relevant_with_snaps", QNetworkConfiguration::ServiceNetwork);
- if (!snapConfig.isValid()) {
- QSKIP("No SNAP accessible, skipping test.", SkipAll);
- }
- QNetworkSession snapSession(snapConfig);
- QVERIFY(openSession(&snapSession));
- QSignalSpy errorSpySnap(&snapSession, SIGNAL(error(QNetworkSession::SessionError)));
- qDebug("Disconnect the WLAN now");
- QTRY_VERIFY(!errorSpySnap.isEmpty()); // wait for error signals
- QVERIFY(errorSpySnap.count() == 1);
- error = qvariant_cast<QNetworkSession::SessionError>(errorSpySnap.first().at(0));
- qDebug() << "Error received when turning off wlan on SNAP: " << error;
- QVERIFY(error == QNetworkSession::RoamingError);
-
- qDebug("Connect the WLAN now");
- QTest::qWait(60000); // Wait for WLAN to get up
- QNetworkConfiguration wlanIapConfig2 = suitableConfiguration("WLAN", QNetworkConfiguration::InternetAccessPoint);
- QNetworkSession iapSession2(wlanIapConfig2);
- QVERIFY(openSession(&iapSession2));
- QSignalSpy errorSpy2(&iapSession2, SIGNAL(error(QNetworkSession::SessionError)));
- qDebug("Disconnect the WLAN now");
- QTRY_VERIFY(!errorSpy2.isEmpty()); // wait for error signals
- QVERIFY(errorSpy2.count() == 1);
- error = qvariant_cast<QNetworkSession::SessionError>(errorSpy2.first().at(0));
- QVERIFY(error == QNetworkSession::SessionAbortedError);
- QVERIFY(iapSession2.state() == QNetworkSession::Disconnected);
-#endif
}
@@ -515,6 +506,9 @@ void tst_QNetworkSession::sessionStop_data() {
void tst_QNetworkSession::sessionStop()
{
+ if (!testsToRun["sessionStop"]) {
+ QSKIP("Temporary skip due to value set false (or it is missing) in testsToRun map", SkipAll);
+ }
#ifndef Q_OS_SYMBIAN
QSKIP("Testcase contains mainly Symbian specific checks, because it is only platform to really support interface (IAP-level) Stop.", SkipAll);
#endif
@@ -522,6 +516,9 @@ void tst_QNetworkSession::sessionStop()
QFETCH(QNetworkConfiguration::Type, configurationType);
int configWaitdelayInMs = 2000;
+
+ updateConfigurations();
+ printConfigurations();
QNetworkConfiguration config = suitableConfiguration(bearerType, configurationType);
if (!config.isValid()) {
@@ -539,6 +536,9 @@ void tst_QNetworkSession::sessionStop()
QSignalSpy closedSessionStateChangedSpy(&closedSession, SIGNAL(stateChanged(QNetworkSession::State)));
QSignalSpy closedErrorSpy(&closedSession, SIGNAL(error(QNetworkSession::SessionError)));
+ QSignalSpy openedSessionClosedSpy(&openedSession, SIGNAL(closed()));
+ QSignalSpy openedSessionStateChangedSpy(&openedSession, SIGNAL(stateChanged(QNetworkSession::State)));
+
QSignalSpy innocentSessionClosedSpy(&innocentSession, SIGNAL(closed()));
QSignalSpy innocentSessionStateChangedSpy(&innocentSession, SIGNAL(stateChanged(QNetworkSession::State)));
QSignalSpy innocentErrorSpy(&innocentSession, SIGNAL(error(QNetworkSession::SessionError)));
@@ -554,10 +554,18 @@ void tst_QNetworkSession::sessionStop()
closedSessionClosedSpy.clear();
closedSessionStateChangedSpy.clear();
closedErrorSpy.clear();
+ openedSessionStateChangedSpy.clear();
+ openedSessionClosedSpy.clear();
+
openedSession.stop();
- QVERIFY(openedSession.state() == QNetworkSession::Disconnected);
+ qDebug("Waiting for %d ms to get all configurationChange signals from platform.", configWaitdelayInMs);
QTest::qWait(configWaitdelayInMs); // Wait to get all relevant configurationChange() signals
+
+ // First to closing, then to disconnected
+ QVERIFY(openedSessionStateChangedSpy.count() == 2);
+ QVERIFY(!openedSessionClosedSpy.isEmpty());
+ QVERIFY(openedSession.state() == QNetworkSession::Disconnected);
QVERIFY(config.state() != QNetworkConfiguration::Active);
// 2. Verify that stopping a session based on non-connected configuration does nothing
@@ -583,18 +591,20 @@ void tst_QNetworkSession::sessionStop()
// 3. Check that stopping a opened session affects also other opened session based on the same configuration.
if (config.type() == QNetworkConfiguration::InternetAccessPoint) {
qDebug("----------3. Check that stopping a opened session affects also other opened session based on the same configuration.");
+
QVERIFY(openSession(&openedSession));
QVERIFY(openSession(&innocentSession));
-
+
configChangeSpy.clear();
innocentSessionClosedSpy.clear();
innocentSessionStateChangedSpy.clear();
innocentErrorSpy.clear();
-
+
openedSession.stop();
qDebug("Waiting for %d ms to get all configurationChange signals from platform.", configWaitdelayInMs);
QTest::qWait(configWaitdelayInMs); // Wait to get all relevant configurationChange() signals
-
+ QTest::qWait(configWaitdelayInMs); // Wait to get all relevant configurationChange() signals
+
QVERIFY(!innocentSessionClosedSpy.isEmpty());
QVERIFY(!innocentSessionStateChangedSpy.isEmpty());
QVERIFY(!innocentErrorSpy.isEmpty());
@@ -614,14 +624,19 @@ void tst_QNetworkSession::sessionStop()
if (config.type() == QNetworkConfiguration::ServiceNetwork) {
qDebug("----------4. Skip for SNAP configuration.");
} else if (config.type() == QNetworkConfiguration::InternetAccessPoint) {
- qDebug("----------4. Check that stopping a non-opened session stops the other session based on the same configuration");
- QVERIFY(openSession(&innocentSession));
+ qDebug("----------4. Check that stopping a non-opened session stops the other session based on the same configuration");
+ qDebug("----------4.1 Opening innocent session");
+ QVERIFY(openSession(&innocentSession));
qDebug("Waiting for %d ms after open to make sure all platform indications are propagated", configWaitdelayInMs);
QTest::qWait(configWaitdelayInMs);
+ qDebug("----------4.2 Calling closedSession.stop()");
closedSession.stop();
qDebug("Waiting for %d ms to get all configurationChange signals from platform..", configWaitdelayInMs);
QTest::qWait(configWaitdelayInMs); // Wait to get all relevant configurationChange() signals
+ QTest::qWait(configWaitdelayInMs);
+ QTest::qWait(configWaitdelayInMs);
+
QVERIFY(!innocentSessionClosedSpy.isEmpty());
QVERIFY(!innocentSessionStateChangedSpy.isEmpty());
QVERIFY(!innocentErrorSpy.isEmpty());
@@ -653,6 +668,9 @@ void tst_QNetworkSession::userChoiceSession_data()
void tst_QNetworkSession::userChoiceSession()
{
+ if (!testsToRun["userChoiceSession"]) {
+ QSKIP("Temporary skip due to value set false (or it is missing) in testsToRun map", SkipAll);
+ }
QFETCH(QNetworkConfiguration, configuration);
QVERIFY(configuration.type() == QNetworkConfiguration::UserChoice);
@@ -682,7 +700,20 @@ void tst_QNetworkSession::userChoiceSession()
session.open();
+#if defined(Q_OS_SYMBIAN)
+ // Opening & closing multiple connections in a row sometimes
+ // results hanging of connection opening on Symbian devices
+ // => If first open fails, wait a moment and try again.
+ if (!session.waitForOpened()) {
+ qDebug("**** Session open Timeout - Wait 5 seconds and try once again ****");
+ session.close();
+ QTest::qWait(5000); // Wait a while before trying to open session again
+ session.open();
+ session.waitForOpened();
+ }
+#else
session.waitForOpened();
+#endif
if (session.isOpen())
QVERIFY(!sessionOpenedSpy.isEmpty() || !errorSpy.isEmpty());
@@ -786,6 +817,9 @@ void tst_QNetworkSession::sessionOpenCloseStop_data()
void tst_QNetworkSession::sessionOpenCloseStop()
{
+ if (!testsToRun["sessionOpenCloseStop"]) {
+ QSKIP("Temporary skip due to value set false (or it is missing) in testsToRun map", SkipAll);
+ }
QFETCH(QNetworkConfiguration, configuration);
QFETCH(bool, forceSessionStop);
@@ -818,7 +852,20 @@ void tst_QNetworkSession::sessionOpenCloseStop()
session.open();
+#if defined(Q_OS_SYMBIAN)
+ // Opening & closing multiple connections in a row sometimes
+ // results hanging of connection opening on Symbian devices
+ // => If first open fails, wait a moment and try again.
+ if (!session.waitForOpened()) {
+ qDebug("**** Session open Timeout - Wait 5 seconds and try once again ****");
+ session.close();
+ QTest::qWait(5000); // Wait a while before trying to open session again
+ session.open();
+ session.waitForOpened();
+ }
+#else
session.waitForOpened();
+#endif
if (session.isOpen())
QVERIFY(!sessionOpenedSpy.isEmpty() || !errorSpy.isEmpty());
@@ -894,26 +941,30 @@ void tst_QNetworkSession::sessionOpenCloseStop()
QVERIFY(session.error() == QNetworkSession::UnknownSessionError);
session2.open();
-
+
QTRY_VERIFY(!sessionOpenedSpy2.isEmpty() || !errorSpy2.isEmpty());
+ if (errorSpy2.isEmpty()) {
+ QVERIFY(session2.isOpen());
+ QVERIFY(session2.state() == QNetworkSession::Connected);
+ }
QVERIFY(session.isOpen());
- QVERIFY(session2.isOpen());
QVERIFY(session.state() == QNetworkSession::Connected);
- QVERIFY(session2.state() == QNetworkSession::Connected);
#ifndef QT_NO_NETWORKINTERFACE
#if !(defined(Q_OS_SYMBIAN) && defined(__WINS__))
// On Symbian emulator, the support for data bearers is limited
QVERIFY(session.interface().isValid());
#endif
- QCOMPARE(session.interface().hardwareAddress(), session2.interface().hardwareAddress());
- QCOMPARE(session.interface().index(), session2.interface().index());
+ if (errorSpy2.isEmpty()) {
+ QCOMPARE(session.interface().hardwareAddress(), session2.interface().hardwareAddress());
+ QCOMPARE(session.interface().index(), session2.interface().index());
+ }
#endif
}
sessionOpenedSpy2.clear();
- if (forceSessionStop) {
+ if (forceSessionStop && session2.isOpen()) {
// Test forcing the second session to stop the interface.
QNetworkSession::State previousState = session.state();
#ifdef Q_CC_NOKIAX86
@@ -922,15 +973,17 @@ void tst_QNetworkSession::sessionOpenCloseStop()
#else
bool expectStateChange = previousState != QNetworkSession::Disconnected;
#endif
-
session2.stop();
+ // QNetworkSession::stop() must result either closed() signal
+ // or error() signal
QTRY_VERIFY(!sessionClosedSpy2.isEmpty() || !errorSpy2.isEmpty());
-
QVERIFY(!session2.isOpen());
if (!errorSpy2.isEmpty()) {
- QVERIFY(!errorSpy.isEmpty());
+ // QNetworkSession::stop() resulted error() signal for session2
+ // => also session should emit error() signal
+ QTRY_VERIFY(!errorSpy.isEmpty());
// check for SessionAbortedError
QNetworkSession::SessionError error =
@@ -950,9 +1003,12 @@ void tst_QNetworkSession::sessionOpenCloseStop()
QVERIFY(errorSpy.isEmpty());
QVERIFY(errorSpy2.isEmpty());
-
+
+ // Wait for Disconnected state
+ QTRY_NOOP(session2.state() == QNetworkSession::Disconnected);
+
if (expectStateChange)
- QTRY_VERIFY(stateChangedSpy2.count() >= 2 || !errorSpy2.isEmpty());
+ QTRY_VERIFY(stateChangedSpy2.count() >= 1 || !errorSpy2.isEmpty());
if (!errorSpy2.isEmpty()) {
QVERIFY(session2.state() == previousState);
@@ -996,16 +1052,29 @@ void tst_QNetworkSession::sessionOpenCloseStop()
state = qvariant_cast<QNetworkSession::State>(stateChangedSpy2.at(3).at(0));
QVERIFY(state == QNetworkSession::Disconnected);
+
+ QTRY_VERIFY(session.state() == QNetworkSession::Roaming ||
+ session.state() == QNetworkSession::Connected ||
+ session.state() == QNetworkSession::Disconnected);
+
QTRY_VERIFY(stateChangedSpy.count() > 0);
- state = qvariant_cast<QNetworkSession::State>(stateChangedSpy.at(0).at(0));
+ state = qvariant_cast<QNetworkSession::State>(stateChangedSpy.at(stateChangedSpy.count() - 1).at(0));
+
if (state == QNetworkSession::Roaming) {
- QTRY_VERIFY(!errorSpy.isEmpty() || stateChangedSpy.count() > 1);
- if (stateChangedSpy.count() > 1 &&
- qvariant_cast<QNetworkSession::State>(stateChangedSpy.at(1).at(0)) ==
- QNetworkSession::Connected) {
- roamedSuccessfully = true;
+ QTRY_VERIFY(session.state() == QNetworkSession::Connected);
+ QTRY_VERIFY(session2.state() == QNetworkSession::Connected);
+ roamedSuccessfully = true;
+ } else if (state == QNetworkSession::Disconnected) {
+ QTRY_VERIFY(!errorSpy.isEmpty());
+ QTRY_VERIFY(session2.state() == QNetworkSession::Disconnected);
+ } else if (state == QNetworkSession::Connected) {
+ QTRY_VERIFY(errorSpy.isEmpty());
+ if (stateChangedSpy.count() > 1) {
+ state = qvariant_cast<QNetworkSession::State>(stateChangedSpy.at(stateChangedSpy.count() - 2).at(0));
+ QVERIFY(state == QNetworkSession::Roaming);
}
- }
+ roamedSuccessfully = true;
+ }
if (roamedSuccessfully) {
QString configId = session.sessionProperty("ActiveConfiguration").toString();
@@ -1013,37 +1082,36 @@ void tst_QNetworkSession::sessionOpenCloseStop()
QNetworkSession session3(config);
QSignalSpy errorSpy3(&session3, SIGNAL(error(QNetworkSession::SessionError)));
QSignalSpy sessionOpenedSpy3(&session3, SIGNAL(opened()));
-
session3.open();
- session3.waitForOpened();
-
+ session3.waitForOpened();
if (session.isOpen())
QVERIFY(!sessionOpenedSpy3.isEmpty() || !errorSpy3.isEmpty());
-
session.stop();
-
QTRY_VERIFY(session.state() == QNetworkSession::Disconnected);
- QTRY_VERIFY(session3.state() == QNetworkSession::Disconnected);
}
#ifndef Q_CC_NOKIAX86
if (!roamedSuccessfully)
QVERIFY(!errorSpy.isEmpty());
#endif
} else {
- QCOMPARE(stateChangedSpy2.count(), 2);
-
- QNetworkSession::State state =
- qvariant_cast<QNetworkSession::State>(stateChangedSpy2.at(0).at(0));
- QVERIFY(state == QNetworkSession::Closing);
-
- state = qvariant_cast<QNetworkSession::State>(stateChangedSpy2.at(1).at(0));
- QVERIFY(state == QNetworkSession::Disconnected);
+ QTest::qWait(2000); // Wait awhile to get all signals from platform
+
+ if (stateChangedSpy2.count() == 2) {
+ QNetworkSession::State state =
+ qvariant_cast<QNetworkSession::State>(stateChangedSpy2.at(0).at(0));
+ QVERIFY(state == QNetworkSession::Closing);
+ state = qvariant_cast<QNetworkSession::State>(stateChangedSpy2.at(1).at(0));
+ QVERIFY(state == QNetworkSession::Disconnected);
+ } else { // Assume .count() == 1
+ QCOMPARE(stateChangedSpy2.count(), 1);
+ QNetworkSession::State state = qvariant_cast<QNetworkSession::State>(stateChangedSpy2.at(0).at(0));
+ // Symbian version dependant.
+ QVERIFY(state == QNetworkSession::Disconnected);
+ }
}
QTRY_VERIFY(!sessionClosedSpy.isEmpty());
-
QTRY_VERIFY(session.state() == QNetworkSession::Disconnected);
- QTRY_VERIFY(session2.state() == QNetworkSession::Disconnected);
}
QVERIFY(errorSpy2.isEmpty());
@@ -1062,7 +1130,7 @@ void tst_QNetworkSession::sessionOpenCloseStop()
QVERIFY(!session.isOpen());
#endif
QVERIFY(!session2.isOpen());
- } else {
+ } else if (session2.isOpen()) {
// Test closing the second session.
{
int stateChangedCountBeforeClose = stateChangedSpy2.count();
@@ -1161,11 +1229,15 @@ QDebug operator<<(QDebug debug, const QList<QNetworkConfiguration> &list)
// at Discovered -state.
void tst_QNetworkSession::outOfProcessSession()
{
- qDebug() << "START";
-
+ if (!testsToRun["outOfProcessSession"]) {
+ QSKIP("Temporary skip due to value set false (or it is missing) in testsToRun map", SkipAll);
+ }
#if defined(Q_OS_SYMBIAN) && defined(__WINS__)
QSKIP("Symbian emulator does not support two [QR]PRocesses linking a dll (QtBearer.dll) with global writeable static data.", SkipAll);
#endif
+ updateConfigurations();
+ QTest::qWait(2000);
+
QNetworkConfigurationManager manager;
// Create a QNetworkConfigurationManager to detect configuration changes made in Lackey. This
// is actually the essence of this testcase - to check that platform mediates/reflects changes
@@ -1182,16 +1254,15 @@ void tst_QNetworkSession::outOfProcessSession()
QLocalServer::removeServer("tst_qnetworksession");
oopServer.listen("tst_qnetworksession");
- qDebug() << "starting lackey";
QProcess lackey;
lackey.start("lackey/lackey");
qDebug() << lackey.error() << lackey.errorString();
QVERIFY(lackey.waitForStarted());
- qDebug() << "waiting for connection";
+
QVERIFY(oopServer.waitForNewConnection(-1));
QLocalSocket *oopSocket = oopServer.nextPendingConnection();
- qDebug() << "got connection";
+
do {
QByteArray output;
@@ -1258,7 +1329,6 @@ void tst_QNetworkSession::outOfProcessSession()
default:
QSKIP("Lackey failed", SkipAll);
}
- qDebug("STOP");
}
// A convinience / helper function for testcases. Return the first matching configuration.
@@ -1269,6 +1339,7 @@ QNetworkConfiguration suitableConfiguration(QString bearerType, QNetworkConfigur
// Refresh configurations and derive configurations matching given parameters.
QNetworkConfigurationManager mgr;
QSignalSpy updateSpy(&mgr, SIGNAL(updateCompleted()));
+
mgr.updateConfigurations();
QTRY_NOOP(updateSpy.count() == 1);
if (updateSpy.count() != 1) {
@@ -1277,8 +1348,7 @@ QNetworkConfiguration suitableConfiguration(QString bearerType, QNetworkConfigur
}
QList<QNetworkConfiguration> discoveredConfigs = mgr.allConfigurations(QNetworkConfiguration::Discovered);
foreach(QNetworkConfiguration config, discoveredConfigs) {
- if ((config.state() & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) {
- // qDebug() << "Dumping config because is active: " << config.name();
+ if ((config.state() & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) {
discoveredConfigs.removeOne(config);
} else if (config.type() != configType) {
// qDebug() << "Dumping config because type (IAP/SNAP) mismatches: " << config.name();
@@ -1315,9 +1385,23 @@ void updateConfigurations()
QTRY_NOOP(updateSpy.count() == 1);
}
+// A convinience-function: updates and prints all available confiurations and their states
+void printConfigurations()
+{
+ QNetworkConfigurationManager manager;
+ QList<QNetworkConfiguration> allConfigs =
+ manager.allConfigurations();
+ qDebug("tst_QNetworkSession::printConfigurations QNetworkConfigurationManager gives following configurations: ");
+ foreach(QNetworkConfiguration config, allConfigs) {
+ qDebug() << "Name of the configuration: " << config.name();
+ qDebug() << "State of the configuration: " << config.state();
+ }
+}
+
// A convinience function for test-cases: opens the given configuration and return
// true if it was done gracefully.
bool openSession(QNetworkSession *session) {
+ bool result = true;
QNetworkConfigurationManager mgr;
QSignalSpy openedSpy(session, SIGNAL(opened()));
QSignalSpy stateChangeSpy(session, SIGNAL(stateChanged(QNetworkSession::State)));
@@ -1327,43 +1411,57 @@ bool openSession(QNetworkSession *session) {
// active by some other session
QNetworkConfiguration::StateFlags configInitState = session->configuration().state();
QNetworkSession::State sessionInitState = session->state();
+ qDebug() << "tst_QNetworkSession::openSession() name of the configuration to be opened: " << session->configuration().name();
+ qDebug() << "tst_QNetworkSession::openSession() state of the configuration to be opened: " << session->configuration().state();
+ qDebug() << "tst_QNetworkSession::openSession() state of the session to be opened: " << session->state();
if (session->isOpen() ||
!session->sessionProperty("ActiveConfiguration").toString().isEmpty()) {
qDebug("tst_QNetworkSession::openSession() failure: session was already open / active.");
- return false;
+ result = false;
} else {
session->open();
session->waitForOpened(120000); // Bringing interfaces up and down may take time at platform
}
+ QTest::qWait(5000); // Wait a moment to ensure all signals are propagated
// Check that connection opening went by the book. Add checks here if more strictness needed.
if (!session->isOpen()) {
qDebug("tst_QNetworkSession::openSession() failure: QNetworkSession::open() failed.");
- return false;
+ result = false;
}
if (openedSpy.count() != 1) {
qDebug("tst_QNetworkSession::openSession() failure: QNetworkSession::opened() - signal not received.");
- return false;
+ result = false;
}
if (!errorSpy.isEmpty()) {
qDebug("tst_QNetworkSession::openSession() failure: QNetworkSession::error() - signal was detected.");
- return false;
+ result = false;
}
if (sessionInitState != QNetworkSession::Connected &&
stateChangeSpy.isEmpty()) {
qDebug("tst_QNetworkSession::openSession() failure: QNetworkSession::stateChanged() - signals not detected.");
- return false;
+ result = false;
}
if (configInitState != QNetworkConfiguration::Active &&
configChangeSpy.isEmpty()) {
qDebug("tst_QNetworkSession::openSession() failure: QNetworkConfigurationManager::configurationChanged() - signals not detected.");
- return false;
+ result = false;
}
if (session->configuration().state() != QNetworkConfiguration::Active) {
qDebug("tst_QNetworkSession::openSession() failure: session's configuration is not in 'Active' -state.");
- return false;
+ qDebug() << "tst_QNetworkSession::openSession() state is: " << session->configuration().state();
+ result = false;
+ }
+ if (result == false) {
+ qDebug() << "tst_QNetworkSession::openSession() opening session failed.";
+ } else {
+ qDebug() << "tst_QNetworkSession::openSession() opening session succeeded.";
}
- return true;
+ qDebug() << "tst_QNetworkSession::openSession() name of the configuration is: " << session->configuration().name();
+ qDebug() << "tst_QNetworkSession::openSession() configuration state is: " << session->configuration().state();
+ qDebug() << "tst_QNetworkSession::openSession() session state is: " << session->state();
+
+ return result;
}
// Helper function for closing opened session. Performs checks that
@@ -1376,6 +1474,11 @@ bool closeSession(QNetworkSession *session, bool lastSessionOnConfiguration) {
qDebug("tst_QNetworkSession::closeSession() failure: NULL session given");
return false;
}
+
+ qDebug() << "tst_QNetworkSession::closeSession() name of the configuration to be closed: " << session->configuration().name();
+ qDebug() << "tst_QNetworkSession::closeSession() state of the configuration to be closed: " << session->configuration().state();
+ qDebug() << "tst_QNetworkSession::closeSession() state of the session to be closed: " << session->state();
+
if (session->state() != QNetworkSession::Connected ||
!session->isOpen()) {
qDebug("tst_QNetworkSession::closeSession() failure: session is not opened.");
@@ -1387,38 +1490,48 @@ bool closeSession(QNetworkSession *session, bool lastSessionOnConfiguration) {
QSignalSpy sessionErrorSpy(session, SIGNAL(error(QNetworkSession::SessionError)));
QSignalSpy configChangeSpy(&mgr, SIGNAL(configurationChanged(QNetworkConfiguration)));
+ bool result = true;
session->close();
+ QTest::qWait(5000); // Wait a moment so that all signals are propagated
if (!sessionErrorSpy.isEmpty()) {
qDebug("tst_QNetworkSession::closeSession() failure: QNetworkSession::error() received.");
- return false;
+ result = false;
}
if (sessionClosedSpy.count() != 1) {
qDebug("tst_QNetworkSession::closeSession() failure: QNetworkSession::closed() signal not received.");
- return false;
+ result = false;
}
if (lastSessionOnConfiguration &&
sessionStateChangedSpy.isEmpty()) {
qDebug("tst_QNetworkSession::closeSession() failure: QNetworkSession::stateChanged() signals not received.");
- return false;
+ result = false;
}
if (lastSessionOnConfiguration &&
session->state() != QNetworkSession::Disconnected) {
qDebug("tst_QNetworkSession::closeSession() failure: QNetworkSession is not in Disconnected -state");
- return false;
+ result = false;
}
QTRY_NOOP(!configChangeSpy.isEmpty());
if (lastSessionOnConfiguration &&
configChangeSpy.isEmpty()) {
qDebug("tst_QNetworkSession::closeSession() failure: QNetworkConfigurationManager::configurationChanged() - signal not detected.");
- return false;
+ result = false;
}
if (lastSessionOnConfiguration &&
session->configuration().state() == QNetworkConfiguration::Active) {
qDebug("tst_QNetworkSession::closeSession() failure: session's configuration is still in active state.");
- return false;
+ result = false;
}
- return true;
+ if (result == false) {
+ qDebug() << "tst_QNetworkSession::closeSession() closing session failed.";
+ } else {
+ qDebug() << "tst_QNetworkSession::closeSession() closing session succeeded.";
+ }
+ qDebug() << "tst_QNetworkSession::closeSession() name of the configuration is: " << session->configuration().name();
+ qDebug() << "tst_QNetworkSession::closeSession() configuration state is: " << session->configuration().state();
+ qDebug() << "tst_QNetworkSession::closeSession() session state is: " << session->state();
+ return result;
}
void tst_QNetworkSession::sessionAutoClose_data()
diff --git a/tests/auto/qtcpsocket/tst_qtcpsocket.cpp b/tests/auto/qtcpsocket/tst_qtcpsocket.cpp
index cd512a1..31cae40 100644
--- a/tests/auto/qtcpsocket/tst_qtcpsocket.cpp
+++ b/tests/auto/qtcpsocket/tst_qtcpsocket.cpp
@@ -144,6 +144,7 @@ private slots:
void blockingIMAP();
void nonBlockingIMAP();
void hostNotFound();
+ void timeoutConnect_data();
void timeoutConnect();
void delayedClose();
void partialRead();
@@ -544,19 +545,36 @@ void tst_QTcpSocket::hostNotFound()
}
//----------------------------------------------------------------------------------
+void tst_QTcpSocket::timeoutConnect_data()
+{
+ QTest::addColumn<QString>("address");
+ QTest::newRow("host") << QtNetworkSettings::serverName();
+ QTest::newRow("ip") << QtNetworkSettings::serverIP().toString();
+}
void tst_QTcpSocket::timeoutConnect()
{
+ QFETCH(QString, address);
QTcpSocket *socket = newSocket();
- // Outgoing port 53 is firewalled in the Oslo office.
- socket->connectToHost("cisco.com", 53);
+ QElapsedTimer timer;
+ timer.start();
+
+ // Port 1357 is configured to drop packets on the test server
+ socket->connectToHost(address, 1357);
+ QVERIFY(timer.elapsed() < 50);
QVERIFY(!socket->waitForConnected(200));
QCOMPARE(socket->state(), QTcpSocket::UnconnectedState);
QCOMPARE(int(socket->error()), int(QTcpSocket::SocketTimeoutError));
- socket->connectToHost("cisco.com", 53);
- QTest::qSleep(50);
+ timer.start();
+ socket->connectToHost(address, 1357);
+ QVERIFY(timer.elapsed() < 50);
+ QTimer::singleShot(50, &QTestEventLoop::instance(), SLOT(exitLoop()));
+ QTestEventLoop::instance().enterLoop(5);
+ QVERIFY(!QTestEventLoop::instance().timeout());
+ QVERIFY(socket->state() == QTcpSocket::ConnectingState
+ || socket->state() == QTcpSocket::HostLookupState);
socket->abort();
QCOMPARE(socket->state(), QTcpSocket::UnconnectedState);
QCOMPARE(socket->openMode(), QIODevice::NotOpen);
diff --git a/tests/manual/bearerex/bearerex.cpp b/tests/manual/bearerex/bearerex.cpp
index 19246a2..bf60dd1 100644
--- a/tests/manual/bearerex/bearerex.cpp
+++ b/tests/manual/bearerex/bearerex.cpp
@@ -300,8 +300,12 @@ 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;
}
void SessionTab::on_createQHttpButton_clicked()
@@ -551,10 +555,16 @@ void SessionTab::done(bool error)
msgBox.setText(QString("HTTP request finished successfully.\nReceived ")+QString::number(result.length())+QString(" bytes."));
}
msgBox.exec();
-
- sentRecDataLineEdit->setText(QString::number(m_NetworkSession->bytesWritten())+
- QString(" / ")+
- QString::number(m_NetworkSession->bytesReceived()));
+ // 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
+ // trigger the done() invokation).
+ if (m_NetworkSession) {
+ sentRecDataLineEdit->setText(QString::number(m_NetworkSession->bytesWritten())+
+ QString(" / ")+
+ QString::number(m_NetworkSession->bytesReceived()));
+ } else {
+ sentRecDataLineEdit->setText("Data amounts not available.");
+ }
}
// End of file