Merge lp:~dandrader/qtmir/surfaceItemFillMode into lp:qtmir

Proposed by Daniel d'Andrada
Status: Superseded
Proposed branch: lp:~dandrader/qtmir/surfaceItemFillMode
Merge into: lp:qtmir
Prerequisite: lp:~unity-team/qtmir/multimonitorNext
Diff against target: 4413 lines (+2255/-802)
73 files modified
CMakeLists.txt (+2/-4)
debian/changelog (+7/-0)
debian/control (+2/-2)
src/modules/Unity/Application/application.cpp (+42/-9)
src/modules/Unity/Application/application.h (+7/-0)
src/modules/Unity/Application/application_manager.cpp (+52/-12)
src/modules/Unity/Application/application_manager.h (+3/-0)
src/modules/Unity/Application/mirbuffersgtexture.cpp (+18/-10)
src/modules/Unity/Application/mirsurface.cpp (+40/-18)
src/modules/Unity/Application/mirsurface.h (+12/-1)
src/modules/Unity/Application/mirsurfaceinterface.h (+6/-0)
src/modules/Unity/Application/mirsurfaceitem.cpp (+49/-5)
src/modules/Unity/Application/mirsurfaceitem.h (+9/-0)
src/modules/Unity/Application/session.cpp (+40/-2)
src/modules/Unity/Application/session.h (+1/-0)
src/modules/Unity/Application/session_interface.h (+1/-0)
tests/CMakeLists.txt (+1/-0)
tests/framework/CMakeLists.txt (+48/-0)
tests/framework/fake_desktopfilereader.cpp (+68/-0)
tests/framework/fake_desktopfilereader.h (+22/-21)
tests/framework/fake_mirsurface.cpp (+212/-0)
tests/framework/fake_mirsurface.h (+56/-137)
tests/framework/fake_session.cpp (+113/-0)
tests/framework/fake_session.h (+35/-57)
tests/framework/mock_application_controller.cpp (+129/-0)
tests/framework/mock_application_controller.h (+22/-99)
tests/framework/mock_desktop_file_reader.cpp (+117/-0)
tests/framework/mock_desktop_file_reader.h (+20/-85)
tests/framework/mock_display.cpp (+35/-0)
tests/framework/mock_display.h (+6/-2)
tests/framework/mock_display_configuration.cpp (+25/-0)
tests/framework/mock_display_configuration.h (+4/-0)
tests/framework/mock_gl_display_buffer.cpp (+30/-0)
tests/framework/mock_gl_display_buffer.h (+3/-9)
tests/framework/mock_main_loop.cpp (+28/-0)
tests/framework/mock_main_loop.h (+5/-8)
tests/framework/mock_mir_session.cpp (+63/-0)
tests/framework/mock_mir_session.h (+13/-20)
tests/framework/mock_proc_info.cpp (+35/-0)
tests/framework/mock_proc_info.h (+8/-7)
tests/framework/mock_prompt_session.cpp (+33/-0)
tests/framework/mock_prompt_session.h (+3/-0)
tests/framework/mock_prompt_session_manager.cpp (+33/-0)
tests/framework/mock_prompt_session_manager.h (+3/-0)
tests/framework/mock_renderable.cpp (+33/-0)
tests/framework/mock_renderable.h (+2/-1)
tests/framework/mock_session.cpp (+69/-0)
tests/framework/mock_session.h (+8/-30)
tests/framework/mock_settings.cpp (+40/-0)
tests/framework/mock_settings.h (+7/-11)
tests/framework/mock_shared_wakelock.cpp (+61/-0)
tests/framework/mock_shared_wakelock.h (+8/-33)
tests/framework/mock_surface.cpp (+39/-0)
tests/framework/mock_surface.h (+5/-4)
tests/framework/qtmir_test.cpp (+98/-1)
tests/framework/qtmir_test.h (+14/-106)
tests/framework/stub_input_channel.cpp (+52/-0)
tests/framework/stub_input_channel.h (+8/-18)
tests/framework/stub_scene_surface.cpp (+103/-0)
tests/framework/stub_scene_surface.h (+41/-49)
tests/mirserver/Screen/CMakeLists.txt (+1/-1)
tests/mirserver/ScreenController/CMakeLists.txt (+4/-1)
tests/modules/Application/CMakeLists.txt (+12/-6)
tests/modules/ApplicationManager/CMakeLists.txt (+7/-5)
tests/modules/ApplicationManager/application_manager_test.cpp (+155/-0)
tests/modules/DesktopFileReader/CMakeLists.txt (+0/-6)
tests/modules/SessionManager/CMakeLists.txt (+6/-4)
tests/modules/SessionManager/session_manager_test.cpp (+5/-5)
tests/modules/SessionManager/session_test.cpp (+5/-5)
tests/modules/SharedWakelock/CMakeLists.txt (+0/-1)
tests/modules/SurfaceManager/CMakeLists.txt (+4/-4)
tests/modules/SurfaceManager/mirsurfaceitem_test.cpp (+1/-1)
tests/modules/TaskController/CMakeLists.txt (+6/-2)
To merge this branch: bzr merge lp:~dandrader/qtmir/surfaceItemFillMode
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Needs Fixing
Michael Zanetti (community) functional testing Approve
Review via email: mp+274750@code.launchpad.net

This proposal supersedes a proposal from 2015-10-14.

This proposal has been superseded by a proposal from 2015-12-04.

Commit message

Add MirSurfaceItem.fillMode and ensure items and buffer are in sync

Ensure that by the time we enter the phase of updating the scene graph, all qml items are up to date regarding the size of the buffer about to be rendered.

NB: This rendering scheme needs triple buffering to work.

Description of the change

* Are there any related MPs required for this MP to build/function as expected? Please list.

https://code.launchpad.net/~dandrader/unity-api/surfaceItemFillMode2/+merge/278955
https://code.launchpad.net/~dandrader/unity8/surfaceItemFillMode/+merge/279010

* Did you perform an exploratory manual test run of your code change and any related functionality?

Yes

* If you changed the packaging (debian), did you subscribe the ubuntu-unity team to this MP?

Not applicable

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

Glad to have helped. This isn't the first time someone has told me I'm wrong and then they went ahead and copied my code :)

Revision history for this message
Gerry Boland (gerboland) wrote : Posted in a previous version of this proposal

What's the use-case of this fillMode? The crop ability might have use in the spread? But it's not a proper solution for the stretched frames issue on rotation.

Revision history for this message
Daniel d'Andrada (dandrader) wrote : Posted in a previous version of this proposal

On 18/09/15 08:02, Gerry Boland wrote:
> What's the use-case of this fillMode? The crop ability might have use in the spread? But it's not a proper solution for the stretched frames issue on rotation.

Resize untiy8-dash in desktop mode on a Nexus device and you'll see.

Revision history for this message
Michael Zanetti (mzanetti) wrote : Posted in a previous version of this proposal

Code looks ok, but as noticed on the related unity8 branch, I'm not sure if this is the proper place to calculate the innerRect stuff. It has the effect that it makes window content and window decoration/shadow go out of sync.

review: Needs Information
Revision history for this message
Daniel d'Andrada (dandrader) wrote : Posted in a previous version of this proposal

On 23/09/2015 07:32, Michael Zanetti wrote:
> Review: Needs Information
>
> Code looks ok, but as noticed on the related unity8 branch, I'm not sure if this is the proper place to calculate the innerRect stuff. It has the effect that it makes window content and window decoration/shadow go out of sync.

They're two separate things. fillMode is there to ensure that you never
see a stretched surface even if the MirSurfaceItem size doesn't match
it. See it as yet another MirSurface feature that shells (unity8) can
take and use it on their UI/interaction designs.

What unity8 *does with it* is another thing. That shadow "going out of
sync" is a crude implementation or that unity7 window resize mode where
the window is not resize live, but you drag a translucent orang bounding
rect of it and only on release does the window get committed to that
bounding rect size (or actually a hint for the possibility doing the same).

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
387. By Albert Astals Cid

Don't search for the element again

Approved by: Gerry Boland, PS Jenkins bot

388. By Daniel d'Andrada

Shell draws its own cursor using the new Cursor QML element
Approved by: Lukáš Tinkl, Gerry Boland

389. By Gerry Boland

Initial multimonitor support - react correctly to Mir DisplayConfiguration changes.

On Mir DisplayConfiguration changes, QtMir now correctly:
1. blocks Mir until it has stopped all renderers and has their GL contexts released
2. reads the new DisplayConfiguration, matches any existing ScreenWindows to new DisplayBuffers should they change (as Mir may destroy and create it on us)
3. restarts all renderers

This also solves shutdown crash issues due to raciness of mir destroying the GL context backing the shell's QWindow before its renderer had stopped.

Add Unity.Screens qml module to advertise current screen state to QML. Fixes: #1436735, #1488831, #1488863
Approved by: Daniel d'Andrada

390. By Michał Sawicz

MirSurfaceItem: Survive holding a surface with an empty texture

Survive having a surface whose texture holds no mir buffer at all.
Instead of crashing in such situation we simply don't render it.
Approved by: Gerry Boland

391. By Michał Sawicz

Improve multimonitor support

* Removed magic:
 - Don't automagically select the screen where a window will be show.
   Let shell decide.
 - Don't automagically focus a window. Let shell handle it.

* Let shell know when a screen is about to be removed so that it has
  the opportunity to move or destroy a window in it before it's too late.
  - Added QGuiApplication::onScreenAboutToBeRemoved

* Added logging to key events
Approved by: Michał Sawicz

392. By Alan Griffiths

Opaquify MirWindowManager to control visibility of upcoming Window Management work
Approved by: Gerry Boland, PS Jenkins bot

393. By Lukáš Tinkl

React to surface modifications (window caption)
Approved by: Daniel d'Andrada

394. By Nick Dedekind

Removed the manipulation of the CMAKE_INSTALL_PREFIX from debian/rules
Approved by: Gerry Boland

395. By Nick Dedekind

Added touch performance tracing and test.
Approved by: Gerry Boland

396. By Lukáš Tinkl

Implement support for mouse wheel events; correctly pass around buttons Fixes: #1497091
Approved by: Gerry Boland

397. By Gerry Boland

Workaround for AutoPilot input coordinate positioning being outside screen geometry

398. By CI Train Bot Account

Releasing 0.4.6+15.10.20151021-0ubuntu1

Revision history for this message
Michael Zanetti (mzanetti) wrote :

I've tested this and it works fine. Would prefer Gerry to have a look at the code as there is quite some buffer handling involved which I'm not too experienced with.

review: Approve (functional testing)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Gerry Boland (gerboland) wrote :

Remind me why we want to support Stretch?

Revision history for this message
Daniel d'Andrada (dandrader) wrote :

> Remind me why we want to support Stretch?

Stretch does sound like a bad name, but scaling is stretching while respecting the aspect ratio of the surface.

And we want scaling working to display window thumbnails in the alt-tab spread, for instance.

399. By Michał Sawicz

Clean up packaging and fix autopkgtest on armhf
Approved by: Gerry Boland

400. By Michael Terry

Support new isTouchApp property to ApplicationInfoInterface and move lifecycle policy logic out of qtmir.

Now that qtmir won't decide policy for suspending anymore, we don't need all the lifecycleException handling in qtmir either. That can move to unity8.

But since the GSettings key for that was registered under the qtmir namespace (and there's no technical reason to migrate settings), I left the schema and classes dealing with GSettings alone, for future use.

401. By Nick Dedekind

Support server->client visibility change to stop rendering (lp:#1475678) Fixes: #1475678
Approved by: Daniel d'Andrada

402. By Alan Griffiths

Test harness for MirWindowManager (in preparation for more intelligent window management)
Approved by: Gerry Boland

403. By Nick Dedekind

Hand Qt millisecond timestamps rather than nanosecond. Fixes: #1510571, #1511076, #1511711
Approved by: Gerry Boland

404. By CI Train Bot Account

Releasing 0.4.6+16.04.20151102-0ubuntu1

405. By Nick Dedekind

Reverted occlusion detection (lp#1514556) Fixes: #1514556

406. By CI Train Bot Account

Releasing 0.4.6+16.04.20151110-0ubuntu1

407. By Gerry Boland

Fix armhf builds on Xenial by using -std=gnu99 instead of c99

Fixes this FTBFS on xenial:

In file included from /usr/include/lttng/tracepoint-rcu.h:26:0,
                 from /usr/include/lttng/tracepoint.h:29,
                 from /home/phablet/dev/projects/qtmir/qtmir/BUILD-xen/src/platforms/mirserver/tracepoints.h:10,
                 from /home/phablet/dev/projects/qtmir/qtmir/BUILD-xen/src/platforms/mirserver/tracepoints.c:7:
/usr/include/urcu/arch/generic.h: In function ‘caa_get_cycles’:
/usr/include/urcu/arch/generic.h:165:6: error: ‘CLOCK_MONOTONIC’ undeclared (first use in this function)
  if (caa_unlikely(clock_gettime(CLOCK_MONOTONIC, &ts)))
      ^
/usr/include/urcu/arch/generic.h:165:6: note: each undeclared identifier is reported only once for each function it appears in

Strictly should compile code with -std=gnu99 instead of -std=c99 to have the identifiers SIGEV_SIGNAL, sigeventStruct, and CLOCK_MONOTONIC available. These identifiers are declared when _POSIX_C_SOURCE is set to a value >= 199309L, which is the case with -std=gnu99. I could also have used -D_POSIX_C_SOURCE=199309L -std=c99 or have the macro defined in source code.

Did not impact wily as libuctu only started looking for CLOCK_MONOTONIC in Xenial release.
Approved by: Daniel d'Andrada

408. By CI Train Bot Account

Releasing 0.4.6+16.04.20151112-0ubuntu1

409. By Nick Dedekind

Update surface textures when dropping frames. Fixes: #1515356
Approved by: Gerry Boland

410. By CI Train Bot Account

Releasing 0.4.6+16.04.20151113-0ubuntu1

411. By Gerry Boland

Fix use of uninitialized variable
Approved by: Daniel d'Andrada, PS Jenkins bot

412. By Albert Astals Cid

Enable Efficient String Construction by default

See http://blog.qt.io/blog/2011/06/13/string-concatenation-with-qstringbuilder/
Approved by: Gerry Boland, PS Jenkins bot

413. By Michał Sawicz

Build with clang (tests/gmock fails and is unfixable on our side i'd say)
Approved by: Gerry Boland

414. By Gerry Boland

Use pid_t for PIDs.
Approved by: Daniel d'Andrada, PS Jenkins bot

415. By Loïc Molinari

Ensured Mir surface items with size less than or equal to zero are not rendered, as it's usually done for standard QtQuick items.
Approved by: Gerry Boland

416. By Nick Dedekind

Fix a crash when dropping a surface frame before Qt draws a surface item. Fixes: #1517139
Approved by: Gerry Boland

417. By CI Train Bot Account

Releasing 0.4.6+16.04.20151119-0ubuntu1

418. By Daniel d'Andrada

Implemented support for cursors set by client surfaces
Approved by: Lukáš Tinkl

419. By Gerry Boland

Manage frameSwapped signal/slot connection with MirSurface more strictly to avoid crash.

Direct Signal/slot connections across thread boundaries incur the same risks as any cross-thread calls. While connect/disconnect are thread safe methods, it is possible for a slot to be called while the slot owner is being deconstructed - and so not yet disconnected.

So watch for the Item's window change signal and disconnect signal immediately. Also move slot ownership to MirSurfaceItem to auto-disconnect more aggressively.
 Fixes: #1517571
Approved by: Daniel d'Andrada

420. By Daniel d'Andrada

Forward Mir mouse wheel events to the shell cursor Fixes: #1497091
Approved by: Lukáš Tinkl

421. By Daniel d'Andrada

Revert revision 415

The commit "Ensured Mir surface items with size less than or equal to zero are not rendered,
as it's usually done for standard QtQuick items." caused a regression.

MirSurface.size was being kept uninitialized, as QSize(-1,-1).

422. By CI Train Bot Account

Releasing 0.4.6+16.04.20151125-0ubuntu1

Revision history for this message
Loïc Molinari (loic.molinari) wrote :

Using polish() sounds like the right thing to do in order to correctly sync surface size and item size, no more temporary frame drawn with surface size different than item size. Emitting the item sizeChanged signal in the GUI thread right before the updatePaintNode() callback in the render thread doesn't imply 2 frames anymore when Unity requires a surface resize. It should also fix that [1].

Regarding the fill mode, I think we should expose the same enum names that the standard QtQuick Image uses with, for now, just the needed ones : Stretch and Pad. That would make things cleaner IMO, easier to understand for people used to that and would allow to add the PreserveAspectFit and PreserveAspectCrop (and maybe the alignment props) later if ever needed.

(Take my comments with a grain of salt because I'm not completely aware of the whole picture, but I'm taking the liberty of commenting on that because I've been working a bit on qtmir lately for the mutlibuffer stream thing and for the AA optimization which kinda touches the same code path ;) )

[1] https://code.launchpad.net/~dandrader/qtmir/revertRev415/+merge/278604

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
423. By Timo Jyrinki

Rebuild against Qt 5.5.1.

424. By Daniel d'Andrada

merge lp:~nick-dedekind/qtmir/polite-close

425. By Daniel d'Andrada

Add MirSurfaceItem.fillMode

426. By Daniel d'Andrada

Fix bad merge of polite-close

Unmerged revisions

426. By Daniel d'Andrada

Fix bad merge of polite-close

425. By Daniel d'Andrada

Add MirSurfaceItem.fillMode

424. By Daniel d'Andrada

merge lp:~nick-dedekind/qtmir/polite-close

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2015-11-25 15:38:50 +0000
3+++ CMakeLists.txt 2015-12-04 13:04:35 +0000
4@@ -20,7 +20,7 @@
5 set(CMAKE_AUTOMOC ON)
6
7 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99 -Wall -Wextra -Werror")
8-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -Wall -fno-strict-aliasing -Werror -Wextra")
9+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -fPIC -Wall -fno-strict-aliasing -Werror -Wextra")
10 set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined")
11
12
13@@ -75,7 +75,7 @@
14 pkg_check_modules(GSETTINGS_QT REQUIRED gsettings-qt)
15 pkg_check_modules(QTDBUSTEST libqtdbustest-1 REQUIRED)
16 pkg_check_modules(QTDBUSMOCK libqtdbusmock-1 REQUIRED)
17-pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application=11)
18+pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application=12)
19
20 include_directories(${APPLICATION_API_INCLUDE_DIRS})
21
22@@ -84,8 +84,6 @@
23 # Use the fast string builder
24 add_definitions(-DQT_USE_QSTRINGBUILDER)
25
26-include_directories( ${APPLICATION_API_INCLUDE_DIRS} )
27-
28 # We expect this to be set via debian/rules for GLES builds
29 if ("${USE_OPENGLES}" STREQUAL 1)
30 message(STATUS "Qt5 determined to be compiled with GLES support")
31
32=== modified file 'debian/changelog'
33--- debian/changelog 2015-12-01 14:14:00 +0000
34+++ debian/changelog 2015-12-04 13:04:35 +0000
35@@ -1,3 +1,10 @@
36+qtmir (0.4.7) UNRELEASED; urgency=medium
37+
38+ * [ Nick Dedekind ]
39+ * Request app closing rather than killing.
40+
41+ -- Nick Dedekind <nick.dedekind@canonical.com> Fri, 25 Sep 2015 09:33:39 +0100
42+
43 qtmir (0.4.6+16.04.20151125-0ubuntu2) xenial; urgency=medium
44
45 * Rebuild against Qt 5.5.1.
46
47=== modified file 'debian/control'
48--- debian/control 2015-11-25 15:38:50 +0000
49+++ debian/control 2015-12-04 13:04:35 +0000
50@@ -22,7 +22,7 @@
51 libubuntu-app-launch2-dev,
52 libubuntu-application-api-dev (>= 2.1.0),
53 libudev-dev,
54- libunity-api-dev (>= 7.103),
55+ libunity-api-dev (>= 7.104),
56 liburl-dispatcher1-dev,
57 libxkbcommon-dev,
58 libxrender-dev,
59@@ -93,7 +93,7 @@
60 Conflicts: libqtmir,
61 libunity-mir1,
62 Provides: unity-application-impl,
63- unity-application-impl-11,
64+ unity-application-impl-12,
65 Description: Qt plugin for Unity specific Mir APIs
66 QtMir provides Qt/QML bindings for Mir features that are exposed through the
67 qtmir-desktop or qtmir-android QPA plugin such as Application management
68
69=== modified file 'src/modules/Unity/Application/application.cpp'
70--- src/modules/Unity/Application/application.cpp 2015-10-01 17:20:40 +0000
71+++ src/modules/Unity/Application/application.cpp 2015-12-04 13:04:35 +0000
72@@ -45,13 +45,14 @@
73 , m_sharedWakelock(sharedWakelock)
74 , m_desktopData(desktopFileReader)
75 , m_pid(0)
76- , m_stage((m_desktopData->stageHint() == "SideStage") ? Application::SideStage : Application::MainStage)
77+ , m_stage((desktopFileReader->stageHint() == "SideStage") ? Application::SideStage : Application::MainStage)
78 , m_state(InternalState::Starting)
79 , m_focused(false)
80 , m_arguments(arguments)
81 , m_session(nullptr)
82 , m_requestedState(RequestedRunning)
83 , m_processState(ProcessUnknown)
84+ , m_closeTimer(0)
85 {
86 qCDebug(QTMIR_APPLICATIONS) << "Application::Application - appId=" << desktopFileReader->appId();
87
88@@ -394,25 +395,22 @@
89 return m_pid;
90 }
91
92-void Application::setPid(pid_t pid)
93-{
94- m_pid = pid;
95-}
96-
97 void Application::close()
98 {
99 qCDebug(QTMIR_APPLICATIONS) << "Application::close - appId=" << appId();
100
101 switch (m_state) {
102 case InternalState::Starting:
103+ stop();
104+ break;
105 case InternalState::Running:
106- setInternalState(InternalState::Closing);
107+ doClose();
108 break;
109 case InternalState::SuspendingWaitSession:
110 case InternalState::SuspendingWaitProcess:
111 case InternalState::Suspended:
112 setRequestedState(RequestedRunning);
113- setInternalState(InternalState::Closing);
114+ doClose();
115 break;
116 case InternalState::Closing:
117 // already on the way
118@@ -422,6 +420,22 @@
119 // too late
120 break;
121 }
122+
123+}
124+
125+void Application::doClose()
126+{
127+ Q_ASSERT(m_closeTimer == 0);
128+ Q_ASSERT(m_session != nullptr);
129+
130+ m_session->close();
131+ m_closeTimer = startTimer(3000);
132+ setInternalState(InternalState::Closing);
133+}
134+
135+void Application::setPid(pid_t pid)
136+{
137+ m_pid = pid;
138 }
139
140 void Application::setArguments(const QStringList arguments)
141@@ -603,6 +617,8 @@
142
143 void Application::suspend()
144 {
145+ qCDebug(QTMIR_APPLICATIONS) << "Application::suspend - appId=" << appId();
146+
147 Q_ASSERT(m_state == InternalState::Running);
148 Q_ASSERT(m_session != nullptr);
149
150@@ -612,6 +628,8 @@
151
152 void Application::resume()
153 {
154+ qCDebug(QTMIR_APPLICATIONS) << "Application::resume - appId=" << appId();
155+
156 if (m_state == InternalState::Suspended) {
157 setInternalState(InternalState::Running);
158 Q_EMIT resumeProcessRequested();
159@@ -634,6 +652,21 @@
160 Q_EMIT startProcessRequested();
161 }
162
163+void Application::stop()
164+{
165+ qCDebug(QTMIR_APPLICATIONS) << "Application::stop - appId=" << appId();
166+
167+ Q_EMIT stopProcessRequested();
168+}
169+
170+void Application::timerEvent(QTimerEvent *event)
171+{
172+ if (event->timerId() == m_closeTimer) {
173+ m_closeTimer = 0;
174+ stop();
175+ }
176+}
177+
178 bool Application::isTouchApp() const
179 {
180 return m_desktopData->isTouchApp();
181@@ -704,7 +737,7 @@
182 * 3. application is managed by upstart and is in foreground (i.e. has
183 * Running state), if Mir reports the application disconnects, it
184 * either crashed or stopped itself.
185- * 4. We're expecting the application to stop after a close request
186+ * 4. We're expecting the application to stop after a close request
187 */
188 setInternalState(InternalState::Stopped);
189 } else {
190
191=== modified file 'src/modules/Unity/Application/application.h'
192--- src/modules/Unity/Application/application.h 2015-11-17 14:16:22 +0000
193+++ src/modules/Unity/Application/application.h 2015-12-04 13:04:35 +0000
194@@ -137,6 +137,7 @@
195 void sessionChanged(SessionInterface *session);
196
197 void startProcessRequested();
198+ void stopProcessRequested();
199 void suspendProcessRequested();
200 void resumeProcessRequested();
201 void stopped();
202@@ -146,6 +147,9 @@
203
204 void respawn();
205
206+protected:
207+ void timerEvent(QTimerEvent *event);
208+
209 private:
210
211 QString longAppId() const;
212@@ -158,11 +162,13 @@
213 void wipeQMLCache();
214 void suspend();
215 void resume();
216+ void stop();
217 QColor colorFromString(const QString &colorString, const char *colorName) const;
218 static const char* internalStateToStr(InternalState state);
219 void applyRequestedState();
220 void applyRequestedRunning();
221 void applyRequestedSuspended();
222+ void doClose();
223
224 QSharedPointer<SharedWakelock> m_sharedWakelock;
225 DesktopFileReader* m_desktopData;
226@@ -178,6 +184,7 @@
227 SessionInterface *m_session;
228 RequestedState m_requestedState;
229 ProcessState m_processState;
230+ int m_closeTimer;
231
232 friend class ApplicationManager;
233 friend class SessionManager;
234
235=== modified file 'src/modules/Unity/Application/application_manager.cpp'
236--- src/modules/Unity/Application/application_manager.cpp 2015-11-17 14:16:22 +0000
237+++ src/modules/Unity/Application/application_manager.cpp 2015-12-04 13:04:35 +0000
238@@ -353,6 +353,23 @@
239 return nullptr;
240 }
241
242+ if (m_queuedStartApplications.contains(inputAppId)) {
243+ qWarning() << "ApplicationManager::startApplication - application appId=" << appId << " is queued to start";
244+ return nullptr;
245+ } else {
246+ application = findClosingApplication(inputAppId);
247+ if (application) {
248+ m_queuedStartApplications.append(inputAppId);
249+ qWarning() << "ApplicationManager::startApplication - application appId=" << appId << " is closing. Queuing start";
250+ connect(application, &QObject::destroyed, this, [this, application, inputAppId, flags, arguments]() {
251+ m_queuedStartApplications.removeAll(inputAppId);
252+ // start the app.
253+ startApplication(inputAppId, flags, arguments);
254+ }, Qt::QueuedConnection); // Queued so that we finish the app removal before starting again.
255+ return nullptr;
256+ }
257+ }
258+
259 if (!m_taskController->start(appId, arguments)) {
260 qWarning() << "Upstart failed to start application with appId" << appId;
261 return nullptr;
262@@ -438,17 +455,12 @@
263 application->close();
264 remove(application);
265
266- bool result = m_taskController->stop(application->longAppId());
267-
268- if (!result && application->pid() > 0) {
269- qWarning() << "FAILED to ask Upstart to stop application with appId" << appId
270- << "Sending SIGTERM to process:" << application->pid();
271- kill(application->pid(), SIGTERM);
272- result = true;
273- }
274-
275- delete application;
276- return result;
277+ connect(application, &QObject::destroyed, this, [this, application](QObject*) {
278+ m_closingApplications.removeAll(application);
279+ });
280+ m_closingApplications.append(application);
281+ application->close();
282+ return true;
283 }
284
285 void ApplicationManager::onProcessFailed(const QString &appId, const bool duringStartup)
286@@ -473,7 +485,11 @@
287 {
288 tracepoint(qtmir, onProcessStopped);
289 qCDebug(QTMIR_APPLICATIONS) << "ApplicationManager::onProcessStopped - appId=" << appId;
290+
291 Application *application = findApplication(appId);
292+ if (!application) {
293+ application = findClosingApplication(appId);
294+ }
295
296 if (!application) {
297 qDebug() << "ApplicationManager::onProcessStopped reports stop of appId=" << appId
298@@ -729,6 +745,15 @@
299 this, [=]() { m_taskController->start(appId, arguments); },
300 Qt::QueuedConnection);
301
302+ connect(application, &Application::stopProcessRequested, this, [=]() {
303+ if (!m_taskController->stop(application->longAppId()) && application->pid() > 0) {
304+ qWarning() << "FAILED to ask Upstart to stop application with appId" << appId
305+ << "Sending SIGTERM to process:" << appId;
306+ kill(application->pid(), SIGTERM);
307+ application->setProcessState(Application::ProcessStopped);
308+ }
309+ });
310+
311 connect(application, &Application::suspendProcessRequested, this, [=]() { m_taskController->suspend(longAppId); } );
312 connect(application, &Application::resumeProcessRequested, this, [=]() { m_taskController->resume(longAppId); } );
313
314@@ -753,7 +778,10 @@
315 Q_ASSERT(application != nullptr);
316 qCDebug(QTMIR_APPLICATIONS) << "ApplicationManager::remove - appId=" << application->appId();
317
318- application->disconnect(this);
319+ disconnect(application, &Application::fullscreenChanged, this, 0);
320+ disconnect(application, &Application::focusedChanged, this, 0);
321+ disconnect(application, &Application::stateChanged, this, 0);
322+ disconnect(application, &Application::stageChanged, this, 0);
323
324 int i = m_applications.indexOf(application);
325 if (i != -1) {
326@@ -813,4 +841,16 @@
327 return result;
328 }
329
330+Application *ApplicationManager::findClosingApplication(const QString &inputAppId) const
331+{
332+ const QString appId = toShortAppIdIfPossible(inputAppId);
333+
334+ for (Application *app : m_closingApplications) {
335+ if (app->appId() == appId) {
336+ return app;
337+ }
338+ }
339+ return nullptr;
340+}
341+
342 } // namespace qtmir
343
344=== modified file 'src/modules/Unity/Application/application_manager.h'
345--- src/modules/Unity/Application/application_manager.h 2015-11-17 14:16:22 +0000
346+++ src/modules/Unity/Application/application_manager.h 2015-12-04 13:04:35 +0000
347@@ -149,6 +149,7 @@
348 QString toString() const;
349
350 Application* findApplicationWithPromptSession(const mir::scene::PromptSession* promptSession);
351+ Application *findClosingApplication(const QString &inputAppId) const;
352
353 QSharedPointer<MirServer> m_mirServer;
354
355@@ -160,6 +161,8 @@
356 QSharedPointer<ProcInfo> m_procInfo;
357 QSharedPointer<SharedWakelock> m_sharedWakelock;
358 QSharedPointer<SettingsInterface> m_settings;
359+ QList<Application*> m_closingApplications;
360+ QList<QString> m_queuedStartApplications;
361 static ApplicationManager* the_application_manager;
362
363 friend class Application;
364
365=== modified file 'src/modules/Unity/Application/mirbuffersgtexture.cpp'
366--- src/modules/Unity/Application/mirbuffersgtexture.cpp 2015-10-02 12:20:00 +0000
367+++ src/modules/Unity/Application/mirbuffersgtexture.cpp 2015-12-04 13:04:35 +0000
368@@ -21,6 +21,9 @@
369 #include <mir/geometry/size.h>
370 #include <mir/renderer/gl/texture_source.h>
371
372+// mirserver
373+#include <logging.h>
374+
375 namespace mg = mir::geometry;
376 namespace mrg = mir::renderer::gl;
377
378@@ -80,20 +83,25 @@
379 return m_mirBuffer->pixel_format() == mir_pixel_format_abgr_8888
380 || m_mirBuffer->pixel_format() == mir_pixel_format_argb_8888;
381 } else {
382+ qCWarning(QTMIR_SURFACES) << "MirBufferSGTexture: hasAlphaChannel() called but there's no mir buffer to query";
383 return false;
384 }
385 }
386
387 void MirBufferSGTexture::bind()
388 {
389- Q_ASSERT(hasBuffer());
390- glBindTexture(GL_TEXTURE_2D, m_textureId);
391- updateBindOptions(true/* force */);
392-
393- auto const texture_source =
394- dynamic_cast<mrg::TextureSource*>(m_mirBuffer->native_buffer_base());
395- if (!texture_source)
396- throw std::logic_error("Buffer does not support GL rendering");
397-
398- texture_source->gl_bind_to_texture();
399+ if (hasBuffer()) {
400+ glBindTexture(GL_TEXTURE_2D, m_textureId);
401+ updateBindOptions(true/* force */);
402+
403+ auto const texture_source =
404+ dynamic_cast<mrg::TextureSource*>(m_mirBuffer->native_buffer_base());
405+ if (!texture_source)
406+ throw std::logic_error("Buffer does not support GL rendering");
407+
408+ texture_source->gl_bind_to_texture();
409+ } else {
410+ qCWarning(QTMIR_SURFACES) << "MirBufferSGTexture: bind() called but there's no mir buffer to bind to";
411+ glBindTexture(GL_TEXTURE_2D, 0);
412+ }
413 }
414
415=== modified file 'src/modules/Unity/Application/mirsurface.cpp'
416--- src/modules/Unity/Application/mirsurface.cpp 2015-11-25 15:38:39 +0000
417+++ src/modules/Unity/Application/mirsurface.cpp 2015-12-04 13:04:35 +0000
418@@ -25,6 +25,7 @@
419
420 // Mir
421 #include <mir/geometry/rectangle.h>
422+#include <mir/graphics/buffer.h>
423 #include <mir/events/event_builders.h>
424 #include <mir/shell/shell.h>
425 #include <mir_toolkit/event.h>
426@@ -297,7 +298,7 @@
427 int framesPending = m_surface->buffers_ready_for_compositor(userId);
428 if (framesPending > 0) {
429 m_textureUpdated = false;
430-
431+
432 locker.unlock();
433 if (updateTexture()) {
434 qCDebug(QTMIR_SURFACES).nospace() << "MirSurface[" << appId() << "]::dropPendingBuffer() dropped=1 left=" << framesPending-1;
435@@ -355,39 +356,53 @@
436 return texture->hasBuffer();
437 }
438
439- const void* const userId = (void*)123;
440- auto renderables = m_surface->generate_renderables(userId);
441-
442- if (renderables.size() > 0 &&
443- (m_surface->buffers_ready_for_compositor(userId) > 0 || !texture->hasBuffer())
444- ) {
445+ if (m_pendingBuffer) {
446 // Avoid holding two buffers for the compositor at the same time. Thus free the current
447 // before acquiring the next
448 texture->freeBuffer();
449- texture->setBuffer(renderables[0]->buffer());
450+ texture->setBuffer(m_pendingBuffer);
451+ m_pendingBuffer.reset();
452 ++m_currentFrameNumber;
453-
454- if (texture->textureSize() != m_size) {
455- m_size = texture->textureSize();
456- QMetaObject::invokeMethod(this, "emitSizeChanged", Qt::QueuedConnection);
457+ }
458+
459+ m_textureUpdated = true;
460+
461+ return texture->hasBuffer();
462+}
463+
464+void MirSurface::consumeBuffer()
465+{
466+ QMutexLocker locker(&m_mutex);
467+ const void* const userId = (void*)123;
468+ auto renderables = m_surface->generate_renderables(userId);
469+
470+ if (renderables.size() > 0 && m_surface->buffers_ready_for_compositor(userId) > 0) {
471+ m_pendingBuffer = renderables[0]->buffer();
472+
473+ QSize size(m_pendingBuffer->size().width.as_int(),
474+ m_pendingBuffer->size().height.as_int());
475+ if (size != m_size) {
476+ m_size = size;
477+ Q_EMIT sizeChanged(m_size);
478 }
479-
480- m_textureUpdated = true;
481 }
482
483 if (m_surface->buffers_ready_for_compositor(userId) > 0) {
484 // restart the frame dropper to give MirSurfaceItems enough time to render the next frame.
485- // queued since the timer lives in a different thread
486- QMetaObject::invokeMethod(&m_frameDropperTimer, "start", Qt::QueuedConnection);
487+ QMetaObject::invokeMethod(&m_frameDropperTimer, "start", Qt::AutoConnection);
488 }
489-
490- return texture->hasBuffer();
491 }
492
493 void MirSurface::onCompositorSwappedBuffers()
494 {
495 QMutexLocker locker(&m_mutex);
496 m_textureUpdated = false;
497+
498+ if (m_texture && m_pendingBuffer) {
499+ // No need to hold onto this buffer as it won't be used on the next frame.
500+ MirBufferSGTexture *texture = static_cast<MirBufferSGTexture*>(m_texture.data());
501+ texture->freeBuffer();
502+ }
503 }
504
505 bool MirSurface::numBuffersReadyForCompositor()
506@@ -420,6 +435,13 @@
507 }
508 }
509
510+void MirSurface::close()
511+{
512+ if (m_surface) {
513+ m_surface->request_client_surface_close();
514+ }
515+}
516+
517 void MirSurface::resize(int width, int height)
518 {
519 int mirWidth = m_surface->size().width.as_int();
520
521=== modified file 'src/modules/Unity/Application/mirsurface.h'
522--- src/modules/Unity/Application/mirsurface.h 2015-11-25 15:38:39 +0000
523+++ src/modules/Unity/Application/mirsurface.h 2015-12-04 13:04:35 +0000
524@@ -35,7 +35,10 @@
525 #include <mir/scene/surface.h>
526 #include <mir_toolkit/common.h>
527
528-namespace mir { namespace shell { class Shell; }}
529+namespace mir {
530+ namespace shell { class Shell; }
531+ namespace graphics { class Buffer; }
532+}
533
534 class SurfaceObserver;
535
536@@ -89,6 +92,8 @@
537 void unregisterView(qintptr viewId) override;
538 void setViewVisibility(qintptr viewId, bool visible) override;
539
540+ void consumeBuffer() override;
541+
542 // methods called from the rendering (scene graph) thread:
543 QSharedPointer<QSGTexture> texture() override;
544 QSGTexture *weakTexture() const override { return m_texture.data(); }
545@@ -99,6 +104,8 @@
546
547 void setFocus(bool focus) override;
548
549+ void close() override;
550+
551 void mousePressEvent(QMouseEvent *event) override;
552 void mouseMoveEvent(QMouseEvent *event) override;
553 void mouseReleaseEvent(QMouseEvent *event) override;
554@@ -120,7 +127,9 @@
555 QCursor cursor() const override;
556
557 public Q_SLOTS:
558+ // methods called from the rendering (scene graph) thread:
559 void onCompositorSwappedBuffers() override;
560+ // end of methods called from the rendering (scene graph) thread
561
562 private Q_SLOTS:
563 void dropPendingBuffer();
564@@ -163,6 +172,8 @@
565 QSize m_size;
566
567 QCursor m_cursor;
568+
569+ std::shared_ptr<mir::graphics::Buffer> m_pendingBuffer;
570 };
571
572 } // namespace qtmir
573
574=== modified file 'src/modules/Unity/Application/mirsurfaceinterface.h'
575--- src/modules/Unity/Application/mirsurfaceinterface.h 2015-11-25 15:38:39 +0000
576+++ src/modules/Unity/Application/mirsurfaceinterface.h 2015-12-04 13:04:35 +0000
577@@ -54,6 +54,8 @@
578 virtual void unregisterView(qintptr viewId) = 0;
579 virtual void setViewVisibility(qintptr viewId, bool visible) = 0;
580
581+ virtual void consumeBuffer() = 0;
582+
583 // methods called from the rendering (scene graph) thread:
584 virtual QSharedPointer<QSGTexture> texture() = 0;
585 virtual QSGTexture *weakTexture() const = 0;
586@@ -64,6 +66,8 @@
587
588 virtual void setFocus(bool focus) = 0;
589
590+ virtual void close() = 0;
591+
592 virtual void mousePressEvent(QMouseEvent *event) = 0;
593 virtual void mouseMoveEvent(QMouseEvent *event) = 0;
594 virtual void mouseReleaseEvent(QMouseEvent *event) = 0;
595@@ -88,7 +92,9 @@
596 void cursorChanged(const QCursor &cursor);
597
598 public Q_SLOTS:
599+ // methods called from the rendering (scene graph) thread:
600 virtual void onCompositorSwappedBuffers() = 0;
601+ // end of methods called from the rendering (scene graph) thread
602
603 Q_SIGNALS:
604 void firstFrameDrawn();
605
606=== modified file 'src/modules/Unity/Application/mirsurfaceitem.cpp'
607--- src/modules/Unity/Application/mirsurfaceitem.cpp 2015-11-25 15:38:54 +0000
608+++ src/modules/Unity/Application/mirsurfaceitem.cpp 2015-12-04 13:04:35 +0000
609@@ -92,6 +92,7 @@
610 , m_surfaceHeight(0)
611 , m_orientationAngle(nullptr)
612 , m_consumesInput(false)
613+ , m_fillMode(Stretch)
614 {
615 qCDebug(QTMIR_SURFACES) << "MirSurfaceItem::MirSurfaceItem";
616
617@@ -227,7 +228,7 @@
618 }
619
620 if (m_surface->numBuffersReadyForCompositor() > 0) {
621- QTimer::singleShot(0, this, SLOT(update()));
622+ QTimer::singleShot(0, this, SLOT(polishAndUpdate()));
623 }
624
625 m_textureProvider->smooth = smooth();
626@@ -240,15 +241,31 @@
627 node->setMipmapFiltering(QSGTexture::None);
628 node->setHorizontalWrapMode(QSGTexture::ClampToEdge);
629 node->setVerticalWrapMode(QSGTexture::ClampToEdge);
630- node->setSubSourceRect(QRectF(0, 0, 1, 1));
631 } else {
632 if (!m_lastFrameNumberRendered || (*m_lastFrameNumberRendered != m_surface->currentFrameNumber())) {
633 node->markDirty(QSGNode::DirtyMaterial);
634 }
635 }
636
637- node->setTargetRect(QRectF(0, 0, width(), height()));
638- node->setInnerTargetRect(QRectF(0, 0, width(), height()));
639+ if (m_fillMode == PadOrCrop) {
640+ const QSize &textureSize = m_textureProvider->texture()->textureSize();
641+
642+ QRectF targetRect;
643+ targetRect.setWidth(qMin(width(), static_cast<qreal>(textureSize.width())));
644+ targetRect.setHeight(qMin(height(), static_cast<qreal>(textureSize.height())));
645+
646+ qreal u = targetRect.width() / textureSize.width();
647+ qreal v = targetRect.height() / textureSize.height();
648+ node->setSubSourceRect(QRectF(0, 0, u, v));
649+
650+ node->setTargetRect(targetRect);
651+ node->setInnerTargetRect(targetRect);
652+ } else {
653+ // Stretch
654+ node->setSubSourceRect(QRectF(0, 0, 1, 1));
655+ node->setTargetRect(QRectF(0, 0, width(), height()));
656+ node->setInnerTargetRect(QRectF(0, 0, width(), height()));
657+ }
658
659 node->setFiltering(smooth() ? QSGTexture::Linear : QSGTexture::Nearest);
660 node->setAntialiasing(antialiasing());
661@@ -626,7 +643,7 @@
662
663 // When a new mir frame gets posted we notify the QML engine that this item needs redrawing,
664 // schedules call to updatePaintNode() from the rendering thread
665- connect(m_surface, &MirSurfaceInterface::framesPosted, this, &QQuickItem::update);
666+ connect(m_surface, &MirSurfaceInterface::framesPosted, this, &MirSurfaceItem::polishAndUpdate);
667
668 connect(m_surface, &MirSurfaceInterface::stateChanged, this, &MirSurfaceItem::surfaceStateChanged);
669 connect(m_surface, &MirSurfaceInterface::liveChanged, this, &MirSurfaceItem::liveChanged);
670@@ -730,6 +747,33 @@
671 }
672 }
673
674+MirSurfaceItem::FillMode MirSurfaceItem::fillMode() const
675+{
676+ return m_fillMode;
677+}
678+
679+void MirSurfaceItem::setFillMode(FillMode value)
680+{
681+ if (m_fillMode != value) {
682+ m_fillMode = value;
683+ Q_EMIT fillModeChanged(m_fillMode);
684+ }
685+}
686+
687+void MirSurfaceItem::polishAndUpdate()
688+{
689+ polish();
690+ update();
691+}
692+
693+void MirSurfaceItem::updatePolish()
694+{
695+ if (!m_surface || !m_surface->live()) {
696+ return;
697+ }
698+ m_surface->consumeBuffer();
699+}
700+
701 } // namespace qtmir
702
703 #include "mirsurfaceitem.moc"
704
705=== modified file 'src/modules/Unity/Application/mirsurfaceitem.h'
706--- src/modules/Unity/Application/mirsurfaceitem.h 2015-11-25 15:38:44 +0000
707+++ src/modules/Unity/Application/mirsurfaceitem.h 2015-12-04 13:04:35 +0000
708@@ -68,6 +68,9 @@
709 int surfaceHeight() const override;
710 void setSurfaceHeight(int value) override;
711
712+ FillMode fillMode() const override;
713+ void setFillMode(FillMode value) override;
714+
715 ////////
716 // QQuickItem
717
718@@ -107,6 +110,8 @@
719
720 void releaseResources() override;
721
722+ void updatePolish() override;
723+
724 private Q_SLOTS:
725 void scheduleMirSurfaceSizeUpdate();
726 void updateMirSurfaceSize();
727@@ -119,6 +124,8 @@
728
729 void onWindowChanged(QQuickWindow *window);
730
731+ void polishAndUpdate();
732+
733 private:
734 void ensureTextureProvider();
735
736@@ -168,6 +175,8 @@
737 Mir::OrientationAngle *m_orientationAngle;
738
739 bool m_consumesInput;
740+
741+ FillMode m_fillMode;
742 };
743
744 } // namespace qtmir
745
746=== modified file 'src/modules/Unity/Application/session.cpp'
747--- src/modules/Unity/Application/session.cpp 2015-08-31 09:51:28 +0000
748+++ src/modules/Unity/Application/session.cpp 2015-12-04 13:04:35 +0000
749@@ -40,6 +40,28 @@
750 namespace qtmir
751 {
752
753+namespace {
754+
755+const char *sessionStateToString(SessionInterface::State state)
756+{
757+ switch (state) {
758+ case SessionInterface::Starting:
759+ return "starting";
760+ case SessionInterface::Running:
761+ return "running";
762+ case SessionInterface::Suspending:
763+ return "suspending";
764+ case SessionInterface::Suspended:
765+ return "suspended";
766+ case SessionInterface::Stopped:
767+ return "stopped";
768+ default:
769+ return "???";
770+ }
771+}
772+
773+}
774+
775 Session::Session(const std::shared_ptr<ms::Session>& session,
776 const std::shared_ptr<ms::PromptSessionManager>& promptSessionManager,
777 QObject *parent)
778@@ -142,6 +164,9 @@
779
780 void Session::setState(State state) {
781 if (state != m_state) {
782+ qCDebug(QTMIR_SESSIONS) << "Session::setState - session=" << name()
783+ << "state=" << sessionStateToString(state);
784+
785 m_state = state;
786 Q_EMIT stateChanged(m_state);
787 }
788@@ -232,7 +257,7 @@
789
790 void Session::suspend()
791 {
792- qCDebug(QTMIR_SESSIONS) << "Session::suspend - session=" << this << "state=" << applicationStateToStr(m_state);
793+ qCDebug(QTMIR_SESSIONS) << "Session::suspend - session=" << this << "state=" << sessionStateToString(m_state);
794 if (m_state == Running) {
795 session()->set_lifecycle_state(mir_lifecycle_state_will_suspend);
796 m_suspendTimer->start(1500);
797@@ -251,7 +276,7 @@
798
799 void Session::resume()
800 {
801- qCDebug(QTMIR_SESSIONS) << "Session::resume - session=" << this << "state=" << applicationStateToStr(m_state);
802+ qCDebug(QTMIR_SESSIONS) << "Session::resume - session=" << this << "state=" << sessionStateToString(m_state);
803
804 if (m_state == Suspending || m_state == Suspended) {
805 doResume();
806@@ -281,9 +306,20 @@
807 setState(Running);
808 }
809
810+void Session::close()
811+{
812+ qCDebug(QTMIR_SESSIONS) << "Session::close - " << name() << m_surface;
813+ if (m_surface) {
814+ m_surface->close();
815+ }
816+}
817+
818 void Session::stop()
819 {
820+ qCDebug(QTMIR_SESSIONS) << "Session::stop - " << name();
821+
822 if (m_state != Stopped) {
823+
824 stopPromptSessions();
825 if (m_suspendTimer->isActive())
826 m_suspendTimer->stop();
827@@ -304,6 +340,8 @@
828 void Session::setLive(const bool live)
829 {
830 if (m_live != live) {
831+ qCDebug(QTMIR_SESSIONS) << "Session::setLive - " << name() << "live=" << live;
832+
833 m_live = live;
834 Q_EMIT liveChanged(m_live);
835 if (!live) {
836
837=== modified file 'src/modules/Unity/Application/session.h'
838--- src/modules/Unity/Application/session.h 2015-08-31 09:51:28 +0000
839+++ src/modules/Unity/Application/session.h 2015-12-04 13:04:35 +0000
840@@ -63,6 +63,7 @@
841
842 void suspend() override;
843 void resume() override;
844+ void close() override;
845 void stop() override;
846
847 void addChildSession(SessionInterface* session) override;
848
849=== modified file 'src/modules/Unity/Application/session_interface.h'
850--- src/modules/Unity/Application/session_interface.h 2015-08-31 09:51:28 +0000
851+++ src/modules/Unity/Application/session_interface.h 2015-12-04 13:04:35 +0000
852@@ -80,6 +80,7 @@
853 virtual void setApplication(unity::shell::application::ApplicationInfoInterface* item) = 0;
854 virtual void suspend() = 0;
855 virtual void resume() = 0;
856+ virtual void close() = 0;
857 virtual void stop() = 0;
858
859 // For SessionManager use
860
861=== modified file 'tests/CMakeLists.txt'
862--- tests/CMakeLists.txt 2014-12-03 08:56:35 +0000
863+++ tests/CMakeLists.txt 2015-12-04 13:04:35 +0000
864@@ -1,4 +1,5 @@
865 find_package(GMock)
866
867+add_subdirectory(framework)
868 add_subdirectory(mirserver)
869 add_subdirectory(modules)
870
871=== removed directory 'tests/common'
872=== renamed directory 'tests/modules/common' => 'tests/framework'
873=== added file 'tests/framework/CMakeLists.txt'
874--- tests/framework/CMakeLists.txt 1970-01-01 00:00:00 +0000
875+++ tests/framework/CMakeLists.txt 2015-12-04 13:04:35 +0000
876@@ -0,0 +1,48 @@
877+include_directories(
878+ ${APPLICATION_API_INCLUDE_DIRS}
879+ ${CMAKE_SOURCE_DIR}/src/platforms/mirserver
880+ ${CMAKE_SOURCE_DIR}/src/modules
881+ ${MIRSERVER_INCLUDE_DIRS}
882+ ${MIRRENDERERGLDEV_INCLUDE_DIRS}
883+
884+ ${Qt5Quick_INCLUDE_DIRS}
885+ ${Qt5DBus_INCLUDE_DIRS}
886+)
887+
888+set(QTMIR_TEST_PRIVATE_SRC
889+ fake_desktopfilereader.cpp
890+ fake_mirsurface.cpp
891+ fake_session.cpp
892+ mock_application_controller.cpp
893+ mock_desktop_file_reader.cpp
894+ mock_display.cpp
895+ mock_display_configuration.cpp
896+ mock_gl_display_buffer.cpp
897+ mock_main_loop.cpp
898+ mock_mir_session.cpp
899+ mock_proc_info.cpp
900+ mock_prompt_session.cpp
901+ mock_prompt_session_manager.cpp
902+ mock_renderable.cpp
903+ mock_session.cpp
904+ mock_settings.cpp
905+ mock_shared_wakelock.cpp
906+ mock_surface.cpp
907+ stub_input_channel.cpp
908+ stub_scene_surface.cpp
909+ qtmir_test.cpp
910+)
911+
912+add_library(qtmir-test-framework-static STATIC
913+ ${QTMIR_TEST_PRIVATE_SRC}
914+)
915+
916+target_link_libraries(
917+ qtmir-test-framework-static
918+
919+ -L${CMAKE_BINARY_DIR}/tests/framework
920+ qtmir-test-framework-static
921+
922+ ${GTEST_BOTH_LIBRARIES}
923+ ${GMOCK_LIBRARIES}
924+)
925
926=== added file 'tests/framework/fake_desktopfilereader.cpp'
927--- tests/framework/fake_desktopfilereader.cpp 1970-01-01 00:00:00 +0000
928+++ tests/framework/fake_desktopfilereader.cpp 2015-12-04 13:04:35 +0000
929@@ -0,0 +1,68 @@
930+/*
931+ * Copyright (C) 2015 Canonical, Ltd.
932+ *
933+ * This program is free software: you can redistribute it and/or modify it under
934+ * the terms of the GNU Lesser General Public License version 3, as published by
935+ * the Free Software Foundation.
936+ *
937+ * This program is distributed in the hope that it will be useful, but WITHOUT
938+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
939+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
940+ * Lesser General Public License for more details.
941+ *
942+ * You should have received a copy of the GNU Lesser General Public License
943+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
944+ */
945+
946+#include "fake_desktopfilereader.h"
947+
948+namespace qtmir
949+{
950+
951+FakeDesktopFileReader::FakeDesktopFileReader()
952+ : DesktopFileReader()
953+ , m_appId("foo-app")
954+{
955+}
956+
957+FakeDesktopFileReader::~FakeDesktopFileReader()
958+{
959+}
960+
961+QString FakeDesktopFileReader::file() const { return QString(); }
962+
963+QString FakeDesktopFileReader::appId() const { return m_appId; }
964+
965+QString FakeDesktopFileReader::name() const { return QString(); }
966+
967+QString FakeDesktopFileReader::comment() const { return QString(); }
968+
969+QString FakeDesktopFileReader::icon() const { return QString(); }
970+
971+QString FakeDesktopFileReader::exec() const { return QString(); }
972+
973+QString FakeDesktopFileReader::path() const { return QString(); }
974+
975+QString FakeDesktopFileReader::stageHint() const { return QString(); }
976+
977+QString FakeDesktopFileReader::splashTitle() const { return QString(); }
978+
979+QString FakeDesktopFileReader::splashImage() const { return QString(); }
980+
981+QString FakeDesktopFileReader::splashShowHeader() const { return QString(); }
982+
983+QString FakeDesktopFileReader::splashColor() const { return QString(); }
984+
985+QString FakeDesktopFileReader::splashColorHeader() const { return QString(); }
986+
987+QString FakeDesktopFileReader::splashColorFooter() const { return QString(); }
988+
989+Qt::ScreenOrientations FakeDesktopFileReader::supportedOrientations() const { return Qt::PortraitOrientation; }
990+
991+bool FakeDesktopFileReader::rotatesWindowContents() const { return false; }
992+
993+bool FakeDesktopFileReader::isTouchApp() const { return true; }
994+
995+bool FakeDesktopFileReader::loaded() const { return true; }
996+
997+} // namespace qtmir
998
999=== modified file 'tests/framework/fake_desktopfilereader.h'
1000--- tests/modules/common/fake_desktopfilereader.h 2015-09-28 20:11:39 +0000
1001+++ tests/framework/fake_desktopfilereader.h 2015-12-04 13:04:35 +0000
1002@@ -17,33 +17,34 @@
1003 #ifndef FAKE_DESKTOPFILEREADER_H
1004 #define FAKE_DESKTOPFILEREADER_H
1005
1006+#include <Unity/Application/desktopfilereader.h>
1007+
1008 namespace qtmir {
1009
1010 class FakeDesktopFileReader : public qtmir::DesktopFileReader
1011 {
1012 public:
1013- FakeDesktopFileReader() : DesktopFileReader()
1014- , m_appId("foo-app")
1015- {}
1016+ FakeDesktopFileReader();
1017+ virtual ~FakeDesktopFileReader();
1018
1019- QString file() const override { return QString(); }
1020- QString appId() const override { return m_appId; }
1021- QString name() const override { return QString(); }
1022- QString comment() const override { return QString(); }
1023- QString icon() const override { return QString(); }
1024- QString exec() const override { return QString(); }
1025- QString path() const override { return QString(); }
1026- QString stageHint() const override { return QString(); }
1027- QString splashTitle() const override { return QString(); }
1028- QString splashImage() const override { return QString(); }
1029- QString splashShowHeader() const override { return QString(); }
1030- QString splashColor() const override { return QString(); }
1031- QString splashColorHeader() const override { return QString(); }
1032- QString splashColorFooter() const override { return QString(); }
1033- Qt::ScreenOrientations supportedOrientations() const override { return Qt::PortraitOrientation; }
1034- bool rotatesWindowContents() const override { return false; }
1035- bool isTouchApp() const override { return true; }
1036- bool loaded() const override { return true; }
1037+ QString file() const override;
1038+ QString appId() const override;
1039+ QString name() const override;
1040+ QString comment() const override;
1041+ QString icon() const override;
1042+ QString exec() const override;
1043+ QString path() const override;
1044+ QString stageHint() const override;
1045+ QString splashTitle() const override;
1046+ QString splashImage() const override;
1047+ QString splashShowHeader() const override;
1048+ QString splashColor() const override;
1049+ QString splashColorHeader() const override;
1050+ QString splashColorFooter() const override;
1051+ Qt::ScreenOrientations supportedOrientations() const override;
1052+ bool rotatesWindowContents() const override;
1053+ bool isTouchApp() const override;
1054+ bool loaded() const override;
1055
1056 QString m_appId;
1057 };
1058
1059=== renamed file 'tests/common/fake_displayconfigurationoutput.h' => 'tests/framework/fake_displayconfigurationoutput.h'
1060=== added file 'tests/framework/fake_mirsurface.cpp'
1061--- tests/framework/fake_mirsurface.cpp 1970-01-01 00:00:00 +0000
1062+++ tests/framework/fake_mirsurface.cpp 2015-12-04 13:04:35 +0000
1063@@ -0,0 +1,212 @@
1064+/*
1065+ * Copyright (C) 2015 Canonical, Ltd.
1066+ *
1067+ * This program is free software: you can redistribute it and/or modify it under
1068+ * the terms of the GNU Lesser General Public License version 3, as published by
1069+ * the Free Software Foundation.
1070+ *
1071+ * This program is distributed in the hope that it will be useful, but WITHOUT
1072+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
1073+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1074+ * Lesser General Public License for more details.
1075+ *
1076+ * You should have received a copy of the GNU Lesser General Public License
1077+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1078+ */
1079+
1080+#include "fake_mirsurface.h"
1081+
1082+namespace qtmir
1083+{
1084+
1085+FakeMirSurface::TouchEvent::TouchEvent(Qt::KeyboardModifiers mods,
1086+ const QList<QTouchEvent::TouchPoint> &points,
1087+ Qt::TouchPointStates states,
1088+ ulong timestamp)
1089+ : keyboardModifiers(mods)
1090+ , touchPoints(points)
1091+ , states(states)
1092+ , timestamp(timestamp)
1093+{
1094+}
1095+
1096+FakeMirSurface::TouchEvent::~TouchEvent()
1097+{
1098+}
1099+
1100+FakeMirSurface::FakeMirSurface(QObject *parent)
1101+ : MirSurfaceInterface(parent)
1102+ , m_isFirstFrameDrawn(false)
1103+ , m_isFrameDropperRunning(true)
1104+ , m_live(true)
1105+ , m_state(Mir::RestoredState)
1106+ , m_orientationAngle(Mir::Angle0)
1107+ , m_visible(true)
1108+ , m_focused(false)
1109+{
1110+}
1111+
1112+FakeMirSurface::~FakeMirSurface()
1113+{
1114+}
1115+
1116+Mir::Type FakeMirSurface::type() const { return Mir::NormalType; }
1117+
1118+QString FakeMirSurface::name() const { return QString("Fake MirSurface"); }
1119+
1120+QSize FakeMirSurface::size() const { return m_size; }
1121+
1122+void FakeMirSurface::resize(int width, int height)
1123+{
1124+ if (m_size.width() != width || m_size.height() != height) {
1125+ m_size.setWidth(width);
1126+ m_size.setHeight(height);
1127+ Q_EMIT sizeChanged(m_size);
1128+ }
1129+}
1130+
1131+void FakeMirSurface::resize(const QSize &size) { resize(size.width(), size.height()); }
1132+
1133+Mir::State FakeMirSurface::state() const { return m_state; }
1134+
1135+void FakeMirSurface::setState(Mir::State qmlState)
1136+{
1137+ if (qmlState != m_state) {
1138+ m_state = qmlState;
1139+ Q_EMIT stateChanged(m_state);
1140+ }
1141+}
1142+
1143+bool FakeMirSurface::live() const { return m_live; }
1144+
1145+bool FakeMirSurface::visible() const { return m_visible; }
1146+
1147+Mir::OrientationAngle FakeMirSurface::orientationAngle() const { return m_orientationAngle; }
1148+
1149+void FakeMirSurface::setOrientationAngle(Mir::OrientationAngle angle)
1150+{
1151+ if (m_orientationAngle != angle) {
1152+ m_orientationAngle = angle;
1153+ Q_EMIT orientationAngleChanged(m_orientationAngle);
1154+ }
1155+}
1156+
1157+bool FakeMirSurface::isFirstFrameDrawn() const
1158+{
1159+ return m_isFirstFrameDrawn;
1160+}
1161+
1162+void FakeMirSurface::stopFrameDropper()
1163+{
1164+ m_isFrameDropperRunning = false;
1165+}
1166+
1167+void FakeMirSurface::startFrameDropper()
1168+{
1169+ m_isFrameDropperRunning = true;
1170+}
1171+
1172+void FakeMirSurface::setLive(bool value)
1173+{
1174+ if (m_live != value) {
1175+ m_live = value;
1176+ Q_EMIT liveChanged(m_live);
1177+ }
1178+}
1179+
1180+void FakeMirSurface::setViewVisibility(qintptr viewId, bool visible) {
1181+ if (!m_views.contains(viewId)) return;
1182+
1183+ m_views[viewId] = visible;
1184+ updateVisibility();
1185+}
1186+
1187+bool FakeMirSurface::isBeingDisplayed() const { return !m_views.isEmpty(); }
1188+
1189+void FakeMirSurface::registerView(qintptr viewId)
1190+{
1191+ m_views.insert(viewId, false);
1192+ if (m_views.count() == 1) {
1193+ Q_EMIT isBeingDisplayedChanged();
1194+ }
1195+}
1196+
1197+void FakeMirSurface::unregisterView(qintptr viewId)
1198+{
1199+ m_views.remove(viewId);
1200+ if (m_views.count() == 0) {
1201+ Q_EMIT isBeingDisplayedChanged();
1202+ }
1203+ updateVisibility();
1204+}
1205+
1206+QSharedPointer<QSGTexture> FakeMirSurface::texture() { return QSharedPointer<QSGTexture>(); }
1207+
1208+QSGTexture *FakeMirSurface::weakTexture() const { return nullptr; }
1209+
1210+bool FakeMirSurface::updateTexture() { return true; }
1211+
1212+unsigned int FakeMirSurface::currentFrameNumber() const { return 0; }
1213+
1214+bool FakeMirSurface::numBuffersReadyForCompositor() { return 0; }
1215+
1216+void FakeMirSurface::setFocus(bool focus) { m_focused = focus; }
1217+
1218+void FakeMirSurface::mousePressEvent(QMouseEvent *) {}
1219+
1220+void FakeMirSurface::mouseMoveEvent(QMouseEvent *) {}
1221+
1222+void FakeMirSurface::mouseReleaseEvent(QMouseEvent *) {}
1223+
1224+void FakeMirSurface::hoverEnterEvent(QHoverEvent *) {}
1225+
1226+void FakeMirSurface::hoverLeaveEvent(QHoverEvent *) {}
1227+
1228+void FakeMirSurface::hoverMoveEvent(QHoverEvent *) {}
1229+
1230+void FakeMirSurface::wheelEvent(QWheelEvent *) {}
1231+
1232+void FakeMirSurface::keyPressEvent(QKeyEvent *) {}
1233+
1234+void FakeMirSurface::keyReleaseEvent(QKeyEvent *) {}
1235+
1236+void FakeMirSurface::touchEvent(Qt::KeyboardModifiers mods,
1237+ const QList<QTouchEvent::TouchPoint> &points,
1238+ Qt::TouchPointStates states,
1239+ ulong timestamp)
1240+{
1241+ m_touchesReceived.append(TouchEvent(mods, points, states, timestamp));
1242+}
1243+
1244+QString FakeMirSurface::appId() const { return "foo-app"; }
1245+
1246+void FakeMirSurface::onCompositorSwappedBuffers() {}
1247+
1248+void FakeMirSurface::drawFirstFrame()
1249+{
1250+ if (!m_isFirstFrameDrawn) {
1251+ m_isFirstFrameDrawn = true;
1252+ Q_EMIT firstFrameDrawn();
1253+ }
1254+}
1255+
1256+bool FakeMirSurface::isFrameDropperRunning() const { return m_isFrameDropperRunning; }
1257+
1258+QList<FakeMirSurface::TouchEvent> &FakeMirSurface::touchesReceived() { return m_touchesReceived; }
1259+
1260+void FakeMirSurface::updateVisibility()
1261+{
1262+ bool newVisible = false;
1263+ QHashIterator<int, bool> i(m_views);
1264+ while (i.hasNext()) {
1265+ i.next();
1266+ newVisible |= i.value();
1267+ }
1268+
1269+ if (m_visible != newVisible) {
1270+ m_visible = newVisible;
1271+ Q_EMIT visibleChanged(newVisible);
1272+ }
1273+}
1274+
1275+} // namespace qtmir
1276
1277=== modified file 'tests/framework/fake_mirsurface.h'
1278--- tests/modules/common/fake_mirsurface.h 2015-11-25 15:38:39 +0000
1279+++ tests/framework/fake_mirsurface.h 2015-12-04 13:04:35 +0000
1280@@ -36,11 +36,8 @@
1281 TouchEvent(Qt::KeyboardModifiers mods,
1282 const QList<QTouchEvent::TouchPoint> &points,
1283 Qt::TouchPointStates states,
1284- ulong timestamp)
1285- : keyboardModifiers(mods)
1286- , touchPoints(points)
1287- , states(states)
1288- , timestamp(timestamp) {}
1289+ ulong timestamp);
1290+ virtual ~TouchEvent();
1291
1292 Qt::KeyboardModifiers keyboardModifiers;
1293 QList<QTouchEvent::TouchPoint> touchPoints;
1294@@ -48,167 +45,89 @@
1295 ulong timestamp;
1296 };
1297
1298-
1299- FakeMirSurface(QObject *parent = nullptr)
1300- : MirSurfaceInterface(parent)
1301- , m_isFirstFrameDrawn(false)
1302- , m_isFrameDropperRunning(true)
1303- , m_live(true)
1304- , m_state(Mir::RestoredState)
1305- , m_orientationAngle(Mir::Angle0)
1306- , m_visible(true)
1307- , m_focused(false)
1308- {}
1309+ FakeMirSurface(QObject *parent = nullptr);
1310+ virtual ~FakeMirSurface();
1311
1312 ////
1313 // unity.shell.application.MirSurfaceInterface
1314- Mir::Type type() const override { return Mir::NormalType; }
1315-
1316- QString name() const override { return QString("Fake MirSurface"); }
1317-
1318- QSize size() const override { return m_size; }
1319-
1320- void resize(int width, int height) override {
1321- if (m_size.width() != width || m_size.height() != height) {
1322- m_size.setWidth(width);
1323- m_size.setHeight(height);
1324- Q_EMIT sizeChanged(m_size);
1325- }
1326- }
1327- void resize(const QSize &size) override { resize(size.width(), size.height()); }
1328-
1329- Mir::State state() const override { return m_state; }
1330- void setState(Mir::State qmlState) override {
1331- if (qmlState != m_state) {
1332- m_state = qmlState;
1333- Q_EMIT stateChanged(m_state);
1334- }
1335- }
1336-
1337- bool live() const override { return m_live; }
1338-
1339- bool visible() const override { return m_visible; }
1340-
1341- Mir::OrientationAngle orientationAngle() const override { return m_orientationAngle; }
1342- void setOrientationAngle(Mir::OrientationAngle angle) override {
1343- if (m_orientationAngle != angle) {
1344- m_orientationAngle = angle;
1345- Q_EMIT orientationAngleChanged(m_orientationAngle);
1346- }
1347- }
1348+ Mir::Type type() const override;
1349+ QString name() const override;
1350+ QSize size() const override;
1351+ void resize(int width, int height) override;
1352+ void resize(const QSize &size) override;
1353+ Mir::State state() const override;
1354+ void setState(Mir::State qmlState) override;
1355+ bool live() const override;
1356+ bool visible() const override;
1357+ Mir::OrientationAngle orientationAngle() const override;
1358+ void setOrientationAngle(Mir::OrientationAngle angle) override;
1359
1360 ////
1361 // qtmir.MirSurfaceInterface
1362
1363- bool isFirstFrameDrawn() const override {
1364- return m_isFirstFrameDrawn;
1365- }
1366-
1367- void stopFrameDropper() override {
1368- m_isFrameDropperRunning = false;
1369- }
1370- void startFrameDropper() override {
1371- m_isFrameDropperRunning = true;
1372- }
1373-
1374- void setLive(bool value) override {
1375- if (m_live != value) {
1376- m_live = value;
1377- Q_EMIT liveChanged(m_live);
1378- }
1379- }
1380-
1381- void setViewVisibility(qintptr viewId, bool visible) override {
1382- if (!m_views.contains(viewId)) return;
1383-
1384- m_views[viewId] = visible;
1385- updateVisibility();
1386- }
1387-
1388- bool isBeingDisplayed() const override { return !m_views.isEmpty(); }
1389-
1390- void registerView(qintptr viewId) override {
1391- m_views.insert(viewId, false);
1392- if (m_views.count() == 1) {
1393- Q_EMIT isBeingDisplayedChanged();
1394- }
1395- }
1396-
1397- void unregisterView(qintptr viewId) override {
1398- m_views.remove(viewId);
1399- if (m_views.count() == 0) {
1400- Q_EMIT isBeingDisplayedChanged();
1401- }
1402- updateVisibility();
1403- }
1404+ bool isFirstFrameDrawn() const override;
1405+ void stopFrameDropper() override;
1406+ void startFrameDropper() override;
1407+ void setLive(bool value) override;
1408+ void setViewVisibility(qintptr viewId, bool visible) override;
1409+ bool isBeingDisplayed() const override;
1410+ void registerView(qintptr viewId) override;
1411+ void unregisterView(qintptr viewId) override;
1412+
1413+ void consumeBuffer() override {}
1414
1415 // methods called from the rendering (scene graph) thread:
1416- QSharedPointer<QSGTexture> texture() override { return QSharedPointer<QSGTexture>(); }
1417- QSGTexture *weakTexture() const override { return nullptr; }
1418- bool updateTexture() override { return true; }
1419- unsigned int currentFrameNumber() const override { return 0; }
1420- bool numBuffersReadyForCompositor() override { return 0; }
1421+ QSharedPointer<QSGTexture> texture() override;
1422+ QSGTexture *weakTexture() const override;
1423+ bool updateTexture() override;
1424+ unsigned int currentFrameNumber() const override;
1425+ bool numBuffersReadyForCompositor() override;
1426 // end of methods called from the rendering (scene graph) thread
1427
1428- void setFocus(bool focus) override { m_focused = focus; }
1429-
1430- void mousePressEvent(QMouseEvent *) override {}
1431- void mouseMoveEvent(QMouseEvent *) override {}
1432- void mouseReleaseEvent(QMouseEvent *) override {}
1433- void hoverEnterEvent(QHoverEvent *) override {}
1434- void hoverLeaveEvent(QHoverEvent *) override {}
1435- void hoverMoveEvent(QHoverEvent *) override {}
1436- void wheelEvent(QWheelEvent *) override {}
1437-
1438- void keyPressEvent(QKeyEvent *) override {}
1439- void keyReleaseEvent(QKeyEvent *) override {}
1440+ void setFocus(bool focus) override;
1441+
1442+ void mousePressEvent(QMouseEvent *) override;
1443+ void mouseMoveEvent(QMouseEvent *) override;
1444+ void mouseReleaseEvent(QMouseEvent *) override;
1445+ void hoverEnterEvent(QHoverEvent *) override;
1446+ void hoverLeaveEvent(QHoverEvent *) override;
1447+ void hoverMoveEvent(QHoverEvent *) override;
1448+ void wheelEvent(QWheelEvent *) override;
1449+ void keyPressEvent(QKeyEvent *) override;
1450+ void keyReleaseEvent(QKeyEvent *) override;
1451
1452 void touchEvent(Qt::KeyboardModifiers mods,
1453 const QList<QTouchEvent::TouchPoint> &points,
1454 Qt::TouchPointStates states,
1455- ulong timestamp) override {
1456- m_touchesReceived.append(TouchEvent(mods, points, states, timestamp));
1457+ ulong timestamp) override;
1458+
1459+ QString appId() const override;
1460+
1461+ void close() override {
1462+ Q_EMIT closeRequested();
1463 }
1464
1465- QString appId() const override { return "foo-app"; }
1466+Q_SIGNALS:
1467+ void closeRequested();
1468
1469 QCursor cursor() const override { return QCursor(); }
1470
1471 public Q_SLOTS:
1472- void onCompositorSwappedBuffers() override {}
1473+ void onCompositorSwappedBuffers() override;
1474
1475 ////
1476 // Test API from now on
1477
1478 public:
1479
1480- void drawFirstFrame() {
1481- if (!m_isFirstFrameDrawn) {
1482- m_isFirstFrameDrawn = true;
1483- Q_EMIT firstFrameDrawn();
1484- }
1485- }
1486-
1487- bool isFrameDropperRunning() const {
1488- return m_isFrameDropperRunning;
1489- }
1490-
1491- QList<TouchEvent> &touchesReceived() { return m_touchesReceived; }
1492+ void drawFirstFrame();
1493+
1494+ bool isFrameDropperRunning() const;
1495+
1496+ QList<TouchEvent> &touchesReceived();
1497
1498 private:
1499- void updateVisibility() {
1500- bool newVisible = false;
1501- QHashIterator<int, bool> i(m_views);
1502- while (i.hasNext()) {
1503- i.next();
1504- newVisible |= i.value();
1505- }
1506-
1507- if (m_visible != newVisible) {
1508- m_visible = newVisible;
1509- Q_EMIT visibleChanged(newVisible);
1510- }
1511- }
1512+ void updateVisibility();
1513
1514
1515 bool m_isFirstFrameDrawn;
1516
1517=== added file 'tests/framework/fake_session.cpp'
1518--- tests/framework/fake_session.cpp 1970-01-01 00:00:00 +0000
1519+++ tests/framework/fake_session.cpp 2015-12-04 13:04:35 +0000
1520@@ -0,0 +1,113 @@
1521+/*
1522+ * Copyright (C) 2015 Canonical, Ltd.
1523+ *
1524+ * This program is free software: you can redistribute it and/or modify it under
1525+ * the terms of the GNU Lesser General Public License version 3, as published by
1526+ * the Free Software Foundation.
1527+ *
1528+ * This program is distributed in the hope that it will be useful, but WITHOUT
1529+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
1530+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1531+ * Lesser General Public License for more details.
1532+ *
1533+ * You should have received a copy of the GNU Lesser General Public License
1534+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1535+ */
1536+
1537+#include "fake_session.h"
1538+
1539+namespace qtmir
1540+{
1541+
1542+FakeSession::FakeSession()
1543+ : SessionInterface(0)
1544+ , m_application(nullptr)
1545+ , m_state(Starting)
1546+{
1547+}
1548+
1549+FakeSession::~FakeSession()
1550+{
1551+}
1552+
1553+void FakeSession::release() {}
1554+
1555+QString FakeSession::name() const { return QString("foo-session"); }
1556+
1557+unity::shell::application::ApplicationInfoInterface *FakeSession::application() const { return m_application; }
1558+
1559+MirSurfaceInterface *FakeSession::surface() const { return nullptr; }
1560+
1561+SessionInterface *FakeSession::parentSession() const { return nullptr; }
1562+
1563+SessionModel *FakeSession::childSessions() const { return nullptr; }
1564+
1565+SessionInterface::State FakeSession::state() const { return m_state; }
1566+
1567+bool FakeSession::fullscreen() const { return false; }
1568+
1569+bool FakeSession::live() const { return true; }
1570+
1571+std::shared_ptr<mir::scene::Session> FakeSession::session() const { return nullptr; }
1572+
1573+void FakeSession::setSurface(MirSurfaceInterface *) {}
1574+
1575+void FakeSession::setApplication(unity::shell::application::ApplicationInfoInterface *app)
1576+{
1577+ if (m_application != app) {
1578+ m_application = app;
1579+ Q_EMIT applicationChanged(m_application);
1580+ }
1581+}
1582+
1583+void FakeSession::suspend()
1584+{
1585+ if (m_state == Running) {
1586+ setState(Suspending);
1587+ }
1588+}
1589+
1590+void FakeSession::resume()
1591+{
1592+ if (m_state == Suspending || m_state == Suspended) {
1593+ setState(Running);
1594+ }
1595+}
1596+
1597+void FakeSession::stop()
1598+{
1599+ setState(Stopped);
1600+}
1601+
1602+void FakeSession::addChildSession(SessionInterface *) {}
1603+
1604+void FakeSession::insertChildSession(uint, SessionInterface *) {}
1605+
1606+void FakeSession::removeChildSession(SessionInterface *) {}
1607+
1608+void FakeSession::foreachChildSession(std::function<void (SessionInterface *)>) const {}
1609+
1610+std::shared_ptr<mir::scene::PromptSession> FakeSession::activePromptSession() const
1611+{
1612+ return std::shared_ptr<mir::scene::PromptSession>();
1613+}
1614+
1615+void FakeSession::foreachPromptSession(std::function<void (const std::shared_ptr<mir::scene::PromptSession> &)>) const {}
1616+
1617+void FakeSession::setFullscreen(bool) {}
1618+
1619+void FakeSession::setLive(const bool) {}
1620+
1621+void FakeSession::appendPromptSession(const std::shared_ptr<mir::scene::PromptSession> &) {}
1622+
1623+void FakeSession::removePromptSession(const std::shared_ptr<mir::scene::PromptSession> &) {}
1624+
1625+void FakeSession::setState(SessionInterface::State state)
1626+{
1627+ if (m_state != state) {
1628+ m_state = state;
1629+ Q_EMIT stateChanged(m_state);
1630+ }
1631+}
1632+
1633+} // namespace qtmir
1634
1635=== modified file 'tests/framework/fake_session.h'
1636--- tests/modules/common/fake_session.h 2015-10-20 09:57:17 +0000
1637+++ tests/framework/fake_session.h 2015-12-04 13:04:35 +0000
1638@@ -15,6 +15,7 @@
1639 */
1640
1641 #include <Unity/Application/session_interface.h>
1642+#include <QDebug>
1643
1644 #ifndef QTMIR_FAKE_SESSION_H
1645 #define QTMIR_FAKE_SESSION_H
1646@@ -26,78 +27,55 @@
1647 Q_OBJECT
1648
1649 public:
1650- FakeSession()
1651- : SessionInterface(0)
1652- , m_application(nullptr)
1653- , m_state(Starting)
1654- {
1655- }
1656+ FakeSession();
1657+ virtual ~FakeSession();
1658
1659 // For QML use
1660- void release() override {}
1661-
1662- QString name() const override { return QString("foo-session"); }
1663- unity::shell::application::ApplicationInfoInterface* application() const override { return m_application; }
1664- MirSurfaceInterface* surface() const override { return nullptr; }
1665- SessionInterface* parentSession() const override { return nullptr; }
1666- SessionModel* childSessions() const override { return nullptr; }
1667- State state() const override { return m_state; }
1668- bool fullscreen() const override { return false; }
1669- bool live() const override { return true; }
1670-
1671- std::shared_ptr<mir::scene::Session> session() const override { return nullptr; }
1672+ void release() override;
1673+
1674+ QString name() const override;
1675+ unity::shell::application::ApplicationInfoInterface* application() const override;
1676+ MirSurfaceInterface* surface() const override;
1677+ SessionInterface* parentSession() const override;
1678+ SessionModel* childSessions() const override;
1679+ State state() const override;
1680+ bool fullscreen() const override;
1681+ bool live() const override;
1682+
1683+ std::shared_ptr<mir::scene::Session> session() const override;
1684
1685 // For MirSurfaceItem and MirSurfaceManager use
1686
1687- void setSurface(MirSurfaceInterface*) override {}
1688+ void setSurface(MirSurfaceInterface*) override;
1689
1690 // For Application use
1691
1692- void setApplication(unity::shell::application::ApplicationInfoInterface* app) override {
1693- if (m_application != app) {
1694- m_application = app;
1695- Q_EMIT applicationChanged(m_application);
1696- }
1697- }
1698- void suspend() override {
1699- if (m_state == Running) {
1700- setState(Suspending);
1701- }
1702- }
1703- void resume() override {
1704- if (m_state == Suspending || m_state == Suspended) {
1705- setState(Running);
1706- }
1707- }
1708- void stop() override {
1709- setState(Stopped);
1710+ void setApplication(unity::shell::application::ApplicationInfoInterface* app) override;
1711+ void suspend() override;
1712+ void resume() override;
1713+ void stop() override;
1714+
1715+ void close() override {
1716 }
1717
1718 // For SessionManager use
1719
1720- void addChildSession(SessionInterface*) override {}
1721- void insertChildSession(uint, SessionInterface*) override {}
1722- void removeChildSession(SessionInterface*) override {}
1723- void foreachChildSession(std::function<void(SessionInterface* session)>) const override {}
1724-
1725- std::shared_ptr<mir::scene::PromptSession> activePromptSession() const override {
1726- return std::shared_ptr<mir::scene::PromptSession>();
1727- }
1728- void foreachPromptSession(std::function<void(const std::shared_ptr<mir::scene::PromptSession>&)>) const override {}
1729-
1730- void setFullscreen(bool) override {}
1731- void setLive(const bool) override {}
1732- void appendPromptSession(const std::shared_ptr<mir::scene::PromptSession>&) override {}
1733- void removePromptSession(const std::shared_ptr<mir::scene::PromptSession>&) override {}
1734+ void addChildSession(SessionInterface*) override;
1735+ void insertChildSession(uint, SessionInterface*) override;
1736+ void removeChildSession(SessionInterface*) override;
1737+ void foreachChildSession(std::function<void(SessionInterface* session)>) const override;
1738+
1739+ std::shared_ptr<mir::scene::PromptSession> activePromptSession() const override;
1740+ void foreachPromptSession(std::function<void(const std::shared_ptr<mir::scene::PromptSession>&)>) const override;
1741+
1742+ void setFullscreen(bool) override;
1743+ void setLive(const bool) override;
1744+ void appendPromptSession(const std::shared_ptr<mir::scene::PromptSession>&) override;
1745+ void removePromptSession(const std::shared_ptr<mir::scene::PromptSession>&) override;
1746
1747 // For tests
1748
1749- void setState(State state) {
1750- if (m_state != state) {
1751- m_state = state;
1752- Q_EMIT stateChanged(m_state);
1753- }
1754- }
1755+ void setState(State state);
1756
1757 private:
1758 unity::shell::application::ApplicationInfoInterface* m_application;
1759
1760=== renamed file 'tests/common/gmock_fixes.h' => 'tests/framework/gmock_fixes.h'
1761=== added file 'tests/framework/mock_application_controller.cpp'
1762--- tests/framework/mock_application_controller.cpp 1970-01-01 00:00:00 +0000
1763+++ tests/framework/mock_application_controller.cpp 2015-12-04 13:04:35 +0000
1764@@ -0,0 +1,129 @@
1765+/*
1766+ * Copyright (C) 2015 Canonical, Ltd.
1767+ *
1768+ * This program is free software: you can redistribute it and/or modify it under
1769+ * the terms of the GNU Lesser General Public License version 3, as published by
1770+ * the Free Software Foundation.
1771+ *
1772+ * This program is distributed in the hope that it will be useful, but WITHOUT
1773+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
1774+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1775+ * Lesser General Public License for more details.
1776+ *
1777+ * You should have received a copy of the GNU Lesser General Public License
1778+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1779+ */
1780+
1781+#include "mock_application_controller.h"
1782+
1783+namespace qtmir
1784+{
1785+
1786+MockApplicationController::MockApplicationController()
1787+{
1788+ using namespace ::testing;
1789+ ON_CALL(*this, primaryPidForAppId(_))
1790+ .WillByDefault(
1791+ Invoke(this, &MockApplicationController::doPrimaryPidForAppId));
1792+
1793+ ON_CALL(*this, appIdHasProcessId(_, _))
1794+ .WillByDefault(
1795+ Invoke(this, &MockApplicationController::doAppIdHasProcessId));
1796+
1797+ ON_CALL(*this, findDesktopFileForAppId(_))
1798+ .WillByDefault(
1799+ Invoke(this, &MockApplicationController::doFindDesktopFileForAppId));
1800+
1801+ ON_CALL(*this, stopApplicationWithAppId(_))
1802+ .WillByDefault(
1803+ Invoke(this, &MockApplicationController::doStopApplicationWithAppId));
1804+
1805+ ON_CALL(*this, startApplicationWithAppIdAndArgs(_, _))
1806+ .WillByDefault(
1807+ Invoke(this, &MockApplicationController::doStartApplicationWithAppIdAndArgs));
1808+
1809+ ON_CALL(*this, pauseApplicationWithAppId(_))
1810+ .WillByDefault(
1811+ Invoke(this, &MockApplicationController::doPauseApplicationWithAppId));
1812+
1813+ ON_CALL(*this, resumeApplicationWithAppId(_))
1814+ .WillByDefault(
1815+ Invoke(this, &MockApplicationController::doResumeApplicationWithAppId));
1816+}
1817+
1818+MockApplicationController::~MockApplicationController()
1819+{
1820+
1821+}
1822+
1823+pid_t MockApplicationController::doPrimaryPidForAppId(const QString &appId)
1824+{
1825+ auto it = children.find(appId);
1826+ if (it == children.end())
1827+ return -1;
1828+
1829+ return it->pid();
1830+}
1831+
1832+
1833+bool MockApplicationController::doAppIdHasProcessId(pid_t pid, const QString &appId)
1834+{
1835+ auto it = children.find(appId);
1836+ if (it == children.end())
1837+ return -1;
1838+
1839+ return it->pid() == pid;
1840+}
1841+
1842+
1843+QFileInfo MockApplicationController::doFindDesktopFileForAppId(const QString &appId) const
1844+{
1845+ QString path = QString("/usr/share/applications/%1.desktop").arg(appId);
1846+ return QFileInfo(path);
1847+}
1848+
1849+
1850+bool MockApplicationController::doStopApplicationWithAppId(const QString &appId)
1851+{
1852+ Q_UNUSED(appId);
1853+
1854+ return false;
1855+}
1856+
1857+
1858+bool MockApplicationController::doStartApplicationWithAppIdAndArgs(const QString &appId, const QStringList &args)
1859+{
1860+ Q_UNUSED(args);
1861+
1862+ auto child = core::posix::fork([]()
1863+ {
1864+ while (true);
1865+
1866+ return core::posix::exit::Status::success;
1867+ }, core::posix::StandardStream::empty);
1868+
1869+ if (child.pid() > 0)
1870+ {
1871+ children.insert(appId, child);
1872+ return true;
1873+ }
1874+
1875+ return false;
1876+}
1877+
1878+
1879+bool MockApplicationController::doPauseApplicationWithAppId(const QString &appId)
1880+{
1881+ Q_UNUSED(appId);
1882+
1883+ return false;
1884+}
1885+
1886+bool MockApplicationController::doResumeApplicationWithAppId(const QString &appId)
1887+{
1888+ Q_UNUSED(appId);
1889+
1890+ return false;
1891+}
1892+
1893+} // namespace qtmir
1894
1895=== modified file 'tests/framework/mock_application_controller.h'
1896--- tests/modules/common/mock_application_controller.h 2015-08-11 12:08:32 +0000
1897+++ tests/framework/mock_application_controller.h 2015-12-04 13:04:35 +0000
1898@@ -18,15 +18,19 @@
1899 #define MOCK_APPLICATION_CONTROLLER_H
1900
1901 #include <Unity/Application/applicationcontroller.h>
1902+#include <QMap>
1903
1904 #include <core/posix/fork.h>
1905
1906 #include <gmock/gmock.h>
1907
1908-namespace testing
1909+namespace qtmir
1910 {
1911 struct MockApplicationController : public qtmir::ApplicationController
1912 {
1913+ MockApplicationController();
1914+ virtual ~MockApplicationController();
1915+
1916 MOCK_METHOD1(primaryPidForAppId, pid_t(const QString& appId));
1917 MOCK_METHOD2(appIdHasProcessId, bool(pid_t, const QString&));
1918 MOCK_CONST_METHOD1(findDesktopFileForAppId, QFileInfo(const QString &appId));
1919@@ -36,105 +40,24 @@
1920 MOCK_METHOD1(pauseApplicationWithAppId, bool(const QString&));
1921 MOCK_METHOD1(resumeApplicationWithAppId, bool(const QString&));
1922
1923- MockApplicationController()
1924- {
1925- using namespace ::testing;
1926- ON_CALL(*this, primaryPidForAppId(_))
1927- .WillByDefault(
1928- Invoke(this, &MockApplicationController::doPrimaryPidForAppId));
1929-
1930- ON_CALL(*this, appIdHasProcessId(_, _))
1931- .WillByDefault(
1932- Invoke(this, &MockApplicationController::doAppIdHasProcessId));
1933-
1934- ON_CALL(*this, findDesktopFileForAppId(_))
1935- .WillByDefault(
1936- Invoke(this, &MockApplicationController::doFindDesktopFileForAppId));
1937-
1938- ON_CALL(*this, stopApplicationWithAppId(_))
1939- .WillByDefault(
1940- Invoke(this, &MockApplicationController::doStopApplicationWithAppId));
1941-
1942- ON_CALL(*this, startApplicationWithAppIdAndArgs(_, _))
1943- .WillByDefault(
1944- Invoke(this, &MockApplicationController::doStartApplicationWithAppIdAndArgs));
1945-
1946- ON_CALL(*this, pauseApplicationWithAppId(_))
1947- .WillByDefault(
1948- Invoke(this, &MockApplicationController::doPauseApplicationWithAppId));
1949-
1950- ON_CALL(*this, resumeApplicationWithAppId(_))
1951- .WillByDefault(
1952- Invoke(this, &MockApplicationController::doResumeApplicationWithAppId));
1953- }
1954-
1955- pid_t doPrimaryPidForAppId(const QString& appId)
1956- {
1957- auto it = children.find(appId);
1958- if (it == children.end())
1959- return -1;
1960-
1961- return it->pid();
1962- }
1963-
1964- bool doAppIdHasProcessId(pid_t pid, const QString& appId)
1965- {
1966- auto it = children.find(appId);
1967- if (it == children.end())
1968- return -1;
1969-
1970- return it->pid() == pid;
1971- }
1972-
1973- QFileInfo doFindDesktopFileForAppId(const QString& appId) const
1974- {
1975- QString path = QString("/usr/share/applications/%1.desktop").arg(appId);
1976- return QFileInfo(path);
1977- }
1978-
1979- bool doStopApplicationWithAppId(const QString& appId)
1980- {
1981- Q_UNUSED(appId);
1982-
1983- return false;
1984- }
1985-
1986- bool doStartApplicationWithAppIdAndArgs(const QString& appId, const QStringList& args)
1987- {
1988- Q_UNUSED(args);
1989-
1990- auto child = core::posix::fork([]()
1991- {
1992- while (true);
1993-
1994- return core::posix::exit::Status::success;
1995- }, core::posix::StandardStream::empty);
1996-
1997- if (child.pid() > 0)
1998- {
1999- children.insert(appId, child);
2000- return true;
2001- }
2002-
2003- return false;
2004- }
2005-
2006- bool doPauseApplicationWithAppId(const QString& appId)
2007- {
2008- Q_UNUSED(appId);
2009-
2010- return false;
2011- }
2012-
2013- bool doResumeApplicationWithAppId(const QString& appId)
2014- {
2015- Q_UNUSED(appId);
2016-
2017- return false;
2018- }
2019-
2020+ pid_t doPrimaryPidForAppId(const QString& appId);
2021+
2022+ bool doAppIdHasProcessId(pid_t pid, const QString& appId);
2023+
2024+ QFileInfo doFindDesktopFileForAppId(const QString& appId) const;
2025+
2026+ bool doStopApplicationWithAppId(const QString& appId);
2027+
2028+ bool doStartApplicationWithAppIdAndArgs(const QString& appId, const QStringList& args);
2029+
2030+ bool doPauseApplicationWithAppId(const QString& appId);
2031+
2032+ bool doResumeApplicationWithAppId(const QString& appId);
2033+
2034+private:
2035 QMap<QString, core::posix::ChildProcess> children;
2036 };
2037-} // namespace testing
2038+
2039+} // namespace qtmir
2040
2041 #endif // MOCK_APPLICATION_CONTROLLER_H
2042
2043=== added file 'tests/framework/mock_desktop_file_reader.cpp'
2044--- tests/framework/mock_desktop_file_reader.cpp 1970-01-01 00:00:00 +0000
2045+++ tests/framework/mock_desktop_file_reader.cpp 2015-12-04 13:04:35 +0000
2046@@ -0,0 +1,117 @@
2047+/*
2048+ * Copyright (C) 2015 Canonical, Ltd.
2049+ *
2050+ * This program is free software: you can redistribute it and/or modify it under
2051+ * the terms of the GNU Lesser General Public License version 3, as published by
2052+ * the Free Software Foundation.
2053+ *
2054+ * This program is distributed in the hope that it will be useful, but WITHOUT
2055+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
2056+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2057+ * Lesser General Public License for more details.
2058+ *
2059+ * You should have received a copy of the GNU Lesser General Public License
2060+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2061+ */
2062+
2063+#include "mock_desktop_file_reader.h"
2064+
2065+namespace qtmir
2066+{
2067+
2068+MockDesktopFileReader::MockDesktopFileReader(const QString &appId, const QFileInfo &fileInfo)
2069+ : DesktopFileReader(appId, fileInfo)
2070+{
2071+ using namespace ::testing;
2072+
2073+ ON_CALL(*this, file()).WillByDefault(Invoke(this, &MockDesktopFileReader::doFile));
2074+ ON_CALL(*this, appId()).WillByDefault(Invoke(this, &MockDesktopFileReader::doAppId));
2075+ ON_CALL(*this, name()).WillByDefault(Invoke(this, &MockDesktopFileReader::doName));
2076+ ON_CALL(*this, comment()).WillByDefault(Invoke(this, &MockDesktopFileReader::doComment));
2077+ ON_CALL(*this, icon()).WillByDefault(Invoke(this, &MockDesktopFileReader::doIcon));
2078+ ON_CALL(*this, exec()).WillByDefault(Invoke(this, &MockDesktopFileReader::doExec));
2079+ ON_CALL(*this, path()).WillByDefault(Invoke(this, &MockDesktopFileReader::doPath));
2080+ ON_CALL(*this, stageHint()).WillByDefault(Invoke(this, &MockDesktopFileReader::doStageHint));
2081+ ON_CALL(*this, isTouchApp()).WillByDefault(Invoke(this, &MockDesktopFileReader::doIsTouchApp));
2082+ ON_CALL(*this, loaded()).WillByDefault(Invoke(this, &MockDesktopFileReader::doLoaded));
2083+}
2084+
2085+MockDesktopFileReader::~MockDesktopFileReader()
2086+{
2087+}
2088+
2089+QString MockDesktopFileReader::doFile() const
2090+{
2091+ return DesktopFileReader::file();
2092+}
2093+
2094+QString MockDesktopFileReader::doAppId() const
2095+{
2096+ return DesktopFileReader::appId();
2097+}
2098+
2099+QString MockDesktopFileReader::doName() const
2100+{
2101+ return DesktopFileReader::name();
2102+}
2103+
2104+QString MockDesktopFileReader::doComment() const
2105+{
2106+ return DesktopFileReader::comment();
2107+}
2108+
2109+QString MockDesktopFileReader::doIcon() const
2110+{
2111+ return DesktopFileReader::icon();
2112+}
2113+
2114+QString MockDesktopFileReader::doExec() const
2115+{
2116+ return DesktopFileReader::exec();
2117+}
2118+
2119+QString MockDesktopFileReader::doPath() const
2120+{
2121+ return DesktopFileReader::path();
2122+}
2123+
2124+QString MockDesktopFileReader::doStageHint() const
2125+{
2126+ return DesktopFileReader::stageHint();
2127+}
2128+
2129+bool MockDesktopFileReader::doIsTouchApp() const
2130+{
2131+ return DesktopFileReader::isTouchApp();
2132+}
2133+
2134+bool MockDesktopFileReader::doLoaded() const
2135+{
2136+ return DesktopFileReader::loaded();
2137+}
2138+
2139+
2140+MockDesktopFileReaderFactory::MockDesktopFileReaderFactory()
2141+{
2142+ using namespace ::testing;
2143+ ON_CALL(*this, createInstance(_, _))
2144+ .WillByDefault(
2145+ Invoke(
2146+ this,
2147+ &MockDesktopFileReaderFactory::doCreateInstance));
2148+}
2149+
2150+MockDesktopFileReaderFactory::~MockDesktopFileReaderFactory()
2151+{
2152+}
2153+
2154+qtmir::DesktopFileReader *MockDesktopFileReaderFactory::doCreateInstance(const QString &appId, const QFileInfo &fi)
2155+{
2156+ using namespace ::testing;
2157+ auto instance = new NiceMock<MockDesktopFileReader>(appId, fi);
2158+ ON_CALL(*instance, loaded()).WillByDefault(Return(true));
2159+
2160+ return instance;
2161+}
2162+
2163+} // namespace qtmir
2164
2165=== modified file 'tests/framework/mock_desktop_file_reader.h'
2166--- tests/modules/common/mock_desktop_file_reader.h 2015-09-29 18:27:27 +0000
2167+++ tests/framework/mock_desktop_file_reader.h 2015-12-04 13:04:35 +0000
2168@@ -21,26 +21,13 @@
2169
2170 #include <gmock/gmock.h>
2171
2172-namespace testing
2173+namespace qtmir
2174 {
2175+
2176 struct MockDesktopFileReader : public qtmir::DesktopFileReader
2177 {
2178- MockDesktopFileReader(const QString &appId, const QFileInfo& fileInfo)
2179- : DesktopFileReader(appId, fileInfo)
2180- {
2181- using namespace ::testing;
2182-
2183- ON_CALL(*this, file()).WillByDefault(Invoke(this, &MockDesktopFileReader::doFile));
2184- ON_CALL(*this, appId()).WillByDefault(Invoke(this, &MockDesktopFileReader::doAppId));
2185- ON_CALL(*this, name()).WillByDefault(Invoke(this, &MockDesktopFileReader::doName));
2186- ON_CALL(*this, comment()).WillByDefault(Invoke(this, &MockDesktopFileReader::doComment));
2187- ON_CALL(*this, icon()).WillByDefault(Invoke(this, &MockDesktopFileReader::doIcon));
2188- ON_CALL(*this, exec()).WillByDefault(Invoke(this, &MockDesktopFileReader::doExec));
2189- ON_CALL(*this, path()).WillByDefault(Invoke(this, &MockDesktopFileReader::doPath));
2190- ON_CALL(*this, stageHint()).WillByDefault(Invoke(this, &MockDesktopFileReader::doStageHint));
2191- ON_CALL(*this, isTouchApp()).WillByDefault(Invoke(this, &MockDesktopFileReader::doIsTouchApp));
2192- ON_CALL(*this, loaded()).WillByDefault(Invoke(this, &MockDesktopFileReader::doLoaded));
2193- }
2194+ MockDesktopFileReader(const QString &appId, const QFileInfo& fileInfo);
2195+ virtual ~MockDesktopFileReader();
2196
2197 MOCK_CONST_METHOD0(file, QString());
2198 MOCK_CONST_METHOD0(appId, QString ());
2199@@ -53,80 +40,28 @@
2200 MOCK_CONST_METHOD0(isTouchApp, bool());
2201 MOCK_CONST_METHOD0(loaded, bool());
2202
2203- QString doFile() const
2204- {
2205- return DesktopFileReader::file();
2206- }
2207-
2208- QString doAppId() const
2209- {
2210- return DesktopFileReader::appId();
2211- }
2212-
2213- QString doName() const
2214- {
2215- return DesktopFileReader::name();
2216- }
2217-
2218- QString doComment() const
2219- {
2220- return DesktopFileReader::comment();
2221- }
2222-
2223- QString doIcon() const
2224- {
2225- return DesktopFileReader::icon();
2226- }
2227-
2228- QString doExec() const
2229- {
2230- return DesktopFileReader::exec();
2231- }
2232-
2233- QString doPath() const
2234- {
2235- return DesktopFileReader::path();
2236- }
2237-
2238- QString doStageHint() const
2239- {
2240- return DesktopFileReader::stageHint();
2241- }
2242-
2243- bool doIsTouchApp() const
2244- {
2245- return DesktopFileReader::isTouchApp();
2246- }
2247-
2248- bool doLoaded() const
2249- {
2250- return DesktopFileReader::loaded();
2251- }
2252+ QString doFile() const;
2253+ QString doAppId() const;
2254+ QString doName() const;
2255+ QString doComment() const;
2256+ QString doIcon() const;
2257+ QString doExec() const;
2258+ QString doPath() const;
2259+ QString doStageHint() const;
2260+ bool doIsTouchApp() const;
2261+ bool doLoaded() const;
2262 };
2263
2264 struct MockDesktopFileReaderFactory : public qtmir::DesktopFileReader::Factory
2265 {
2266- MockDesktopFileReaderFactory()
2267- {
2268- using namespace ::testing;
2269- ON_CALL(*this, createInstance(_, _))
2270- .WillByDefault(
2271- Invoke(
2272- this,
2273- &MockDesktopFileReaderFactory::doCreateInstance));
2274- }
2275-
2276- virtual qtmir::DesktopFileReader* doCreateInstance(const QString &appId, const QFileInfo &fi)
2277- {
2278- using namespace ::testing;
2279- auto instance = new NiceMock<MockDesktopFileReader>(appId, fi);
2280- ON_CALL(*instance, loaded()).WillByDefault(Return(true));
2281-
2282- return instance;
2283- }
2284+ MockDesktopFileReaderFactory();
2285+ virtual ~MockDesktopFileReaderFactory();
2286+
2287+ virtual qtmir::DesktopFileReader* doCreateInstance(const QString &appId, const QFileInfo &fi);
2288
2289 MOCK_METHOD2(createInstance, qtmir::DesktopFileReader*(const QString &appId, const QFileInfo &fi));
2290 };
2291-}
2292+
2293+} // namespace qtmir
2294
2295 #endif // MOCK_DESKTOP_FILE_READER_H
2296
2297=== added file 'tests/framework/mock_display.cpp'
2298--- tests/framework/mock_display.cpp 1970-01-01 00:00:00 +0000
2299+++ tests/framework/mock_display.cpp 2015-12-04 13:04:35 +0000
2300@@ -0,0 +1,35 @@
2301+/*
2302+ * Copyright (C) 2015 Canonical, Ltd.
2303+ *
2304+ * This program is free software: you can redistribute it and/or modify it under
2305+ * the terms of the GNU Lesser General Public License version 3, as published by
2306+ * the Free Software Foundation.
2307+ *
2308+ * This program is distributed in the hope that it will be useful, but WITHOUT
2309+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
2310+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2311+ * Lesser General Public License for more details.
2312+ *
2313+ * You should have received a copy of the GNU Lesser General Public License
2314+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2315+ */
2316+
2317+#include "mock_display.h"
2318+#include <mir/graphics/event_handler_register.h>
2319+#include <mir/graphics/display_configuration.h>
2320+
2321+MockDisplaySyncGroup::MockDisplaySyncGroup()
2322+{
2323+}
2324+
2325+MockDisplaySyncGroup::~MockDisplaySyncGroup()
2326+{
2327+}
2328+
2329+MockDisplay::MockDisplay()
2330+{
2331+}
2332+
2333+MockDisplay::~MockDisplay()
2334+{
2335+}
2336
2337=== renamed file 'tests/common/mock_display.h' => 'tests/framework/mock_display.h'
2338--- tests/common/mock_display.h 2015-08-20 10:16:54 +0000
2339+++ tests/framework/mock_display.h 2015-12-04 13:04:35 +0000
2340@@ -26,6 +26,9 @@
2341 class MockDisplaySyncGroup : public mir::graphics::DisplaySyncGroup
2342 {
2343 public:
2344+ MockDisplaySyncGroup();
2345+ virtual ~MockDisplaySyncGroup();
2346+
2347 MOCK_METHOD1(for_each_display_buffer, void(std::function<void(mir::graphics::DisplayBuffer&)> const& f));
2348 MOCK_METHOD0(post, void());
2349 };
2350@@ -33,6 +36,9 @@
2351 struct MockDisplay : public mir::graphics::Display
2352 {
2353 public:
2354+ MockDisplay();
2355+ virtual ~MockDisplay();
2356+
2357 MOCK_METHOD1(for_each_display_sync_group, void(std::function<void(mir::graphics::DisplaySyncGroup&)> const&));
2358 MOCK_CONST_METHOD0(configuration, std::unique_ptr<mir::graphics::DisplayConfiguration>());
2359 MOCK_METHOD1(configure, void(mir::graphics::DisplayConfiguration const&));
2360@@ -48,6 +54,4 @@
2361 MOCK_METHOD0(create_gl_context, std::unique_ptr<mir::graphics::GLContext>());
2362 };
2363
2364-
2365-
2366 #endif // MOCKDISPLAY_H
2367
2368=== added file 'tests/framework/mock_display_configuration.cpp'
2369--- tests/framework/mock_display_configuration.cpp 1970-01-01 00:00:00 +0000
2370+++ tests/framework/mock_display_configuration.cpp 2015-12-04 13:04:35 +0000
2371@@ -0,0 +1,25 @@
2372+/*
2373+ * Copyright (C) 2015 Canonical, Ltd.
2374+ *
2375+ * This program is free software: you can redistribute it and/or modify it under
2376+ * the terms of the GNU Lesser General Public License version 3, as published by
2377+ * the Free Software Foundation.
2378+ *
2379+ * This program is distributed in the hope that it will be useful, but WITHOUT
2380+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
2381+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2382+ * Lesser General Public License for more details.
2383+ *
2384+ * You should have received a copy of the GNU Lesser General Public License
2385+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2386+ */
2387+
2388+#include "mock_display_configuration.h"
2389+
2390+MockDisplayConfiguration::MockDisplayConfiguration()
2391+{
2392+}
2393+
2394+MockDisplayConfiguration::~MockDisplayConfiguration()
2395+{
2396+}
2397
2398=== renamed file 'tests/common/mock_display_configuration.h' => 'tests/framework/mock_display_configuration.h'
2399--- tests/common/mock_display_configuration.h 2015-08-20 10:16:54 +0000
2400+++ tests/framework/mock_display_configuration.h 2015-12-04 13:04:35 +0000
2401@@ -25,6 +25,9 @@
2402 class MockDisplayConfiguration : public mir::graphics::DisplayConfiguration
2403 {
2404 public:
2405+ MockDisplayConfiguration();
2406+ virtual ~MockDisplayConfiguration();
2407+
2408 MOCK_CONST_METHOD1(for_each_card, void(std::function<void(mir::graphics::DisplayConfigurationCard const&)>));
2409
2410 MOCK_CONST_METHOD1(for_each_output, void(std::function<void(mir::graphics::DisplayConfigurationOutput const&)>));
2411@@ -32,4 +35,5 @@
2412
2413 MOCK_CONST_METHOD0(valid, bool());
2414 };
2415+
2416 #endif // MOCK_DISPLAY_CONFIGURATION_H
2417
2418=== added file 'tests/framework/mock_gl_display_buffer.cpp'
2419--- tests/framework/mock_gl_display_buffer.cpp 1970-01-01 00:00:00 +0000
2420+++ tests/framework/mock_gl_display_buffer.cpp 2015-12-04 13:04:35 +0000
2421@@ -0,0 +1,30 @@
2422+/*
2423+ * Copyright (C) 2015 Canonical, Ltd.
2424+ *
2425+ * This program is free software: you can redistribute it and/or modify it under
2426+ * the terms of the GNU Lesser General Public License version 3, as published by
2427+ * the Free Software Foundation.
2428+ *
2429+ * This program is distributed in the hope that it will be useful, but WITHOUT
2430+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
2431+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2432+ * Lesser General Public License for more details.
2433+ *
2434+ * You should have received a copy of the GNU Lesser General Public License
2435+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2436+ */
2437+
2438+#include "mock_gl_display_buffer.h"
2439+
2440+MockGLDisplayBuffer::MockGLDisplayBuffer()
2441+{
2442+ using namespace testing;
2443+ ON_CALL(*this, view_area())
2444+ .WillByDefault(Return(mir::geometry::Rectangle{{0,0},{0,0}}));
2445+ ON_CALL(*this, native_display_buffer())
2446+ .WillByDefault(Return(dynamic_cast<mir::graphics::NativeDisplayBuffer*>(this)));
2447+}
2448+
2449+MockGLDisplayBuffer::~MockGLDisplayBuffer()
2450+{
2451+}
2452
2453=== renamed file 'tests/common/mock_gl_display_buffer.h' => 'tests/framework/mock_gl_display_buffer.h'
2454--- tests/common/mock_gl_display_buffer.h 2015-10-14 23:14:48 +0000
2455+++ tests/framework/mock_gl_display_buffer.h 2015-12-04 13:04:35 +0000
2456@@ -27,14 +27,9 @@
2457 public mir::graphics::NativeDisplayBuffer
2458 {
2459 public:
2460- MockGLDisplayBuffer()
2461- {
2462- using namespace testing;
2463- ON_CALL(*this, view_area())
2464- .WillByDefault(Return(mir::geometry::Rectangle{{0,0},{0,0}}));
2465- ON_CALL(*this, native_display_buffer())
2466- .WillByDefault(Return(dynamic_cast<mir::graphics::NativeDisplayBuffer*>(this)));
2467- }
2468+ MockGLDisplayBuffer();
2469+ virtual ~MockGLDisplayBuffer();
2470+
2471 MOCK_CONST_METHOD0(view_area, mir::geometry::Rectangle());
2472 MOCK_METHOD1(post_renderables_if_optimizable, bool(mir::graphics::RenderableList const&));
2473 MOCK_CONST_METHOD0(orientation, MirOrientation());
2474@@ -45,5 +40,4 @@
2475 MOCK_METHOD0(swap_buffers, void());
2476 };
2477
2478-
2479 #endif // MOCK_GL_DISPLAY_BUFFER_H
2480
2481=== added file 'tests/framework/mock_main_loop.cpp'
2482--- tests/framework/mock_main_loop.cpp 1970-01-01 00:00:00 +0000
2483+++ tests/framework/mock_main_loop.cpp 2015-12-04 13:04:35 +0000
2484@@ -0,0 +1,28 @@
2485+/*
2486+ * Copyright (C) 2015 Canonical, Ltd.
2487+ *
2488+ * This program is free software: you can redistribute it and/or modify it under
2489+ * the terms of the GNU Lesser General Public License version 3, as published by
2490+ * the Free Software Foundation.
2491+ *
2492+ * This program is distributed in the hope that it will be useful, but WITHOUT
2493+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
2494+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2495+ * Lesser General Public License for more details.
2496+ *
2497+ * You should have received a copy of the GNU Lesser General Public License
2498+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2499+ */
2500+
2501+#include "mock_main_loop.h"
2502+
2503+MockMainLoop::MockMainLoop()
2504+{
2505+}
2506+
2507+MockMainLoop::~MockMainLoop()
2508+{
2509+}
2510+
2511+void MockMainLoop::run() {}
2512+void MockMainLoop::stop() {}
2513\ No newline at end of file
2514
2515=== renamed file 'tests/common/mock_main_loop.h' => 'tests/framework/mock_main_loop.h'
2516--- tests/common/mock_main_loop.h 2015-08-20 10:16:54 +0000
2517+++ tests/framework/mock_main_loop.h 2015-12-04 13:04:35 +0000
2518@@ -17,19 +17,17 @@
2519 #ifndef MOCKMAINLOOP_H
2520 #define MOCKMAINLOOP_H
2521
2522-#include <gmock/gmock.h>
2523-
2524 #include <mir/main_loop.h>
2525-
2526-#include <memory>
2527+#include "gmock_fixes.h"
2528
2529 class MockMainLoop : public mir::MainLoop
2530 {
2531 public:
2532- ~MockMainLoop() noexcept {}
2533+ MockMainLoop();
2534+ ~MockMainLoop() noexcept;
2535
2536- void run() override {}
2537- void stop() override {}
2538+ void run() override;
2539+ void stop() override;
2540
2541 MOCK_METHOD2(register_signal_handler,
2542 void(std::initializer_list<int>,
2543@@ -49,5 +47,4 @@
2544 MOCK_METHOD1(create_alarm, std::unique_ptr<mir::time::Alarm>(std::shared_ptr<mir::LockableCallback> const& callback));
2545 };
2546
2547-
2548 #endif // MOCKMAINLOOP_H
2549
2550=== added file 'tests/framework/mock_mir_session.cpp'
2551--- tests/framework/mock_mir_session.cpp 1970-01-01 00:00:00 +0000
2552+++ tests/framework/mock_mir_session.cpp 2015-12-04 13:04:35 +0000
2553@@ -0,0 +1,63 @@
2554+/*
2555+ * Copyright (C) 2015 Canonical, Ltd.
2556+ *
2557+ * This program is free software: you can redistribute it and/or modify it under
2558+ * the terms of the GNU Lesser General Public License version 3, as published by
2559+ * the Free Software Foundation.
2560+ *
2561+ * This program is distributed in the hope that it will be useful, but WITHOUT
2562+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
2563+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2564+ * Lesser General Public License for more details.
2565+ *
2566+ * You should have received a copy of the GNU Lesser General Public License
2567+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2568+ */
2569+
2570+#include "mock_mir_session.h"
2571+
2572+namespace mir
2573+{
2574+namespace scene
2575+{
2576+
2577+MockSession::MockSession()
2578+{
2579+}
2580+
2581+MockSession::MockSession(const std::string &sessionName, pid_t processId)
2582+ : m_sessionName(sessionName), m_sessionId(processId)
2583+{
2584+}
2585+
2586+MockSession::~MockSession()
2587+{
2588+}
2589+
2590+std::string MockSession::name() const
2591+{
2592+ return m_sessionName;
2593+}
2594+
2595+pid_t MockSession::process_id() const
2596+{
2597+ return m_sessionId;
2598+}
2599+
2600+void MockSession::resume_prompt_session() {}
2601+
2602+void MockSession::suspend_prompt_session() {}
2603+
2604+void MockSession::stop_prompt_session() {}
2605+
2606+void MockSession::start_prompt_session() {}
2607+
2608+std::shared_ptr<scene::Surface> MockSession::surface_after(const std::shared_ptr<scene::Surface> &) const
2609+{
2610+ return {};
2611+}
2612+
2613+void MockSession::configure_streams(scene::Surface &, const std::vector<mir::shell::StreamSpecification> &) {}
2614+
2615+} // namespace scene
2616+} // namespace mir
2617
2618=== modified file 'tests/framework/mock_mir_session.h'
2619--- tests/modules/common/mock_mir_session.h 2015-10-07 14:38:44 +0000
2620+++ tests/framework/mock_mir_session.h 2015-12-04 13:04:35 +0000
2621@@ -29,20 +29,13 @@
2622
2623 struct MockSession : public Session
2624 {
2625- MockSession() {}
2626- MockSession(std::string const& sessionName, pid_t processId)
2627- : m_sessionName(sessionName), m_sessionId(processId)
2628- {}
2629-
2630- std::string name() const override
2631- {
2632- return m_sessionName;
2633- }
2634-
2635- pid_t process_id() const override
2636- {
2637- return m_sessionId;
2638- }
2639+ MockSession();
2640+ MockSession(std::string const& sessionName, pid_t processId);
2641+ virtual ~MockSession();
2642+
2643+ std::string name() const override;
2644+
2645+ pid_t process_id() const override;
2646
2647 MOCK_METHOD0(force_requests_to_complete, void());
2648
2649@@ -62,16 +55,16 @@
2650 MOCK_METHOD1(send_display_config, void(graphics::DisplayConfiguration const&));
2651 MOCK_METHOD3(configure_surface, int(frontend::SurfaceId, MirSurfaceAttrib, int));
2652
2653- void start_prompt_session() override {};
2654- void stop_prompt_session() override {};
2655- void suspend_prompt_session() override {};
2656- void resume_prompt_session() override {};
2657- std::shared_ptr<Surface> surface_after(std::shared_ptr<Surface> const&) const override { return {}; }
2658+ void start_prompt_session() override;
2659+ void stop_prompt_session() override;
2660+ void suspend_prompt_session() override;
2661+ void resume_prompt_session() override;
2662+ std::shared_ptr<Surface> surface_after(std::shared_ptr<Surface> const&) const override;
2663
2664 MOCK_CONST_METHOD1(get_buffer_stream, std::shared_ptr<frontend::BufferStream>(frontend::BufferStreamId));
2665 MOCK_METHOD1(destroy_buffer_stream, void(frontend::BufferStreamId));
2666 MOCK_METHOD1(create_buffer_stream, frontend::BufferStreamId(graphics::BufferProperties const&));
2667- void configure_streams(Surface&, std::vector<shell::StreamSpecification> const&) override {};
2668+ void configure_streams(Surface&, std::vector<shell::StreamSpecification> const&) override;;
2669
2670 private:
2671 std::string m_sessionName;
2672
2673=== added file 'tests/framework/mock_proc_info.cpp'
2674--- tests/framework/mock_proc_info.cpp 1970-01-01 00:00:00 +0000
2675+++ tests/framework/mock_proc_info.cpp 2015-12-04 13:04:35 +0000
2676@@ -0,0 +1,35 @@
2677+/*
2678+ * Copyright (C) 2015 Canonical, Ltd.
2679+ *
2680+ * This program is free software: you can redistribute it and/or modify it under
2681+ * the terms of the GNU Lesser General Public License version 3, as published by
2682+ * the Free Software Foundation.
2683+ *
2684+ * This program is distributed in the hope that it will be useful, but WITHOUT
2685+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
2686+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2687+ * Lesser General Public License for more details.
2688+ *
2689+ * You should have received a copy of the GNU Lesser General Public License
2690+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2691+ */
2692+
2693+#include "mock_proc_info.h"
2694+
2695+namespace qtmir
2696+{
2697+
2698+MockProcInfo::MockProcInfo()
2699+{
2700+}
2701+
2702+MockProcInfo::~MockProcInfo()
2703+{
2704+}
2705+
2706+std::unique_ptr<qtmir::ProcInfo::CommandLine> MockProcInfo::commandLine(pid_t pid)
2707+{
2708+ return std::unique_ptr<CommandLine>(new CommandLine{command_line(pid)});
2709+}
2710+
2711+} // namespace qtmir
2712
2713=== modified file 'tests/framework/mock_proc_info.h'
2714--- tests/modules/common/mock_proc_info.h 2015-10-08 11:20:30 +0000
2715+++ tests/framework/mock_proc_info.h 2015-12-04 13:04:35 +0000
2716@@ -21,16 +21,17 @@
2717
2718 #include <gmock/gmock.h>
2719
2720-namespace testing
2721-{
2722+namespace qtmir {
2723+
2724 struct MockProcInfo : public qtmir::ProcInfo
2725 {
2726+ MockProcInfo();
2727+ virtual ~MockProcInfo();
2728+
2729 MOCK_METHOD1(command_line, QByteArray(pid_t));
2730- std::unique_ptr<CommandLine> commandLine(pid_t pid)
2731- {
2732- return std::unique_ptr<CommandLine>(new CommandLine{command_line(pid)});
2733- }
2734+ std::unique_ptr<CommandLine> commandLine(pid_t pid);
2735 };
2736-}
2737+
2738+} // namespace qtmir
2739
2740 #endif // MOCK_PROC_INFO_H
2741
2742=== added file 'tests/framework/mock_prompt_session.cpp'
2743--- tests/framework/mock_prompt_session.cpp 1970-01-01 00:00:00 +0000
2744+++ tests/framework/mock_prompt_session.cpp 2015-12-04 13:04:35 +0000
2745@@ -0,0 +1,33 @@
2746+/*
2747+ * Copyright (C) 2015 Canonical, Ltd.
2748+ *
2749+ * This program is free software: you can redistribute it and/or modify it under
2750+ * the terms of the GNU Lesser General Public License version 3, as published by
2751+ * the Free Software Foundation.
2752+ *
2753+ * This program is distributed in the hope that it will be useful, but WITHOUT
2754+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
2755+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2756+ * Lesser General Public License for more details.
2757+ *
2758+ * You should have received a copy of the GNU Lesser General Public License
2759+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2760+ */
2761+
2762+#include "mock_prompt_session.h"
2763+
2764+namespace mir
2765+{
2766+namespace scene
2767+{
2768+
2769+MockPromptSession::MockPromptSession()
2770+{
2771+}
2772+
2773+MockPromptSession::~MockPromptSession()
2774+{
2775+}
2776+
2777+} // namespace scene
2778+} // namespace mir
2779
2780=== modified file 'tests/framework/mock_prompt_session.h'
2781--- tests/modules/common/mock_prompt_session.h 2015-08-11 12:08:32 +0000
2782+++ tests/framework/mock_prompt_session.h 2015-12-04 13:04:35 +0000
2783@@ -26,6 +26,9 @@
2784 struct MockPromptSession : public PromptSession
2785 {
2786 public:
2787+ MockPromptSession();
2788+ virtual ~MockPromptSession();
2789+
2790 MOCK_METHOD1(start, void(std::shared_ptr<Session> const&));
2791 MOCK_METHOD1(stop, void(std::shared_ptr<Session> const&));
2792 MOCK_METHOD1(suspend, void(std::shared_ptr<Session> const&));
2793
2794=== added file 'tests/framework/mock_prompt_session_manager.cpp'
2795--- tests/framework/mock_prompt_session_manager.cpp 1970-01-01 00:00:00 +0000
2796+++ tests/framework/mock_prompt_session_manager.cpp 2015-12-04 13:04:35 +0000
2797@@ -0,0 +1,33 @@
2798+/*
2799+ * Copyright (C) 2015 Canonical, Ltd.
2800+ *
2801+ * This program is free software: you can redistribute it and/or modify it under
2802+ * the terms of the GNU Lesser General Public License version 3, as published by
2803+ * the Free Software Foundation.
2804+ *
2805+ * This program is distributed in the hope that it will be useful, but WITHOUT
2806+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
2807+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2808+ * Lesser General Public License for more details.
2809+ *
2810+ * You should have received a copy of the GNU Lesser General Public License
2811+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2812+ */
2813+
2814+#include "mock_prompt_session_manager.h"
2815+
2816+namespace mir
2817+{
2818+namespace scene
2819+{
2820+
2821+MockPromptSessionManager::MockPromptSessionManager()
2822+{
2823+}
2824+
2825+MockPromptSessionManager::~MockPromptSessionManager()
2826+{
2827+}
2828+
2829+} // namespace scene
2830+} // namespace mir
2831
2832=== modified file 'tests/framework/mock_prompt_session_manager.h'
2833--- tests/modules/common/mock_prompt_session_manager.h 2015-08-11 12:08:32 +0000
2834+++ tests/framework/mock_prompt_session_manager.h 2015-12-04 13:04:35 +0000
2835@@ -28,6 +28,9 @@
2836 class MockPromptSessionManager: public PromptSessionManager
2837 {
2838 public:
2839+ MockPromptSessionManager();
2840+ virtual ~MockPromptSessionManager();
2841+
2842 MOCK_CONST_METHOD2(start_prompt_session_for, std::shared_ptr<PromptSession>(std::shared_ptr<mir::scene::Session> const&,
2843 mir::scene::PromptSessionCreationParameters const&));
2844
2845
2846=== added file 'tests/framework/mock_renderable.cpp'
2847--- tests/framework/mock_renderable.cpp 1970-01-01 00:00:00 +0000
2848+++ tests/framework/mock_renderable.cpp 2015-12-04 13:04:35 +0000
2849@@ -0,0 +1,33 @@
2850+/*
2851+ * Copyright (C) 2015 Canonical, Ltd.
2852+ *
2853+ * This program is free software: you can redistribute it and/or modify it under
2854+ * the terms of the GNU Lesser General Public License version 3, as published by
2855+ * the Free Software Foundation.
2856+ *
2857+ * This program is distributed in the hope that it will be useful, but WITHOUT
2858+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
2859+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2860+ * Lesser General Public License for more details.
2861+ *
2862+ * You should have received a copy of the GNU Lesser General Public License
2863+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2864+ */
2865+
2866+#include "mock_renderable.h"
2867+
2868+namespace mir
2869+{
2870+namespace graphics
2871+{
2872+
2873+MockRenderable::MockRenderable()
2874+{
2875+}
2876+
2877+MockRenderable::~MockRenderable()
2878+{
2879+}
2880+
2881+} // namespace graphics
2882+} // namespace mir
2883
2884=== modified file 'tests/framework/mock_renderable.h'
2885--- tests/modules/common/mock_renderable.h 2015-08-11 12:08:32 +0000
2886+++ tests/framework/mock_renderable.h 2015-12-04 13:04:35 +0000
2887@@ -25,7 +25,8 @@
2888
2889 struct MockRenderable : public Renderable
2890 {
2891- MockRenderable() {};
2892+ MockRenderable();
2893+ virtual ~MockRenderable();
2894
2895 MOCK_CONST_METHOD0(id, ID());
2896 MOCK_CONST_METHOD0(buffer, std::shared_ptr<Buffer>());
2897
2898=== added file 'tests/framework/mock_session.cpp'
2899--- tests/framework/mock_session.cpp 1970-01-01 00:00:00 +0000
2900+++ tests/framework/mock_session.cpp 2015-12-04 13:04:35 +0000
2901@@ -0,0 +1,69 @@
2902+/*
2903+ * Copyright (C) 2015 Canonical, Ltd.
2904+ *
2905+ * This program is free software: you can redistribute it and/or modify it under
2906+ * the terms of the GNU Lesser General Public License version 3, as published by
2907+ * the Free Software Foundation.
2908+ *
2909+ * This program is distributed in the hope that it will be useful, but WITHOUT
2910+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
2911+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2912+ * Lesser General Public License for more details.
2913+ *
2914+ * You should have received a copy of the GNU Lesser General Public License
2915+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2916+ */
2917+
2918+#include "mock_session.h"
2919+
2920+namespace qtmir
2921+{
2922+
2923+MockSession::MockSession()
2924+ : SessionInterface(0)
2925+{
2926+ m_state = Starting;
2927+ ON_CALL(*this, suspend()).WillByDefault(::testing::Invoke(this, &MockSession::doSuspend));
2928+ ON_CALL(*this, resume()).WillByDefault(::testing::Invoke(this, &MockSession::doResume));
2929+ ON_CALL(*this, stop()).WillByDefault(::testing::Invoke(this, &MockSession::doStop));
2930+ ON_CALL(*this, state()).WillByDefault(::testing::Invoke(this, &MockSession::doState));
2931+}
2932+
2933+MockSession::~MockSession()
2934+{
2935+
2936+}
2937+
2938+SessionInterface::State MockSession::doState() const
2939+{
2940+ return m_state;
2941+}
2942+
2943+void MockSession::doStop()
2944+{
2945+ setState(Stopped);
2946+}
2947+
2948+void MockSession::doResume()
2949+{
2950+ if (m_state == Suspending || m_state == Suspended) {
2951+ setState(Running);
2952+ }
2953+}
2954+
2955+void MockSession::doSuspend()
2956+{
2957+ if (m_state == Running) {
2958+ setState(Suspending);
2959+ }
2960+}
2961+
2962+void MockSession::setState(SessionInterface::State state)
2963+{
2964+ if (m_state != state) {
2965+ m_state = state;
2966+ Q_EMIT stateChanged(m_state);
2967+ }
2968+}
2969+
2970+} // namespace qtmir
2971
2972=== modified file 'tests/framework/mock_session.h'
2973--- tests/modules/common/mock_session.h 2015-08-31 09:51:28 +0000
2974+++ tests/framework/mock_session.h 2015-12-04 13:04:35 +0000
2975@@ -24,13 +24,8 @@
2976
2977 class MockSession : public SessionInterface {
2978 public:
2979- MockSession() : SessionInterface(0) {
2980- m_state = Starting;
2981- ON_CALL(*this, suspend()).WillByDefault(::testing::Invoke(this, &MockSession::doSuspend));
2982- ON_CALL(*this, resume()).WillByDefault(::testing::Invoke(this, &MockSession::doResume));
2983- ON_CALL(*this, stop()).WillByDefault(::testing::Invoke(this, &MockSession::doStop));
2984- ON_CALL(*this, state()).WillByDefault(::testing::Invoke(this, &MockSession::doState));
2985- }
2986+ MockSession();
2987+ virtual ~MockSession();
2988
2989 MOCK_METHOD0(release, void());
2990
2991@@ -49,6 +44,7 @@
2992
2993 MOCK_METHOD0(suspend, void());
2994 MOCK_METHOD0(resume, void());
2995+ MOCK_METHOD0(close, void());
2996 MOCK_METHOD0(stop, void());
2997
2998 MOCK_METHOD1(addChildSession, void(SessionInterface* session));
2999@@ -63,29 +59,12 @@
3000
3001 MOCK_CONST_METHOD0(childSessions, SessionModel*());
3002
3003- void setState(State state) {
3004- if (m_state != state) {
3005- m_state = state;
3006- Q_EMIT stateChanged(m_state);
3007- }
3008- }
3009+ void setState(State state);
3010
3011- void doSuspend() {
3012- if (m_state == Running) {
3013- setState(Suspending);
3014- }
3015- }
3016- void doResume() {
3017- if (m_state == Suspending || m_state == Suspended) {
3018- setState(Running);
3019- }
3020- }
3021- void doStop() {
3022- setState(Stopped);
3023- }
3024- State doState() const {
3025- return m_state;
3026- }
3027+ void doSuspend();
3028+ void doResume();
3029+ void doStop();
3030+ State doState() const;
3031
3032 protected:
3033 MOCK_METHOD1(setFullscreen, void(bool fullscreen));
3034@@ -94,7 +73,6 @@
3035 MOCK_METHOD1(removePromptSession, void(const std::shared_ptr<mir::scene::PromptSession>& session));
3036
3037 private:
3038-
3039 State m_state;
3040 };
3041
3042
3043=== added file 'tests/framework/mock_settings.cpp'
3044--- tests/framework/mock_settings.cpp 1970-01-01 00:00:00 +0000
3045+++ tests/framework/mock_settings.cpp 2015-12-04 13:04:35 +0000
3046@@ -0,0 +1,40 @@
3047+/*
3048+ * Copyright (C) 2015 Canonical, Ltd.
3049+ *
3050+ * This program is free software: you can redistribute it and/or modify it under
3051+ * the terms of the GNU Lesser General Public License version 3, as published by
3052+ * the Free Software Foundation.
3053+ *
3054+ * This program is distributed in the hope that it will be useful, but WITHOUT
3055+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
3056+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3057+ * Lesser General Public License for more details.
3058+ *
3059+ * You should have received a copy of the GNU Lesser General Public License
3060+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3061+ */
3062+
3063+#include "mock_settings.h"
3064+
3065+namespace qtmir
3066+{
3067+
3068+MockSettings::MockSettings()
3069+{
3070+ using namespace ::testing;
3071+
3072+ QVariantList lifecycleExemptAppIds;
3073+ lifecycleExemptAppIds << "com.ubuntu.music";
3074+ ON_CALL(*this, get(_))
3075+ .WillByDefault(
3076+ Return(lifecycleExemptAppIds));
3077+
3078+}
3079+
3080+MockSettings::~MockSettings()
3081+{
3082+
3083+}
3084+
3085+} // namespace qtmir
3086+
3087
3088=== modified file 'tests/framework/mock_settings.h'
3089--- tests/modules/common/mock_settings.h 2015-03-24 23:38:33 +0000
3090+++ tests/framework/mock_settings.h 2015-12-04 13:04:35 +0000
3091@@ -18,24 +18,20 @@
3092 #define MOCK_SETTINGS_H
3093
3094 #include <Unity/Application/settings_interface.h>
3095-
3096+#include <QVariant>
3097+
3098 #include <gmock/gmock.h>
3099
3100-namespace testing
3101+namespace qtmir
3102 {
3103 struct MockSettings : public qtmir::SettingsInterface
3104 {
3105- MockSettings()
3106- {
3107- QVariantList lifecycleExemptAppIds;
3108- lifecycleExemptAppIds << "com.ubuntu.music";
3109- ON_CALL(*this, get(_))
3110- .WillByDefault(
3111- Return(lifecycleExemptAppIds));
3112+ MockSettings();
3113+ virtual ~MockSettings();
3114
3115- }
3116 MOCK_CONST_METHOD1(get, QVariant(const QString &));
3117 };
3118
3119-} // namespace testing
3120+} // namespace qtmir
3121+
3122 #endif // MOCK_SETTINGS_H
3123
3124=== added file 'tests/framework/mock_shared_wakelock.cpp'
3125--- tests/framework/mock_shared_wakelock.cpp 1970-01-01 00:00:00 +0000
3126+++ tests/framework/mock_shared_wakelock.cpp 2015-12-04 13:04:35 +0000
3127@@ -0,0 +1,61 @@
3128+/*
3129+ * Copyright (C) 2015 Canonical, Ltd.
3130+ *
3131+ * This program is free software: you can redistribute it and/or modify it under
3132+ * the terms of the GNU Lesser General Public License version 3, as published by
3133+ * the Free Software Foundation.
3134+ *
3135+ * This program is distributed in the hope that it will be useful, but WITHOUT
3136+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
3137+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3138+ * Lesser General Public License for more details.
3139+ *
3140+ * You should have received a copy of the GNU Lesser General Public License
3141+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3142+ */
3143+
3144+#include "mock_shared_wakelock.h"
3145+
3146+namespace qtmir
3147+{
3148+
3149+MockSharedWakelock::MockSharedWakelock(const QDBusConnection &)
3150+{
3151+ using namespace ::testing;
3152+
3153+ ON_CALL(*this, enabled()).WillByDefault(Invoke(this, &MockSharedWakelock::doEnabled));
3154+ ON_CALL(*this, acquire(_)).WillByDefault(Invoke(this, &MockSharedWakelock::doAcquire));
3155+ ON_CALL(*this, release(_)).WillByDefault(Invoke(this, &MockSharedWakelock::doRelease));
3156+}
3157+
3158+MockSharedWakelock::~MockSharedWakelock()
3159+{
3160+}
3161+
3162+void MockSharedWakelock::doRelease(const QObject *object)
3163+{
3164+ if (!m_owners.remove(object)) {
3165+ return;
3166+ }
3167+ if (m_owners.isEmpty()) {
3168+ Q_EMIT enabledChanged(false);
3169+ }
3170+}
3171+
3172+void MockSharedWakelock::doAcquire(const QObject *object)
3173+{
3174+ if (m_owners.contains(object)) {
3175+ return;
3176+ }
3177+ m_owners.insert(object);
3178+ if (m_owners.size() == 1) {
3179+ Q_EMIT enabledChanged(true);
3180+ }
3181+}
3182+
3183+bool MockSharedWakelock::doEnabled()
3184+{
3185+ return !m_owners.isEmpty();
3186+}
3187+
3188+} // namespace qtmir
3189
3190=== modified file 'tests/framework/mock_shared_wakelock.h'
3191--- tests/modules/common/mock_shared_wakelock.h 2015-03-05 09:36:02 +0000
3192+++ tests/framework/mock_shared_wakelock.h 2015-12-04 13:04:35 +0000
3193@@ -21,51 +21,26 @@
3194
3195 #include <gmock/gmock.h>
3196
3197-namespace testing
3198+namespace qtmir
3199 {
3200 class MockSharedWakelock : public qtmir::SharedWakelock
3201 {
3202 public:
3203- MockSharedWakelock(const QDBusConnection& /*connection*/= QDBusConnection::systemBus())
3204- {
3205- ON_CALL(*this, enabled()).WillByDefault(Invoke(this, &MockSharedWakelock::doEnabled));
3206- ON_CALL(*this, acquire(_)).WillByDefault(Invoke(this, &MockSharedWakelock::doAcquire));
3207- ON_CALL(*this, release(_)).WillByDefault(Invoke(this, &MockSharedWakelock::doRelease));
3208- }
3209+ MockSharedWakelock(const QDBusConnection& /*connection*/= QDBusConnection::systemBus());
3210+ virtual ~MockSharedWakelock();
3211
3212 MOCK_CONST_METHOD0(enabled, bool());
3213 MOCK_METHOD1(acquire, void(const QObject *));
3214 MOCK_METHOD1(release, void(const QObject *));
3215
3216- bool doEnabled()
3217- {
3218- return !m_owners.isEmpty();
3219- }
3220-
3221- void doAcquire(const QObject *object)
3222- {
3223- if (m_owners.contains(object)) {
3224- return;
3225- }
3226- m_owners.insert(object);
3227- if (m_owners.size() == 1) {
3228- Q_EMIT enabledChanged(true);
3229- }
3230- }
3231-
3232- void doRelease(const QObject *object)
3233- {
3234- if (!m_owners.remove(object)) {
3235- return;
3236- }
3237- if (m_owners.isEmpty()) {
3238- Q_EMIT enabledChanged(false);
3239- }
3240- }
3241+ bool doEnabled();
3242+ void doAcquire(const QObject *object);
3243+ void doRelease(const QObject *object);
3244
3245 private:
3246 QSet<const QObject *> m_owners;
3247 };
3248
3249-} // namespace testing
3250+} // namespace qtmir
3251+
3252 #endif // MOCK_SHARED_WAKELOCK_H
3253
3254=== added file 'tests/framework/mock_surface.cpp'
3255--- tests/framework/mock_surface.cpp 1970-01-01 00:00:00 +0000
3256+++ tests/framework/mock_surface.cpp 2015-12-04 13:04:35 +0000
3257@@ -0,0 +1,39 @@
3258+/*
3259+ * Copyright (C) 2015 Canonical, Ltd.
3260+ *
3261+ * This program is free software: you can redistribute it and/or modify it under
3262+ * the terms of the GNU Lesser General Public License version 3, as published by
3263+ * the Free Software Foundation.
3264+ *
3265+ * This program is distributed in the hope that it will be useful, but WITHOUT
3266+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
3267+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3268+ * Lesser General Public License for more details.
3269+ *
3270+ * You should have received a copy of the GNU Lesser General Public License
3271+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3272+ */
3273+
3274+#include "mock_surface.h"
3275+
3276+namespace mir
3277+{
3278+namespace scene
3279+{
3280+
3281+MockSurface::MockSurface()
3282+{
3283+}
3284+
3285+MockSurface::~MockSurface()
3286+{
3287+}
3288+
3289+void MockSurface::rename(const std::string &) {}
3290+
3291+void MockSurface::set_keymap(const xkb_rule_names &) {}
3292+
3293+void MockSurface::consume(const MirEvent &event) { consume(&event); }
3294+
3295+} // namespace scene
3296+} // namespace mir
3297
3298=== modified file 'tests/framework/mock_surface.h'
3299--- tests/modules/common/mock_surface.h 2015-08-11 12:08:32 +0000
3300+++ tests/framework/mock_surface.h 2015-12-04 13:04:35 +0000
3301@@ -28,7 +28,8 @@
3302
3303 struct MockSurface : public mir::scene::Surface
3304 {
3305- MockSurface() {}
3306+ MockSurface();
3307+ virtual ~MockSurface();
3308
3309 MOCK_CONST_METHOD0(name, std::string());
3310 MOCK_CONST_METHOD0(client_size, geometry::Size());
3311@@ -62,15 +63,15 @@
3312 MOCK_METHOD1(set_reception_mode, void(input::InputReceptionMode mode));
3313 MOCK_METHOD0(request_client_surface_close, void());
3314 MOCK_CONST_METHOD1(buffers_ready_for_compositor, int(void const*));
3315- void set_keymap(xkb_rule_names const &) override {}
3316- void rename(std::string const&) override {}
3317+ void set_keymap(xkb_rule_names const &) override;
3318+ void rename(std::string const&) override;
3319 MOCK_METHOD1(set_streams, void(std::list<StreamInfo> const&));
3320
3321 // from mir::input::surface
3322 MOCK_CONST_METHOD1(input_area_contains, bool(geometry::Point const& point));
3323 MOCK_CONST_METHOD0(reception_mode, input::InputReceptionMode());
3324 MOCK_METHOD1(consume, void(MirEvent const* event));
3325- void consume(MirEvent const& event) override { consume(&event); }
3326+ void consume(MirEvent const& event) override;
3327
3328 // from mir::frontend::surface
3329 MOCK_CONST_METHOD0(pixel_format, MirPixelFormat());
3330
3331=== modified file 'tests/framework/qtmir_test.cpp'
3332--- tests/modules/common/qtmir_test.cpp 2015-10-01 16:48:38 +0000
3333+++ tests/framework/qtmir_test.cpp 2015-12-04 13:04:35 +0000
3334@@ -18,7 +18,8 @@
3335
3336 namespace qtmir {
3337
3338-void PrintTo(const Application::InternalState& state, ::std::ostream* os) {
3339+void PrintTo(const Application::InternalState& state, ::std::ostream* os)
3340+{
3341 switch (state) {
3342 case Application::InternalState::Starting:
3343 *os << "Starting";
3344@@ -71,4 +72,100 @@
3345 }
3346 }
3347
3348+// Initialization of mir::Server needed for by tests
3349+class TestMirServerInit : public virtual mir::Server
3350+{
3351+public:
3352+ TestMirServerInit(std::shared_ptr<StubPromptSessionManager> const& promptSessionManager)
3353+ : mock_prompt_session_manager(promptSessionManager)
3354+ {
3355+ override_the_prompt_session_manager(
3356+ [this]{ return the_mock_prompt_session_manager(); });
3357+ }
3358+
3359+ std::shared_ptr<mir::scene::MockPromptSessionManager> the_mock_prompt_session_manager()
3360+ {
3361+ return mock_prompt_session_manager;
3362+ }
3363+
3364+private:
3365+ std::shared_ptr<StubPromptSessionManager> const mock_prompt_session_manager;
3366+};
3367+
3368+
3369+namespace { char const* argv[] = { nullptr }; }
3370+
3371+class FakeMirServer: private TestMirServerInit, public MirServer
3372+{
3373+public:
3374+ FakeMirServer(std::shared_ptr<StubPromptSessionManager> const& promptSessionManager)
3375+ : TestMirServerInit(promptSessionManager), MirServer(0, argv, QSharedPointer<ScreenController>())
3376+ {
3377+ }
3378+
3379+ using TestMirServerInit::the_mock_prompt_session_manager;
3380+};
3381+
3382 } // namespace qtmir
3383+
3384+namespace testing
3385+{
3386+
3387+QtMirTest::QtMirTest()
3388+ : promptSessionManager(std::make_shared<StubPromptSessionManager>())
3389+ , mirServer(QSharedPointer<MirServer>(new FakeMirServer(promptSessionManager)))
3390+ , taskController(QSharedPointer<TaskController>(
3391+ new TaskController(
3392+ nullptr,
3393+ QSharedPointer<ApplicationController>(&appController, [](ApplicationController*){}))))
3394+ , applicationManager(mirServer,
3395+ taskController,
3396+ QSharedPointer<MockSharedWakelock>(&sharedWakelock, [](MockSharedWakelock *){}),
3397+ QSharedPointer<DesktopFileReader::Factory>(&desktopFileReaderFactory,[](DesktopFileReader::Factory*){}),
3398+ QSharedPointer<ProcInfo>(&procInfo,[](ProcInfo *){}),
3399+ QSharedPointer<MockSettings>(&settings,[](MockSettings *){}))
3400+ , sessionManager(mirServer, &applicationManager)
3401+ , surfaceManager(mirServer, mirShell, &sessionManager)
3402+{
3403+}
3404+
3405+QtMirTest::~QtMirTest()
3406+{
3407+
3408+}
3409+
3410+Application *QtMirTest::startApplication(pid_t procId, const QString &appId)
3411+{
3412+ using namespace testing;
3413+
3414+ ON_CALL(appController,appIdHasProcessId(procId, appId)).WillByDefault(Return(true));
3415+
3416+ // Set up Mocks & signal watcher
3417+ auto mockDesktopFileReader = new NiceMock<MockDesktopFileReader>(appId, QFileInfo());
3418+ ON_CALL(*mockDesktopFileReader, loaded()).WillByDefault(Return(true));
3419+ ON_CALL(*mockDesktopFileReader, appId()).WillByDefault(Return(appId));
3420+
3421+ EXPECT_CALL(desktopFileReaderFactory, createInstance(appId, _))
3422+ .Times(1)
3423+ .WillOnce(Return(mockDesktopFileReader));
3424+
3425+ EXPECT_CALL(appController, startApplicationWithAppIdAndArgs(appId, _))
3426+ .Times(1)
3427+ .WillOnce(Return(true));
3428+
3429+ auto application = applicationManager.startApplication(appId, ApplicationManager::NoFlag);
3430+ applicationManager.onProcessStarting(appId);
3431+
3432+ bool authed = false;
3433+ applicationManager.authorizeSession(procId, authed);
3434+ EXPECT_EQ(authed, true);
3435+
3436+ auto appSession = std::make_shared<mir::scene::MockSession>(appId.toStdString(), procId);
3437+ sessionManager.onSessionStarting(appSession);
3438+
3439+ Mock::VerifyAndClearExpectations(&appController);
3440+ Mock::VerifyAndClearExpectations(&desktopFileReaderFactory);
3441+ return application;
3442+}
3443+
3444+} // namespace testing
3445
3446=== modified file 'tests/framework/qtmir_test.h'
3447--- tests/modules/common/qtmir_test.h 2015-11-19 12:56:02 +0000
3448+++ tests/framework/qtmir_test.h 2015-12-04 13:04:35 +0000
3449@@ -46,45 +46,12 @@
3450
3451 namespace qtmir {
3452
3453+typedef testing::NiceMock<mir::scene::MockPromptSessionManager> StubPromptSessionManager;
3454+
3455 // For better output in ASSERT_* and EXPECT_* error messages
3456 void PrintTo(const Application::InternalState& state, ::std::ostream* os);
3457 void PrintTo(const SessionInterface::State& state, ::std::ostream* os);
3458
3459-// Initialization of mir::Server needed for by tests
3460-class TestMirServerInit : public virtual mir::Server
3461-{
3462-public:
3463- TestMirServerInit()
3464- {
3465- override_the_prompt_session_manager(
3466- [this]{ return the_mock_prompt_session_manager(); });
3467- }
3468-
3469- std::shared_ptr<mir::scene::MockPromptSessionManager> the_mock_prompt_session_manager()
3470- {
3471- return mock_prompt_session_manager;
3472- }
3473-
3474-private:
3475- typedef testing::NiceMock<mir::scene::MockPromptSessionManager> StubPromptSessionManager;
3476- std::shared_ptr<StubPromptSessionManager> const mock_prompt_session_manager
3477- {std::make_shared<StubPromptSessionManager>()};
3478-};
3479-
3480-
3481-namespace { char const* argv[] = { nullptr }; }
3482-
3483-class FakeMirServer: private TestMirServerInit, public MirServer
3484-{
3485-public:
3486- FakeMirServer()
3487- : MirServer(0, argv, QSharedPointer<ScreenController>())
3488- {
3489- }
3490-
3491- using TestMirServerInit::the_mock_prompt_session_manager;
3492-};
3493-
3494 } // namespace qtmir
3495
3496 namespace testing {
3497@@ -92,77 +59,18 @@
3498 class QtMirTest : public ::testing::Test
3499 {
3500 public:
3501- QtMirTest()
3502- : mirServer{
3503- QSharedPointer<FakeMirServer> (new FakeMirServer)
3504- }
3505- , taskController{
3506- QSharedPointer<TaskController> (
3507- new TaskController(
3508- nullptr,
3509- QSharedPointer<ApplicationController>(
3510- &appController,
3511- [](ApplicationController*){})
3512- )
3513- )
3514- }
3515- , applicationManager{
3516- mirServer,
3517- taskController,
3518- QSharedPointer<MockSharedWakelock>(&sharedWakelock, [](MockSharedWakelock *){}),
3519- QSharedPointer<DesktopFileReader::Factory>(
3520- &desktopFileReaderFactory,
3521- [](DesktopFileReader::Factory*){}),
3522- QSharedPointer<ProcInfo>(&procInfo,[](ProcInfo *){}),
3523- QSharedPointer<MockSettings>(&settings,[](MockSettings *){})
3524- }
3525- , sessionManager{
3526- mirServer,
3527- &applicationManager,
3528- }
3529- , surfaceManager{
3530- mirServer,
3531- mirShell,
3532- &sessionManager
3533- }
3534- {
3535- }
3536-
3537- Application* startApplication(pid_t procId, QString const& appId)
3538- {
3539- using namespace testing;
3540-
3541- ON_CALL(appController,appIdHasProcessId(procId, appId)).WillByDefault(Return(true));
3542-
3543- // Set up Mocks & signal watcher
3544- auto mockDesktopFileReader = new NiceMock<MockDesktopFileReader>(appId, QFileInfo());
3545- ON_CALL(*mockDesktopFileReader, loaded()).WillByDefault(Return(true));
3546- ON_CALL(*mockDesktopFileReader, appId()).WillByDefault(Return(appId));
3547-
3548- ON_CALL(desktopFileReaderFactory, createInstance(appId, _)).WillByDefault(Return(mockDesktopFileReader));
3549-
3550- EXPECT_CALL(appController, startApplicationWithAppIdAndArgs(appId, _))
3551- .Times(1)
3552- .WillOnce(Return(true));
3553-
3554- auto application = applicationManager.startApplication(appId, ApplicationManager::NoFlag);
3555- applicationManager.onProcessStarting(appId);
3556-
3557- bool authed = false;
3558- applicationManager.authorizeSession(procId, authed);
3559- EXPECT_EQ(authed, true);
3560-
3561- auto appSession = std::make_shared<mir::scene::MockSession>(appId.toStdString(), procId);
3562- sessionManager.onSessionStarting(appSession);
3563- return application;
3564- }
3565-
3566- testing::NiceMock<testing::MockApplicationController> appController;
3567- testing::NiceMock<testing::MockProcInfo> procInfo;
3568- testing::NiceMock<testing::MockDesktopFileReaderFactory> desktopFileReaderFactory;
3569- testing::NiceMock<testing::MockSharedWakelock> sharedWakelock;
3570- testing::NiceMock<testing::MockSettings> settings;
3571- QSharedPointer<FakeMirServer> mirServer;
3572+ QtMirTest();
3573+ virtual ~QtMirTest();
3574+
3575+ Application* startApplication(pid_t procId, QString const& appId);
3576+
3577+ testing::NiceMock<MockApplicationController> appController;
3578+ testing::NiceMock<MockProcInfo> procInfo;
3579+ testing::NiceMock<MockDesktopFileReaderFactory> desktopFileReaderFactory;
3580+ testing::NiceMock<MockSharedWakelock> sharedWakelock;
3581+ testing::NiceMock<MockSettings> settings;
3582+ std::shared_ptr<StubPromptSessionManager> promptSessionManager;
3583+ QSharedPointer<MirServer> mirServer;
3584 MirShell *mirShell{nullptr};
3585 QSharedPointer<TaskController> taskController;
3586 ApplicationManager applicationManager;
3587
3588=== added file 'tests/framework/stub_input_channel.cpp'
3589--- tests/framework/stub_input_channel.cpp 1970-01-01 00:00:00 +0000
3590+++ tests/framework/stub_input_channel.cpp 2015-12-04 13:04:35 +0000
3591@@ -0,0 +1,52 @@
3592+/*
3593+ * Copyright (C) 2015 Canonical, Ltd.
3594+ *
3595+ * This program is free software: you can redistribute it and/or modify it under
3596+ * the terms of the GNU Lesser General Public License version 3, as published by
3597+ * the Free Software Foundation.
3598+ *
3599+ * This program is distributed in the hope that it will be useful, but WITHOUT
3600+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
3601+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3602+ * Lesser General Public License for more details.
3603+ *
3604+ * You should have received a copy of the GNU Lesser General Public License
3605+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3606+ */
3607+
3608+#include "stub_input_channel.h"
3609+
3610+namespace mir
3611+{
3612+namespace test
3613+{
3614+namespace doubles
3615+{
3616+
3617+StubInputChannel::StubInputChannel(int fd)
3618+ : input_fd(fd)
3619+{
3620+}
3621+
3622+StubInputChannel::StubInputChannel()
3623+ : StubInputChannel(0)
3624+{
3625+}
3626+
3627+StubInputChannel::~StubInputChannel()
3628+{
3629+}
3630+
3631+int StubInputChannel::client_fd() const
3632+{
3633+ return input_fd;
3634+}
3635+
3636+int StubInputChannel::server_fd() const
3637+{
3638+ return input_fd;
3639+}
3640+
3641+} // namespace doubles
3642+} // namespace test
3643+} // namespace mir
3644
3645=== modified file 'tests/framework/stub_input_channel.h'
3646--- tests/modules/common/stub_input_channel.h 2015-08-11 12:08:32 +0000
3647+++ tests/framework/stub_input_channel.h 2015-12-04 13:04:35 +0000
3648@@ -28,24 +28,14 @@
3649
3650 struct StubInputChannel : public input::InputChannel
3651 {
3652- StubInputChannel(int fd)
3653- : input_fd(fd)
3654- {
3655- }
3656-
3657- StubInputChannel()
3658- : StubInputChannel(0)
3659- {
3660- }
3661-
3662- int client_fd() const override
3663- {
3664- return input_fd;
3665- }
3666- int server_fd() const override
3667- {
3668- return input_fd;
3669- }
3670+ StubInputChannel(int fd);
3671+
3672+ StubInputChannel();
3673+
3674+ virtual ~StubInputChannel();
3675+
3676+ int client_fd() const override;
3677+ int server_fd() const override;
3678 int input_fd;
3679 };
3680
3681
3682=== added file 'tests/framework/stub_scene_surface.cpp'
3683--- tests/framework/stub_scene_surface.cpp 1970-01-01 00:00:00 +0000
3684+++ tests/framework/stub_scene_surface.cpp 2015-12-04 13:04:35 +0000
3685@@ -0,0 +1,103 @@
3686+/*
3687+ * Copyright (C) 2015 Canonical, Ltd.
3688+ *
3689+ * This program is free software: you can redistribute it and/or modify it under
3690+ * the terms of the GNU Lesser General Public License version 3, as published by
3691+ * the Free Software Foundation.
3692+ *
3693+ * This program is distributed in the hope that it will be useful, but WITHOUT
3694+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
3695+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3696+ * Lesser General Public License for more details.
3697+ *
3698+ * You should have received a copy of the GNU Lesser General Public License
3699+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3700+ */
3701+
3702+#include "stub_scene_surface.h"
3703+
3704+namespace mir
3705+{
3706+namespace test
3707+{
3708+namespace doubles
3709+{
3710+
3711+StubSceneSurface::StubSceneSurface(int fd)
3712+ : channel(std::make_shared<StubInputChannel>(fd)), fd(fd)
3713+{
3714+}
3715+
3716+StubSceneSurface::~StubSceneSurface()
3717+{
3718+}
3719+
3720+std::shared_ptr<mir::input::InputChannel> StubSceneSurface::input_channel() const
3721+{
3722+ return channel;
3723+}
3724+
3725+mir::input::InputReceptionMode StubSceneSurface::reception_mode() const
3726+{
3727+ return input_mode;
3728+}
3729+
3730+std::string StubSceneSurface::name() const { return {}; }
3731+
3732+mir::geometry::Point StubSceneSurface::top_left() const { return {}; }
3733+
3734+mir::geometry::Size StubSceneSurface::client_size() const { return {};}
3735+
3736+mir::geometry::Size StubSceneSurface::size() const { return {}; }
3737+
3738+mir::geometry::Rectangle StubSceneSurface::input_bounds() const { return {{},{}}; }
3739+
3740+bool StubSceneSurface::input_area_contains(mir::geometry::Point const&) const { return false; }
3741+
3742+mir::graphics::RenderableList StubSceneSurface::generate_renderables(mir::compositor::CompositorID) const { return {};}
3743+
3744+float StubSceneSurface::alpha() const { return 0.0f; }
3745+
3746+MirSurfaceType StubSceneSurface::type() const { return mir_surface_type_normal; }
3747+
3748+MirSurfaceState StubSceneSurface::state() const { return mir_surface_state_unknown; }
3749+
3750+void StubSceneSurface::hide() {}
3751+
3752+void StubSceneSurface::show() {}
3753+
3754+void StubSceneSurface::move_to(const mir::geometry::Point &) {}
3755+
3756+void StubSceneSurface::set_input_region(const std::vector<mir::geometry::Rectangle> &) {}
3757+
3758+void StubSceneSurface::resize(const mir::geometry::Size &) {}
3759+
3760+void StubSceneSurface::set_transformation(const glm::mat4 &) {}
3761+
3762+void StubSceneSurface::set_alpha(float) {}
3763+
3764+void StubSceneSurface::set_orientation(MirOrientation) {}
3765+
3766+void StubSceneSurface::add_observer(const std::shared_ptr<mir::scene::SurfaceObserver> &) {}
3767+
3768+void StubSceneSurface::remove_observer(const std::weak_ptr<mir::scene::SurfaceObserver> &) {}
3769+
3770+void StubSceneSurface::set_reception_mode(mir::input::InputReceptionMode mode) { input_mode = mode; }
3771+
3772+void StubSceneSurface::consume(const MirEvent &) {}
3773+
3774+void StubSceneSurface::set_cursor_image(const std::shared_ptr<mir::graphics::CursorImage> &) {}
3775+
3776+std::shared_ptr<mir::graphics::CursorImage> StubSceneSurface::cursor_image() const { return {}; }
3777+
3778+bool StubSceneSurface::supports_input() const { return true; }
3779+
3780+int StubSceneSurface::client_input_fd() const { return fd;}
3781+
3782+int StubSceneSurface::configure(MirSurfaceAttrib, int) { return 0; }
3783+
3784+int StubSceneSurface::query(MirSurfaceAttrib) const { return 0; }
3785+
3786+} // namespace doubles
3787+} // namespace test
3788+} // namespace mir
3789
3790=== modified file 'tests/framework/stub_scene_surface.h'
3791--- tests/modules/common/stub_scene_surface.h 2015-09-30 09:27:52 +0000
3792+++ tests/framework/stub_scene_surface.h 2015-12-04 13:04:35 +0000
3793@@ -38,55 +38,47 @@
3794 int fd;
3795 mir::input::InputReceptionMode input_mode{mir::input::InputReceptionMode::normal};
3796
3797- StubSceneSurface(int fd)
3798- : channel(std::make_shared<StubInputChannel>(fd)), fd(fd)
3799- {
3800- }
3801-
3802- std::shared_ptr<mir::input::InputChannel> input_channel() const override
3803- {
3804- return channel;
3805- }
3806-
3807- mir::input::InputReceptionMode reception_mode() const override
3808- {
3809- return input_mode;
3810- }
3811-
3812- std::string name() const override { return {}; }
3813- geometry::Point top_left() const override { return {}; }
3814- geometry::Size client_size() const override { return {};}
3815- geometry::Size size() const override { return {}; }
3816- geometry::Rectangle input_bounds() const override { return {{},{}}; }
3817- bool input_area_contains(mir::geometry::Point const&) const override { return false; }
3818-
3819- graphics::RenderableList generate_renderables(compositor::CompositorID) const override { return {};}
3820- float alpha() const override { return 0.0f;}
3821- MirSurfaceType type() const override { return mir_surface_type_normal; }
3822- MirSurfaceState state() const override { return mir_surface_state_unknown; }
3823-
3824- void hide() override {}
3825- void show() override {}
3826- void move_to(geometry::Point const&) override {}
3827- void set_input_region(std::vector<geometry::Rectangle> const&) override {}
3828- void resize(geometry::Size const&) override {}
3829- void set_transformation(glm::mat4 const&) override {}
3830- void set_alpha(float) override {}
3831- void set_orientation(MirOrientation) override {}
3832-
3833- void add_observer(std::shared_ptr<scene::SurfaceObserver> const&) override {}
3834- void remove_observer(std::weak_ptr<scene::SurfaceObserver> const&) override {}
3835-
3836- void set_reception_mode(input::InputReceptionMode mode) override { input_mode = mode; }
3837- void consume(MirEvent const&) override {}
3838-
3839- void set_cursor_image(std::shared_ptr<graphics::CursorImage> const& /* image */) override {}
3840- std::shared_ptr<graphics::CursorImage> cursor_image() const override { return {}; }
3841-
3842- bool supports_input() const override { return true;}
3843- int client_input_fd() const override { return fd;}
3844- int configure(MirSurfaceAttrib, int) override { return 0; }
3845- int query(MirSurfaceAttrib) const override { return 0; }
3846+ StubSceneSurface(int fd);
3847+ virtual ~StubSceneSurface();
3848+
3849+ std::shared_ptr<mir::input::InputChannel> input_channel() const override;
3850+
3851+ mir::input::InputReceptionMode reception_mode() const override;
3852+
3853+ std::string name() const override;
3854+ geometry::Point top_left() const override;
3855+ geometry::Size client_size() const override;
3856+ geometry::Size size() const override;
3857+ geometry::Rectangle input_bounds() const override;
3858+ bool input_area_contains(mir::geometry::Point const&) const override;
3859+
3860+ graphics::RenderableList generate_renderables(compositor::CompositorID) const override;
3861+ float alpha() const override;
3862+ MirSurfaceType type() const override;
3863+ MirSurfaceState state() const override;
3864+
3865+ void hide() override;
3866+ void show() override;
3867+ void move_to(geometry::Point const&) override;
3868+ void set_input_region(std::vector<geometry::Rectangle> const&) override;
3869+ void resize(geometry::Size const&) override;
3870+ void set_transformation(glm::mat4 const&) override;
3871+ void set_alpha(float) override;
3872+ void set_orientation(MirOrientation) override;
3873+
3874+ void add_observer(std::shared_ptr<scene::SurfaceObserver> const&) override;
3875+ void remove_observer(std::weak_ptr<scene::SurfaceObserver> const&) override;
3876+
3877+ void set_reception_mode(input::InputReceptionMode mode) override;
3878+ void consume(MirEvent const&) override;
3879+
3880+ void set_cursor_image(std::shared_ptr<graphics::CursorImage> const& /* image */) override;
3881+ std::shared_ptr<graphics::CursorImage> cursor_image() const override;
3882+
3883+ bool supports_input() const override;
3884+ int client_input_fd() const override;
3885+ int configure(MirSurfaceAttrib, int) override;
3886+ int query(MirSurfaceAttrib) const override;
3887 };
3888
3889 }
3890
3891=== modified file 'tests/mirserver/Screen/CMakeLists.txt'
3892--- tests/mirserver/Screen/CMakeLists.txt 2015-08-20 10:16:54 +0000
3893+++ tests/mirserver/Screen/CMakeLists.txt 2015-12-04 13:04:35 +0000
3894@@ -5,7 +5,7 @@
3895 )
3896
3897 include_directories(
3898- ${CMAKE_SOURCE_DIR}/tests/common
3899+ ${CMAKE_SOURCE_DIR}/tests/framework
3900 ${CMAKE_SOURCE_DIR}/src/platforms/mirserver
3901 ${CMAKE_SOURCE_DIR}/src/common
3902 ${Qt5Gui_PRIVATE_INCLUDE_DIRS}
3903
3904=== modified file 'tests/mirserver/ScreenController/CMakeLists.txt'
3905--- tests/mirserver/ScreenController/CMakeLists.txt 2015-10-14 22:59:04 +0000
3906+++ tests/mirserver/ScreenController/CMakeLists.txt 2015-12-04 13:04:35 +0000
3907@@ -8,7 +8,7 @@
3908 )
3909
3910 include_directories(
3911- ${CMAKE_SOURCE_DIR}/tests/common
3912+ ${CMAKE_SOURCE_DIR}/tests/framework
3913 ${CMAKE_SOURCE_DIR}/src/platforms/mirserver
3914 ${CMAKE_SOURCE_DIR}/src/common
3915 ${Qt5Gui_PRIVATE_INCLUDE_DIRS}
3916@@ -22,6 +22,9 @@
3917 ScreenControllerTest
3918 qpa-mirserver
3919
3920+ -L${CMAKE_BINARY_DIR}/tests/framework
3921+ qtmir-test-framework-static
3922+
3923 ${GTEST_BOTH_LIBRARIES}
3924 ${GMOCK_LIBRARIES}
3925 )
3926
3927=== modified file 'tests/modules/Application/CMakeLists.txt'
3928--- tests/modules/Application/CMakeLists.txt 2015-08-19 20:17:56 +0000
3929+++ tests/modules/Application/CMakeLists.txt 2015-12-04 13:04:35 +0000
3930@@ -1,27 +1,33 @@
3931 set(
3932 APPLICATION_TEST_SOURCES
3933 application_test.cpp
3934- ${CMAKE_SOURCE_DIR}/tests/modules/common/fake_session.h
3935- ${CMAKE_SOURCE_DIR}/tests/modules/common/qtmir_test.cpp
3936 )
3937
3938 include_directories(
3939- ${APPLICATION_API_INCLUDE_DIRS}
3940 ${CMAKE_SOURCE_DIR}/src/platforms/mirserver
3941 ${CMAKE_SOURCE_DIR}/src/modules
3942- ${CMAKE_SOURCE_DIR}/tests/modules/common
3943+ ${CMAKE_SOURCE_DIR}/tests/framework
3944 ${MIRSERVER_INCLUDE_DIRS}
3945+
3946+ ${Qt5Core_INCLUDE_DIRS}
3947+ ${Qt5GUI_INCLUDE_DIRS}
3948+ ${Qt5Quick_INCLUDE_DIRS}
3949+ ${Qt5DBus_INCLUDE_DIRS}
3950 )
3951
3952 add_executable(application_test ${APPLICATION_TEST_SOURCES})
3953
3954+add_dependencies(application_test qtmir-test-framework-static)
3955+
3956 target_link_libraries(
3957 application_test
3958
3959+ Qt5::Test
3960+
3961 unityapplicationplugin
3962- qpa-mirserver
3963
3964- Qt5::Test
3965+ -L${CMAKE_BINARY_DIR}/tests/framework
3966+ qtmir-test-framework-static
3967
3968 ${GTEST_BOTH_LIBRARIES}
3969 ${GMOCK_LIBRARIES}
3970
3971=== modified file 'tests/modules/ApplicationManager/CMakeLists.txt'
3972--- tests/modules/ApplicationManager/CMakeLists.txt 2015-08-31 09:51:28 +0000
3973+++ tests/modules/ApplicationManager/CMakeLists.txt 2015-12-04 13:04:35 +0000
3974@@ -2,27 +2,29 @@
3975 APPLICATION_MANAGER_TEST_SOURCES
3976 application_manager_test.cpp
3977 ${CMAKE_SOURCE_DIR}/src/common/debughelpers.cpp
3978- ${CMAKE_SOURCE_DIR}/tests/modules/common/qtmir_test.cpp
3979- ../common/fake_mirsurface.h
3980 )
3981
3982 include_directories(
3983 ${APPLICATION_API_INCLUDE_DIRS}
3984 ${CMAKE_SOURCE_DIR}/src/platforms/mirserver
3985 ${CMAKE_SOURCE_DIR}/src/modules
3986- ${CMAKE_SOURCE_DIR}/tests/modules/common
3987+ ${CMAKE_SOURCE_DIR}/tests/framework
3988 ${MIRSERVER_INCLUDE_DIRS}
3989 )
3990
3991 add_executable(applicationmanager_test ${APPLICATION_MANAGER_TEST_SOURCES})
3992
3993+add_dependencies(applicationmanager_test qtmir-test-framework-static)
3994+
3995 target_link_libraries(
3996 applicationmanager_test
3997
3998- qpa-mirserver
3999+ Qt5::Test
4000+
4001 unityapplicationplugin
4002
4003- Qt5::Test
4004+ -L${CMAKE_BINARY_DIR}/tests/framework
4005+ qtmir-test-framework-static
4006
4007 ${GTEST_BOTH_LIBRARIES}
4008 ${GMOCK_LIBRARIES}
4009
4010=== modified file 'tests/modules/ApplicationManager/application_manager_test.cpp'
4011--- tests/modules/ApplicationManager/application_manager_test.cpp 2015-11-17 14:16:22 +0000
4012+++ tests/modules/ApplicationManager/application_manager_test.cpp 2015-12-04 13:04:35 +0000
4013@@ -1870,3 +1870,158 @@
4014 EXPECT_EQ(0, applicationManager.count());
4015 EXPECT_TRUE(dir.exists());
4016 }
4017+
4018+/*
4019+ * Test that there is an attempt at polite exiting of the app by requesting closure of the surface.
4020+ */
4021+TEST_F(ApplicationManagerTests,requestSurfaceCloseOnStop)
4022+{
4023+ using namespace ::testing;
4024+
4025+ const QString appId("testAppId");
4026+ quint64 procId = 5551;
4027+ Application* app = startApplication(procId, appId);
4028+ std::shared_ptr<mir::scene::Session> session = app->session()->session();
4029+
4030+ FakeMirSurface *surface = new FakeMirSurface;
4031+ onSessionCreatedSurface(session.get(), surface);
4032+ surface->drawFirstFrame();
4033+
4034+ QSignalSpy spy(surface, SIGNAL(closeRequested()));
4035+
4036+ // Stop app
4037+ applicationManager.stopApplication(appId);
4038+
4039+ EXPECT_EQ(1, spy.count());
4040+}
4041+
4042+
4043+// * Test that if there is no surface available to the app when it is stopped, that it is forced to close.
4044+TEST_F(ApplicationManagerTests,forceAppDeleteWhenRemovedWithMissingSurface)
4045+{
4046+ using namespace ::testing;
4047+
4048+ int argc = 0;
4049+ char* argv[0];
4050+ QCoreApplication qtApp(argc, argv); // app for deleteLater event
4051+
4052+ const QString appId("testAppId");
4053+ quint64 procId = 5551;
4054+ Application* app = startApplication(procId, appId);
4055+
4056+ QSignalSpy spy(app, SIGNAL(destroyed(QObject*)));
4057+ QObject::connect(app, &QObject::destroyed, app, [&qtApp](){ qtApp.quit(); });
4058+
4059+ // Stop app
4060+ applicationManager.stopApplication(appId);
4061+ qtApp.exec();
4062+ EXPECT_EQ(1, spy.count());
4063+}
4064+
4065+/*
4066+ * Test that if an application is started while it is still attempting to close, it is queued to start again.
4067+ */
4068+TEST_F(ApplicationManagerTests,applicationStartQueuedOnStartStopStart)
4069+{
4070+ using namespace ::testing;
4071+
4072+ int argc = 0;
4073+ char* argv[0];
4074+ QCoreApplication qtApp(argc, argv); // app for deleteLater event
4075+
4076+ const QString appId("testAppId");
4077+ quint64 procId = 5551;
4078+ Application* app = startApplication(procId, appId);
4079+ std::shared_ptr<mir::scene::Session> session = app->session()->session();
4080+
4081+ FakeMirSurface *surface = new FakeMirSurface;
4082+ onSessionCreatedSurface(session.get(), surface);
4083+ surface->drawFirstFrame();
4084+
4085+ EXPECT_EQ(Application::InternalState::Running, app->internalState());
4086+
4087+ // Stop app
4088+ applicationManager.stopApplication(appId);
4089+
4090+ EXPECT_EQ(Application::InternalState::Closing, app->internalState());
4091+
4092+ // // Set up Mocks & signal watcher
4093+ auto mockDesktopFileReader = new NiceMock<MockDesktopFileReader>(appId, QFileInfo());
4094+ ON_CALL(*mockDesktopFileReader, loaded()).WillByDefault(Return(true));
4095+ ON_CALL(*mockDesktopFileReader, appId()).WillByDefault(Return(appId));
4096+ ON_CALL(desktopFileReaderFactory, createInstance(appId, _)).WillByDefault(Return(mockDesktopFileReader));
4097+
4098+ EXPECT_EQ(nullptr, applicationManager.startApplication(appId, ApplicationManager::NoFlag));
4099+
4100+ QSignalSpy spy(&applicationManager, SIGNAL(applicationAdded(const QString&)));
4101+ applicationManager.onProcessStopped(appId);
4102+
4103+ QObject::connect(&applicationManager, &ApplicationManager::applicationAdded,
4104+ &applicationManager, [&qtApp, appId](const QString& startedApp) {
4105+ if (startedApp == appId) {
4106+ qtApp.quit();
4107+ }
4108+ });
4109+
4110+ qtApp.exec();
4111+ EXPECT_EQ(1, spy.count());
4112+}
4113+
4114+/*
4115+ * Test that there is an attempt at polite exiting of the app by requesting closure of the surface.
4116+ */
4117+TEST_F(ApplicationManagerTests,suspendedApplicationResumesClosesAndDeletes)
4118+{
4119+ using namespace ::testing;
4120+
4121+ const QString appId("testAppId");
4122+ quint64 procId = 5551;
4123+ Application* app = startApplication(procId, appId);
4124+ std::shared_ptr<mir::scene::Session> session = app->session()->session();
4125+
4126+ FakeMirSurface *surface = new FakeMirSurface;
4127+ onSessionCreatedSurface(session.get(), surface);
4128+ surface->drawFirstFrame();
4129+ EXPECT_EQ(Application::InternalState::Running, app->internalState());
4130+ EXPECT_EQ(SessionInterface::Running, app->session()->state());
4131+
4132+ // Suspend the application.
4133+ suspend(app);
4134+ EXPECT_EQ(Application::InternalState::Suspended, app->internalState());
4135+
4136+ // Stop app
4137+ applicationManager.stopApplication(appId);
4138+ EXPECT_EQ(Application::InternalState::Closing, app->internalState());
4139+ EXPECT_EQ(SessionInterface::Running, app->session()->state());
4140+}
4141+
4142+/*
4143+ * Test that a application which fails to close will eventually be forceable closed.
4144+ */
4145+TEST_F(ApplicationManagerTests,failedApplicationCloseEventualyDeletesApplication)
4146+{
4147+ using namespace ::testing;
4148+
4149+ int argc = 0;
4150+ char* argv[0];
4151+ QCoreApplication qtApp(argc, argv); // app for deleteLater event
4152+
4153+ const QString appId("testAppId");
4154+ quint64 procId = 5551;
4155+ Application* app = startApplication(procId, appId);
4156+ std::shared_ptr<mir::scene::Session> session = app->session()->session();
4157+
4158+ FakeMirSurface *surface = new FakeMirSurface;
4159+ onSessionCreatedSurface(session.get(), surface);
4160+ surface->drawFirstFrame();
4161+
4162+ EXPECT_EQ(Application::InternalState::Running, app->internalState());
4163+
4164+ QSignalSpy spy(app, SIGNAL(destroyed(QObject*)));
4165+ QObject::connect(app, &QObject::destroyed, app, [&qtApp](){ qtApp.quit(); });
4166+
4167+ // Stop app
4168+ applicationManager.stopApplication(appId);
4169+ qtApp.exec();
4170+ EXPECT_EQ(1, spy.count());
4171+}
4172
4173=== modified file 'tests/modules/DesktopFileReader/CMakeLists.txt'
4174--- tests/modules/DesktopFileReader/CMakeLists.txt 2014-12-03 08:56:35 +0000
4175+++ tests/modules/DesktopFileReader/CMakeLists.txt 2015-12-04 13:04:35 +0000
4176@@ -7,8 +7,6 @@
4177
4178 include_directories(
4179 ${CMAKE_SOURCE_DIR}/src/modules
4180- ${CMAKE_SOURCE_DIR}/tests/modules/common
4181- ${MIRSERVER_INCLUDE_DIRS}
4182 )
4183
4184 add_executable(desktop_file_reader_test ${DESKTOP_FILE_READER_TEST_SOURCES})
4185@@ -16,13 +14,9 @@
4186 target_link_libraries(
4187 desktop_file_reader_test
4188
4189- qpa-mirserver
4190 unityapplicationplugin
4191
4192- Qt5::Gui
4193-
4194 ${GTEST_BOTH_LIBRARIES}
4195- ${GMOCK_LIBRARIES}
4196 )
4197
4198 add_test(DesktopFileReader desktop_file_reader_test)
4199
4200=== modified file 'tests/modules/SessionManager/CMakeLists.txt'
4201--- tests/modules/SessionManager/CMakeLists.txt 2015-08-31 09:51:28 +0000
4202+++ tests/modules/SessionManager/CMakeLists.txt 2015-12-04 13:04:35 +0000
4203@@ -3,28 +3,30 @@
4204 session_manager_test.cpp
4205 session_test.cpp
4206 ${CMAKE_SOURCE_DIR}/src/common/debughelpers.cpp
4207- ${CMAKE_SOURCE_DIR}/tests/modules/common/qtmir_test.cpp
4208- ${CMAKE_SOURCE_DIR}/tests/modules/common/fake_mirsurface.h
4209 )
4210
4211 include_directories(
4212 ${APPLICATION_API_INCLUDE_DIRS}
4213 ${CMAKE_SOURCE_DIR}/src/platforms/mirserver
4214 ${CMAKE_SOURCE_DIR}/src/modules
4215- ${CMAKE_SOURCE_DIR}/tests/modules/common
4216+ ${CMAKE_SOURCE_DIR}/tests/framework
4217 ${MIRSERVER_INCLUDE_DIRS}
4218 )
4219
4220 add_executable(sessionmanager_test ${SESSION_MANAGER_TEST_SOURCES})
4221
4222+add_dependencies(sessionmanager_test qtmir-test-framework-static)
4223+
4224 target_link_libraries(
4225 sessionmanager_test
4226
4227- qpa-mirserver
4228 unityapplicationplugin
4229
4230 Qt5::Test
4231
4232+ -L${CMAKE_BINARY_DIR}/tests/framework
4233+ qtmir-test-framework-static
4234+
4235 ${GTEST_BOTH_LIBRARIES}
4236 ${GMOCK_LIBRARIES}
4237 )
4238
4239=== modified file 'tests/modules/SessionManager/session_manager_test.cpp'
4240--- tests/modules/SessionManager/session_manager_test.cpp 2015-08-11 12:08:32 +0000
4241+++ tests/modules/SessionManager/session_manager_test.cpp 2015-12-04 13:04:35 +0000
4242@@ -60,7 +60,7 @@
4243 EXPECT_TRUE(qtmirAppSession != nullptr);
4244
4245 auto promptSession = std::make_shared<ms::MockPromptSession>();
4246- ON_CALL(*mirServer->the_mock_prompt_session_manager(), application_for(_)).WillByDefault(Return(mirAppSession));
4247+ ON_CALL(*promptSessionManager, application_for(_)).WillByDefault(Return(mirAppSession));
4248
4249 sessionManager.onPromptSessionStarting(promptSession);
4250
4251@@ -83,8 +83,8 @@
4252 SessionInterface* qtmirAppSession = sessionManager.findSession(mirAppSession.get());
4253 EXPECT_TRUE(qtmirAppSession != nullptr);
4254
4255- EXPECT_CALL(*mirServer->the_mock_prompt_session_manager(), application_for(_)).WillRepeatedly(Return(mirAppSession));
4256- EXPECT_CALL(*mirServer->the_mock_prompt_session_manager(), helper_for(_)).WillRepeatedly(Return(nullptr));
4257+ EXPECT_CALL(*promptSessionManager, application_for(_)).WillRepeatedly(Return(mirAppSession));
4258+ EXPECT_CALL(*promptSessionManager, helper_for(_)).WillRepeatedly(Return(nullptr));
4259
4260 std::shared_ptr<ms::PromptSession> mirPromptSession = std::make_shared<ms::MockPromptSession>();
4261
4262@@ -93,7 +93,7 @@
4263 sessionManager.onSessionStarting(mirProviderSession);
4264 SessionInterface* qtmirProviderSession = sessionManager.findSession(mirProviderSession.get());
4265
4266- EXPECT_CALL(*mirServer->the_mock_prompt_session_manager(), for_each_provider_in(mirPromptSession,_)).WillRepeatedly(WithArgs<1>(Invoke(
4267+ EXPECT_CALL(*promptSessionManager, for_each_provider_in(mirPromptSession,_)).WillRepeatedly(WithArgs<1>(Invoke(
4268 [&](std::function<void(std::shared_ptr<ms::Session> const& prompt_provider)> const& f) {
4269 f(mirProviderSession);
4270 })));
4271@@ -109,7 +109,7 @@
4272
4273 EXPECT_THAT(listChildSessions(qtmirAppSession), ElementsAre(qtmirProviderSession));
4274
4275- EXPECT_CALL(*mirServer->the_mock_prompt_session_manager(), for_each_provider_in(mirPromptSession,_)).WillRepeatedly(InvokeWithoutArgs([]{}));
4276+ EXPECT_CALL(*promptSessionManager, for_each_provider_in(mirPromptSession,_)).WillRepeatedly(InvokeWithoutArgs([]{}));
4277
4278 EXPECT_EQ(qtmirProviderSession->live(), true);
4279 sessionManager.onPromptProviderRemoved(mirPromptSession.get(), mirProviderSession);
4280
4281=== modified file 'tests/modules/SessionManager/session_test.cpp'
4282--- tests/modules/SessionManager/session_test.cpp 2015-10-08 11:20:30 +0000
4283+++ tests/modules/SessionManager/session_test.cpp 2015-12-04 13:04:35 +0000
4284@@ -236,7 +236,7 @@
4285 auto mirPromptSession = std::make_shared<ms::MockPromptSession>();
4286 session->appendPromptSession(mirPromptSession);
4287
4288- EXPECT_CALL(*mirServer->the_mock_prompt_session_manager(), suspend_prompt_session(_)).Times(1);
4289+ EXPECT_CALL(*promptSessionManager, suspend_prompt_session(_)).Times(1);
4290
4291 EXPECT_CALL(*mirSession, set_lifecycle_state(mir_lifecycle_state_will_suspend));
4292 session->suspend();
4293@@ -244,7 +244,7 @@
4294 session->doSuspend();
4295 EXPECT_EQ(Session::Suspended, session->state());
4296
4297- Mock::VerifyAndClear(mirServer->the_mock_prompt_session_manager().get());
4298+ Mock::VerifyAndClear(promptSessionManager.get());
4299 }
4300
4301 TEST_F(SessionTests, ResumePromptSessionWhenSessionResumes)
4302@@ -256,7 +256,7 @@
4303
4304 auto mirSession = std::make_shared<MockSession>(appId.toStdString(), procId);
4305
4306- auto session = std::make_shared<qtmir::Session>(mirSession, mirServer->the_prompt_session_manager());
4307+ auto session = std::make_shared<qtmir::Session>(mirSession, promptSessionManager);
4308 {
4309 FakeMirSurface *surface = new FakeMirSurface;
4310 session->setSurface(surface);
4311@@ -273,11 +273,11 @@
4312 auto mirPromptSession = std::make_shared<ms::MockPromptSession>();
4313 session->appendPromptSession(mirPromptSession);
4314
4315- EXPECT_CALL(*mirServer->the_mock_prompt_session_manager(), resume_prompt_session(_)).Times(1);
4316+ EXPECT_CALL(*promptSessionManager, resume_prompt_session(_)).Times(1);
4317
4318 EXPECT_CALL(*mirSession, set_lifecycle_state(mir_lifecycle_state_resumed));
4319 session->resume();
4320 EXPECT_EQ(Session::Running, session->state());
4321
4322- Mock::VerifyAndClear(mirServer->the_mock_prompt_session_manager().get());
4323+ Mock::VerifyAndClear(promptSessionManager.get());
4324 }
4325
4326=== modified file 'tests/modules/SharedWakelock/CMakeLists.txt'
4327--- tests/modules/SharedWakelock/CMakeLists.txt 2015-03-04 23:32:28 +0000
4328+++ tests/modules/SharedWakelock/CMakeLists.txt 2015-12-04 13:04:35 +0000
4329@@ -5,7 +5,6 @@
4330
4331 include_directories(
4332 ${CMAKE_SOURCE_DIR}/src/modules
4333- ${CMAKE_SOURCE_DIR}/tests/modules/common
4334 ${QTDBUSTEST_INCLUDE_DIRS}
4335 ${QTDBUSMOCK_INCLUDE_DIRS}
4336 )
4337
4338=== modified file 'tests/modules/SurfaceManager/CMakeLists.txt'
4339--- tests/modules/SurfaceManager/CMakeLists.txt 2015-11-17 14:47:38 +0000
4340+++ tests/modules/SurfaceManager/CMakeLists.txt 2015-12-04 13:04:35 +0000
4341@@ -3,14 +3,12 @@
4342 mirsurfaceitem_test.cpp
4343 mirsurface_test.cpp
4344 ${CMAKE_SOURCE_DIR}/src/common/debughelpers.cpp
4345- ${CMAKE_SOURCE_DIR}/tests/modules/common/fake_mirsurface.h
4346- ${CMAKE_SOURCE_DIR}/tests/modules/common/fake_session.h
4347 )
4348
4349 include_directories(
4350 ${CMAKE_SOURCE_DIR}/src/modules
4351 ${CMAKE_SOURCE_DIR}/src/platforms/mirserver
4352- ${CMAKE_SOURCE_DIR}/tests/modules/common
4353+ ${CMAKE_SOURCE_DIR}/tests/framework
4354 ${MIRSERVER_INCLUDE_DIRS}
4355 )
4356
4357@@ -19,11 +17,13 @@
4358 target_link_libraries(
4359 surfacemanager_test
4360
4361- qpa-mirserver
4362 unityapplicationplugin
4363
4364 Qt5::Test
4365
4366+ -L${CMAKE_BINARY_DIR}/tests/framework
4367+ qtmir-test-framework-static
4368+
4369 ${GTEST_BOTH_LIBRARIES}
4370 ${GMOCK_LIBRARIES}
4371 )
4372
4373=== modified file 'tests/modules/SurfaceManager/mirsurfaceitem_test.cpp'
4374--- tests/modules/SurfaceManager/mirsurfaceitem_test.cpp 2015-11-25 15:38:39 +0000
4375+++ tests/modules/SurfaceManager/mirsurfaceitem_test.cpp 2015-12-04 13:04:35 +0000
4376@@ -24,7 +24,7 @@
4377 // the test subject
4378 #include <Unity/Application/mirsurfaceitem.h>
4379
4380-// tests/modules/common
4381+// tests/framework
4382 #include <fake_mirsurface.h>
4383
4384 using namespace qtmir;
4385
4386=== modified file 'tests/modules/TaskController/CMakeLists.txt'
4387--- tests/modules/TaskController/CMakeLists.txt 2015-06-15 17:01:28 +0000
4388+++ tests/modules/TaskController/CMakeLists.txt 2015-12-04 13:04:35 +0000
4389@@ -7,18 +7,22 @@
4390 include_directories(
4391 ${APPLICATION_API_INCLUDE_DIRS}
4392 ${CMAKE_SOURCE_DIR}/src/modules
4393- ${CMAKE_SOURCE_DIR}/tests/modules/common
4394+ ${CMAKE_SOURCE_DIR}/tests/framework
4395 ${MIRSERVER_INCLUDE_DIRS}
4396 )
4397
4398 add_executable(taskcontroller_test ${TASK_CONTROLLER_TEST_SOURCES})
4399
4400+add_dependencies(taskcontroller_test qtmir-test-framework-static)
4401+
4402 target_link_libraries(
4403 taskcontroller_test
4404
4405- qpa-mirserver
4406 unityapplicationplugin
4407
4408+ -L${CMAKE_BINARY_DIR}/tests/framework
4409+ qtmir-test-framework-static
4410+
4411 ${GTEST_BOTH_LIBRARIES}
4412 ${GMOCK_LIBRARIES}
4413 )

Subscribers

People subscribed via source and target branches