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:~nick-dedekind/qtmir/polite-close
Diff against target: 4414 lines (+2256/-803)
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 (+57/-138)
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 functional testing Pending
Review via email: mp+279593@code.launchpad.net

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

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

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 : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
Michael Zanetti (mzanetti) wrote : Posted in a previous version of this proposal

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 : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
Gerry Boland (gerboland) wrote : Posted in a previous version of this proposal

Remind me why we want to support Stretch?

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

> 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.

Revision history for this message
Loïc Molinari (loic.molinari) wrote : Posted in a previous version of this proposal

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 : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
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 : 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)
426. By Daniel d'Andrada

Fix bad merge of polite-close

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

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 18:37:28 +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 18:37:28 +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 18:37:28 +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 18:37:28 +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 18:37:28 +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 18:37:28 +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 18:37:28 +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 18:37:28 +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 18:37:28 +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 18:37:28 +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 18:37:28 +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 18:37:28 +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 18:37:28 +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 18:37:28 +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 18:37:28 +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 18:37:28 +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 18:37:28 +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 18:37:28 +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 18:37:28 +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 18:37:28 +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 18:37:28 +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 18:37:28 +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- }
1458+ ulong timestamp) override;
1459
1460- QString appId() const override { return "foo-app"; }
1461+ QString appId() const override;
1462
1463 QCursor cursor() const override { return QCursor(); }
1464
1465+ void close() override {
1466+ Q_EMIT closeRequested();
1467+ }
1468+
1469+Q_SIGNALS:
1470+ void closeRequested();
1471+
1472 public Q_SLOTS:
1473- void onCompositorSwappedBuffers() override {}
1474+ void onCompositorSwappedBuffers() override;
1475
1476 ////
1477 // Test API from now on
1478
1479 public:
1480
1481- void drawFirstFrame() {
1482- if (!m_isFirstFrameDrawn) {
1483- m_isFirstFrameDrawn = true;
1484- Q_EMIT firstFrameDrawn();
1485- }
1486- }
1487-
1488- bool isFrameDropperRunning() const {
1489- return m_isFrameDropperRunning;
1490- }
1491-
1492- QList<TouchEvent> &touchesReceived() { return m_touchesReceived; }
1493+ void drawFirstFrame();
1494+
1495+ bool isFrameDropperRunning() const;
1496+
1497+ QList<TouchEvent> &touchesReceived();
1498
1499 private:
1500- void updateVisibility() {
1501- bool newVisible = false;
1502- QHashIterator<int, bool> i(m_views);
1503- while (i.hasNext()) {
1504- i.next();
1505- newVisible |= i.value();
1506- }
1507-
1508- if (m_visible != newVisible) {
1509- m_visible = newVisible;
1510- Q_EMIT visibleChanged(newVisible);
1511- }
1512- }
1513+ void updateVisibility();
1514
1515
1516 bool m_isFirstFrameDrawn;
1517
1518=== added file 'tests/framework/fake_session.cpp'
1519--- tests/framework/fake_session.cpp 1970-01-01 00:00:00 +0000
1520+++ tests/framework/fake_session.cpp 2015-12-04 18:37:28 +0000
1521@@ -0,0 +1,113 @@
1522+/*
1523+ * Copyright (C) 2015 Canonical, Ltd.
1524+ *
1525+ * This program is free software: you can redistribute it and/or modify it under
1526+ * the terms of the GNU Lesser General Public License version 3, as published by
1527+ * the Free Software Foundation.
1528+ *
1529+ * This program is distributed in the hope that it will be useful, but WITHOUT
1530+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
1531+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1532+ * Lesser General Public License for more details.
1533+ *
1534+ * You should have received a copy of the GNU Lesser General Public License
1535+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1536+ */
1537+
1538+#include "fake_session.h"
1539+
1540+namespace qtmir
1541+{
1542+
1543+FakeSession::FakeSession()
1544+ : SessionInterface(0)
1545+ , m_application(nullptr)
1546+ , m_state(Starting)
1547+{
1548+}
1549+
1550+FakeSession::~FakeSession()
1551+{
1552+}
1553+
1554+void FakeSession::release() {}
1555+
1556+QString FakeSession::name() const { return QString("foo-session"); }
1557+
1558+unity::shell::application::ApplicationInfoInterface *FakeSession::application() const { return m_application; }
1559+
1560+MirSurfaceInterface *FakeSession::surface() const { return nullptr; }
1561+
1562+SessionInterface *FakeSession::parentSession() const { return nullptr; }
1563+
1564+SessionModel *FakeSession::childSessions() const { return nullptr; }
1565+
1566+SessionInterface::State FakeSession::state() const { return m_state; }
1567+
1568+bool FakeSession::fullscreen() const { return false; }
1569+
1570+bool FakeSession::live() const { return true; }
1571+
1572+std::shared_ptr<mir::scene::Session> FakeSession::session() const { return nullptr; }
1573+
1574+void FakeSession::setSurface(MirSurfaceInterface *) {}
1575+
1576+void FakeSession::setApplication(unity::shell::application::ApplicationInfoInterface *app)
1577+{
1578+ if (m_application != app) {
1579+ m_application = app;
1580+ Q_EMIT applicationChanged(m_application);
1581+ }
1582+}
1583+
1584+void FakeSession::suspend()
1585+{
1586+ if (m_state == Running) {
1587+ setState(Suspending);
1588+ }
1589+}
1590+
1591+void FakeSession::resume()
1592+{
1593+ if (m_state == Suspending || m_state == Suspended) {
1594+ setState(Running);
1595+ }
1596+}
1597+
1598+void FakeSession::stop()
1599+{
1600+ setState(Stopped);
1601+}
1602+
1603+void FakeSession::addChildSession(SessionInterface *) {}
1604+
1605+void FakeSession::insertChildSession(uint, SessionInterface *) {}
1606+
1607+void FakeSession::removeChildSession(SessionInterface *) {}
1608+
1609+void FakeSession::foreachChildSession(std::function<void (SessionInterface *)>) const {}
1610+
1611+std::shared_ptr<mir::scene::PromptSession> FakeSession::activePromptSession() const
1612+{
1613+ return std::shared_ptr<mir::scene::PromptSession>();
1614+}
1615+
1616+void FakeSession::foreachPromptSession(std::function<void (const std::shared_ptr<mir::scene::PromptSession> &)>) const {}
1617+
1618+void FakeSession::setFullscreen(bool) {}
1619+
1620+void FakeSession::setLive(const bool) {}
1621+
1622+void FakeSession::appendPromptSession(const std::shared_ptr<mir::scene::PromptSession> &) {}
1623+
1624+void FakeSession::removePromptSession(const std::shared_ptr<mir::scene::PromptSession> &) {}
1625+
1626+void FakeSession::setState(SessionInterface::State state)
1627+{
1628+ if (m_state != state) {
1629+ m_state = state;
1630+ Q_EMIT stateChanged(m_state);
1631+ }
1632+}
1633+
1634+} // namespace qtmir
1635
1636=== modified file 'tests/framework/fake_session.h'
1637--- tests/modules/common/fake_session.h 2015-10-20 09:57:17 +0000
1638+++ tests/framework/fake_session.h 2015-12-04 18:37:28 +0000
1639@@ -15,6 +15,7 @@
1640 */
1641
1642 #include <Unity/Application/session_interface.h>
1643+#include <QDebug>
1644
1645 #ifndef QTMIR_FAKE_SESSION_H
1646 #define QTMIR_FAKE_SESSION_H
1647@@ -26,78 +27,55 @@
1648 Q_OBJECT
1649
1650 public:
1651- FakeSession()
1652- : SessionInterface(0)
1653- , m_application(nullptr)
1654- , m_state(Starting)
1655- {
1656- }
1657+ FakeSession();
1658+ virtual ~FakeSession();
1659
1660 // For QML use
1661- void release() override {}
1662-
1663- QString name() const override { return QString("foo-session"); }
1664- unity::shell::application::ApplicationInfoInterface* application() const override { return m_application; }
1665- MirSurfaceInterface* surface() const override { return nullptr; }
1666- SessionInterface* parentSession() const override { return nullptr; }
1667- SessionModel* childSessions() const override { return nullptr; }
1668- State state() const override { return m_state; }
1669- bool fullscreen() const override { return false; }
1670- bool live() const override { return true; }
1671-
1672- std::shared_ptr<mir::scene::Session> session() const override { return nullptr; }
1673+ void release() override;
1674+
1675+ QString name() const override;
1676+ unity::shell::application::ApplicationInfoInterface* application() const override;
1677+ MirSurfaceInterface* surface() const override;
1678+ SessionInterface* parentSession() const override;
1679+ SessionModel* childSessions() const override;
1680+ State state() const override;
1681+ bool fullscreen() const override;
1682+ bool live() const override;
1683+
1684+ std::shared_ptr<mir::scene::Session> session() const override;
1685
1686 // For MirSurfaceItem and MirSurfaceManager use
1687
1688- void setSurface(MirSurfaceInterface*) override {}
1689+ void setSurface(MirSurfaceInterface*) override;
1690
1691 // For Application use
1692
1693- void setApplication(unity::shell::application::ApplicationInfoInterface* app) override {
1694- if (m_application != app) {
1695- m_application = app;
1696- Q_EMIT applicationChanged(m_application);
1697- }
1698- }
1699- void suspend() override {
1700- if (m_state == Running) {
1701- setState(Suspending);
1702- }
1703- }
1704- void resume() override {
1705- if (m_state == Suspending || m_state == Suspended) {
1706- setState(Running);
1707- }
1708- }
1709- void stop() override {
1710- setState(Stopped);
1711+ void setApplication(unity::shell::application::ApplicationInfoInterface* app) override;
1712+ void suspend() override;
1713+ void resume() override;
1714+ void stop() override;
1715+
1716+ void close() override {
1717 }
1718
1719 // For SessionManager use
1720
1721- void addChildSession(SessionInterface*) override {}
1722- void insertChildSession(uint, SessionInterface*) override {}
1723- void removeChildSession(SessionInterface*) override {}
1724- void foreachChildSession(std::function<void(SessionInterface* session)>) const override {}
1725-
1726- std::shared_ptr<mir::scene::PromptSession> activePromptSession() const override {
1727- return std::shared_ptr<mir::scene::PromptSession>();
1728- }
1729- void foreachPromptSession(std::function<void(const std::shared_ptr<mir::scene::PromptSession>&)>) const override {}
1730-
1731- void setFullscreen(bool) override {}
1732- void setLive(const bool) override {}
1733- void appendPromptSession(const std::shared_ptr<mir::scene::PromptSession>&) override {}
1734- void removePromptSession(const std::shared_ptr<mir::scene::PromptSession>&) override {}
1735+ void addChildSession(SessionInterface*) override;
1736+ void insertChildSession(uint, SessionInterface*) override;
1737+ void removeChildSession(SessionInterface*) override;
1738+ void foreachChildSession(std::function<void(SessionInterface* session)>) const override;
1739+
1740+ std::shared_ptr<mir::scene::PromptSession> activePromptSession() const override;
1741+ void foreachPromptSession(std::function<void(const std::shared_ptr<mir::scene::PromptSession>&)>) const override;
1742+
1743+ void setFullscreen(bool) override;
1744+ void setLive(const bool) override;
1745+ void appendPromptSession(const std::shared_ptr<mir::scene::PromptSession>&) override;
1746+ void removePromptSession(const std::shared_ptr<mir::scene::PromptSession>&) override;
1747
1748 // For tests
1749
1750- void setState(State state) {
1751- if (m_state != state) {
1752- m_state = state;
1753- Q_EMIT stateChanged(m_state);
1754- }
1755- }
1756+ void setState(State state);
1757
1758 private:
1759 unity::shell::application::ApplicationInfoInterface* m_application;
1760
1761=== renamed file 'tests/common/gmock_fixes.h' => 'tests/framework/gmock_fixes.h'
1762=== added file 'tests/framework/mock_application_controller.cpp'
1763--- tests/framework/mock_application_controller.cpp 1970-01-01 00:00:00 +0000
1764+++ tests/framework/mock_application_controller.cpp 2015-12-04 18:37:28 +0000
1765@@ -0,0 +1,129 @@
1766+/*
1767+ * Copyright (C) 2015 Canonical, Ltd.
1768+ *
1769+ * This program is free software: you can redistribute it and/or modify it under
1770+ * the terms of the GNU Lesser General Public License version 3, as published by
1771+ * the Free Software Foundation.
1772+ *
1773+ * This program is distributed in the hope that it will be useful, but WITHOUT
1774+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
1775+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1776+ * Lesser General Public License for more details.
1777+ *
1778+ * You should have received a copy of the GNU Lesser General Public License
1779+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1780+ */
1781+
1782+#include "mock_application_controller.h"
1783+
1784+namespace qtmir
1785+{
1786+
1787+MockApplicationController::MockApplicationController()
1788+{
1789+ using namespace ::testing;
1790+ ON_CALL(*this, primaryPidForAppId(_))
1791+ .WillByDefault(
1792+ Invoke(this, &MockApplicationController::doPrimaryPidForAppId));
1793+
1794+ ON_CALL(*this, appIdHasProcessId(_, _))
1795+ .WillByDefault(
1796+ Invoke(this, &MockApplicationController::doAppIdHasProcessId));
1797+
1798+ ON_CALL(*this, findDesktopFileForAppId(_))
1799+ .WillByDefault(
1800+ Invoke(this, &MockApplicationController::doFindDesktopFileForAppId));
1801+
1802+ ON_CALL(*this, stopApplicationWithAppId(_))
1803+ .WillByDefault(
1804+ Invoke(this, &MockApplicationController::doStopApplicationWithAppId));
1805+
1806+ ON_CALL(*this, startApplicationWithAppIdAndArgs(_, _))
1807+ .WillByDefault(
1808+ Invoke(this, &MockApplicationController::doStartApplicationWithAppIdAndArgs));
1809+
1810+ ON_CALL(*this, pauseApplicationWithAppId(_))
1811+ .WillByDefault(
1812+ Invoke(this, &MockApplicationController::doPauseApplicationWithAppId));
1813+
1814+ ON_CALL(*this, resumeApplicationWithAppId(_))
1815+ .WillByDefault(
1816+ Invoke(this, &MockApplicationController::doResumeApplicationWithAppId));
1817+}
1818+
1819+MockApplicationController::~MockApplicationController()
1820+{
1821+
1822+}
1823+
1824+pid_t MockApplicationController::doPrimaryPidForAppId(const QString &appId)
1825+{
1826+ auto it = children.find(appId);
1827+ if (it == children.end())
1828+ return -1;
1829+
1830+ return it->pid();
1831+}
1832+
1833+
1834+bool MockApplicationController::doAppIdHasProcessId(pid_t pid, const QString &appId)
1835+{
1836+ auto it = children.find(appId);
1837+ if (it == children.end())
1838+ return -1;
1839+
1840+ return it->pid() == pid;
1841+}
1842+
1843+
1844+QFileInfo MockApplicationController::doFindDesktopFileForAppId(const QString &appId) const
1845+{
1846+ QString path = QString("/usr/share/applications/%1.desktop").arg(appId);
1847+ return QFileInfo(path);
1848+}
1849+
1850+
1851+bool MockApplicationController::doStopApplicationWithAppId(const QString &appId)
1852+{
1853+ Q_UNUSED(appId);
1854+
1855+ return false;
1856+}
1857+
1858+
1859+bool MockApplicationController::doStartApplicationWithAppIdAndArgs(const QString &appId, const QStringList &args)
1860+{
1861+ Q_UNUSED(args);
1862+
1863+ auto child = core::posix::fork([]()
1864+ {
1865+ while (true);
1866+
1867+ return core::posix::exit::Status::success;
1868+ }, core::posix::StandardStream::empty);
1869+
1870+ if (child.pid() > 0)
1871+ {
1872+ children.insert(appId, child);
1873+ return true;
1874+ }
1875+
1876+ return false;
1877+}
1878+
1879+
1880+bool MockApplicationController::doPauseApplicationWithAppId(const QString &appId)
1881+{
1882+ Q_UNUSED(appId);
1883+
1884+ return false;
1885+}
1886+
1887+bool MockApplicationController::doResumeApplicationWithAppId(const QString &appId)
1888+{
1889+ Q_UNUSED(appId);
1890+
1891+ return false;
1892+}
1893+
1894+} // namespace qtmir
1895
1896=== modified file 'tests/framework/mock_application_controller.h'
1897--- tests/modules/common/mock_application_controller.h 2015-08-11 12:08:32 +0000
1898+++ tests/framework/mock_application_controller.h 2015-12-04 18:37:28 +0000
1899@@ -18,15 +18,19 @@
1900 #define MOCK_APPLICATION_CONTROLLER_H
1901
1902 #include <Unity/Application/applicationcontroller.h>
1903+#include <QMap>
1904
1905 #include <core/posix/fork.h>
1906
1907 #include <gmock/gmock.h>
1908
1909-namespace testing
1910+namespace qtmir
1911 {
1912 struct MockApplicationController : public qtmir::ApplicationController
1913 {
1914+ MockApplicationController();
1915+ virtual ~MockApplicationController();
1916+
1917 MOCK_METHOD1(primaryPidForAppId, pid_t(const QString& appId));
1918 MOCK_METHOD2(appIdHasProcessId, bool(pid_t, const QString&));
1919 MOCK_CONST_METHOD1(findDesktopFileForAppId, QFileInfo(const QString &appId));
1920@@ -36,105 +40,24 @@
1921 MOCK_METHOD1(pauseApplicationWithAppId, bool(const QString&));
1922 MOCK_METHOD1(resumeApplicationWithAppId, bool(const QString&));
1923
1924- MockApplicationController()
1925- {
1926- using namespace ::testing;
1927- ON_CALL(*this, primaryPidForAppId(_))
1928- .WillByDefault(
1929- Invoke(this, &MockApplicationController::doPrimaryPidForAppId));
1930-
1931- ON_CALL(*this, appIdHasProcessId(_, _))
1932- .WillByDefault(
1933- Invoke(this, &MockApplicationController::doAppIdHasProcessId));
1934-
1935- ON_CALL(*this, findDesktopFileForAppId(_))
1936- .WillByDefault(
1937- Invoke(this, &MockApplicationController::doFindDesktopFileForAppId));
1938-
1939- ON_CALL(*this, stopApplicationWithAppId(_))
1940- .WillByDefault(
1941- Invoke(this, &MockApplicationController::doStopApplicationWithAppId));
1942-
1943- ON_CALL(*this, startApplicationWithAppIdAndArgs(_, _))
1944- .WillByDefault(
1945- Invoke(this, &MockApplicationController::doStartApplicationWithAppIdAndArgs));
1946-
1947- ON_CALL(*this, pauseApplicationWithAppId(_))
1948- .WillByDefault(
1949- Invoke(this, &MockApplicationController::doPauseApplicationWithAppId));
1950-
1951- ON_CALL(*this, resumeApplicationWithAppId(_))
1952- .WillByDefault(
1953- Invoke(this, &MockApplicationController::doResumeApplicationWithAppId));
1954- }
1955-
1956- pid_t doPrimaryPidForAppId(const QString& appId)
1957- {
1958- auto it = children.find(appId);
1959- if (it == children.end())
1960- return -1;
1961-
1962- return it->pid();
1963- }
1964-
1965- bool doAppIdHasProcessId(pid_t pid, const QString& appId)
1966- {
1967- auto it = children.find(appId);
1968- if (it == children.end())
1969- return -1;
1970-
1971- return it->pid() == pid;
1972- }
1973-
1974- QFileInfo doFindDesktopFileForAppId(const QString& appId) const
1975- {
1976- QString path = QString("/usr/share/applications/%1.desktop").arg(appId);
1977- return QFileInfo(path);
1978- }
1979-
1980- bool doStopApplicationWithAppId(const QString& appId)
1981- {
1982- Q_UNUSED(appId);
1983-
1984- return false;
1985- }
1986-
1987- bool doStartApplicationWithAppIdAndArgs(const QString& appId, const QStringList& args)
1988- {
1989- Q_UNUSED(args);
1990-
1991- auto child = core::posix::fork([]()
1992- {
1993- while (true);
1994-
1995- return core::posix::exit::Status::success;
1996- }, core::posix::StandardStream::empty);
1997-
1998- if (child.pid() > 0)
1999- {
2000- children.insert(appId, child);
2001- return true;
2002- }
2003-
2004- return false;
2005- }
2006-
2007- bool doPauseApplicationWithAppId(const QString& appId)
2008- {
2009- Q_UNUSED(appId);
2010-
2011- return false;
2012- }
2013-
2014- bool doResumeApplicationWithAppId(const QString& appId)
2015- {
2016- Q_UNUSED(appId);
2017-
2018- return false;
2019- }
2020-
2021+ pid_t doPrimaryPidForAppId(const QString& appId);
2022+
2023+ bool doAppIdHasProcessId(pid_t pid, const QString& appId);
2024+
2025+ QFileInfo doFindDesktopFileForAppId(const QString& appId) const;
2026+
2027+ bool doStopApplicationWithAppId(const QString& appId);
2028+
2029+ bool doStartApplicationWithAppIdAndArgs(const QString& appId, const QStringList& args);
2030+
2031+ bool doPauseApplicationWithAppId(const QString& appId);
2032+
2033+ bool doResumeApplicationWithAppId(const QString& appId);
2034+
2035+private:
2036 QMap<QString, core::posix::ChildProcess> children;
2037 };
2038-} // namespace testing
2039+
2040+} // namespace qtmir
2041
2042 #endif // MOCK_APPLICATION_CONTROLLER_H
2043
2044=== added file 'tests/framework/mock_desktop_file_reader.cpp'
2045--- tests/framework/mock_desktop_file_reader.cpp 1970-01-01 00:00:00 +0000
2046+++ tests/framework/mock_desktop_file_reader.cpp 2015-12-04 18:37:28 +0000
2047@@ -0,0 +1,117 @@
2048+/*
2049+ * Copyright (C) 2015 Canonical, Ltd.
2050+ *
2051+ * This program is free software: you can redistribute it and/or modify it under
2052+ * the terms of the GNU Lesser General Public License version 3, as published by
2053+ * the Free Software Foundation.
2054+ *
2055+ * This program is distributed in the hope that it will be useful, but WITHOUT
2056+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
2057+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2058+ * Lesser General Public License for more details.
2059+ *
2060+ * You should have received a copy of the GNU Lesser General Public License
2061+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2062+ */
2063+
2064+#include "mock_desktop_file_reader.h"
2065+
2066+namespace qtmir
2067+{
2068+
2069+MockDesktopFileReader::MockDesktopFileReader(const QString &appId, const QFileInfo &fileInfo)
2070+ : DesktopFileReader(appId, fileInfo)
2071+{
2072+ using namespace ::testing;
2073+
2074+ ON_CALL(*this, file()).WillByDefault(Invoke(this, &MockDesktopFileReader::doFile));
2075+ ON_CALL(*this, appId()).WillByDefault(Invoke(this, &MockDesktopFileReader::doAppId));
2076+ ON_CALL(*this, name()).WillByDefault(Invoke(this, &MockDesktopFileReader::doName));
2077+ ON_CALL(*this, comment()).WillByDefault(Invoke(this, &MockDesktopFileReader::doComment));
2078+ ON_CALL(*this, icon()).WillByDefault(Invoke(this, &MockDesktopFileReader::doIcon));
2079+ ON_CALL(*this, exec()).WillByDefault(Invoke(this, &MockDesktopFileReader::doExec));
2080+ ON_CALL(*this, path()).WillByDefault(Invoke(this, &MockDesktopFileReader::doPath));
2081+ ON_CALL(*this, stageHint()).WillByDefault(Invoke(this, &MockDesktopFileReader::doStageHint));
2082+ ON_CALL(*this, isTouchApp()).WillByDefault(Invoke(this, &MockDesktopFileReader::doIsTouchApp));
2083+ ON_CALL(*this, loaded()).WillByDefault(Invoke(this, &MockDesktopFileReader::doLoaded));
2084+}
2085+
2086+MockDesktopFileReader::~MockDesktopFileReader()
2087+{
2088+}
2089+
2090+QString MockDesktopFileReader::doFile() const
2091+{
2092+ return DesktopFileReader::file();
2093+}
2094+
2095+QString MockDesktopFileReader::doAppId() const
2096+{
2097+ return DesktopFileReader::appId();
2098+}
2099+
2100+QString MockDesktopFileReader::doName() const
2101+{
2102+ return DesktopFileReader::name();
2103+}
2104+
2105+QString MockDesktopFileReader::doComment() const
2106+{
2107+ return DesktopFileReader::comment();
2108+}
2109+
2110+QString MockDesktopFileReader::doIcon() const
2111+{
2112+ return DesktopFileReader::icon();
2113+}
2114+
2115+QString MockDesktopFileReader::doExec() const
2116+{
2117+ return DesktopFileReader::exec();
2118+}
2119+
2120+QString MockDesktopFileReader::doPath() const
2121+{
2122+ return DesktopFileReader::path();
2123+}
2124+
2125+QString MockDesktopFileReader::doStageHint() const
2126+{
2127+ return DesktopFileReader::stageHint();
2128+}
2129+
2130+bool MockDesktopFileReader::doIsTouchApp() const
2131+{
2132+ return DesktopFileReader::isTouchApp();
2133+}
2134+
2135+bool MockDesktopFileReader::doLoaded() const
2136+{
2137+ return DesktopFileReader::loaded();
2138+}
2139+
2140+
2141+MockDesktopFileReaderFactory::MockDesktopFileReaderFactory()
2142+{
2143+ using namespace ::testing;
2144+ ON_CALL(*this, createInstance(_, _))
2145+ .WillByDefault(
2146+ Invoke(
2147+ this,
2148+ &MockDesktopFileReaderFactory::doCreateInstance));
2149+}
2150+
2151+MockDesktopFileReaderFactory::~MockDesktopFileReaderFactory()
2152+{
2153+}
2154+
2155+qtmir::DesktopFileReader *MockDesktopFileReaderFactory::doCreateInstance(const QString &appId, const QFileInfo &fi)
2156+{
2157+ using namespace ::testing;
2158+ auto instance = new NiceMock<MockDesktopFileReader>(appId, fi);
2159+ ON_CALL(*instance, loaded()).WillByDefault(Return(true));
2160+
2161+ return instance;
2162+}
2163+
2164+} // namespace qtmir
2165
2166=== modified file 'tests/framework/mock_desktop_file_reader.h'
2167--- tests/modules/common/mock_desktop_file_reader.h 2015-09-29 18:27:27 +0000
2168+++ tests/framework/mock_desktop_file_reader.h 2015-12-04 18:37:28 +0000
2169@@ -21,26 +21,13 @@
2170
2171 #include <gmock/gmock.h>
2172
2173-namespace testing
2174+namespace qtmir
2175 {
2176+
2177 struct MockDesktopFileReader : public qtmir::DesktopFileReader
2178 {
2179- MockDesktopFileReader(const QString &appId, const QFileInfo& fileInfo)
2180- : DesktopFileReader(appId, fileInfo)
2181- {
2182- using namespace ::testing;
2183-
2184- ON_CALL(*this, file()).WillByDefault(Invoke(this, &MockDesktopFileReader::doFile));
2185- ON_CALL(*this, appId()).WillByDefault(Invoke(this, &MockDesktopFileReader::doAppId));
2186- ON_CALL(*this, name()).WillByDefault(Invoke(this, &MockDesktopFileReader::doName));
2187- ON_CALL(*this, comment()).WillByDefault(Invoke(this, &MockDesktopFileReader::doComment));
2188- ON_CALL(*this, icon()).WillByDefault(Invoke(this, &MockDesktopFileReader::doIcon));
2189- ON_CALL(*this, exec()).WillByDefault(Invoke(this, &MockDesktopFileReader::doExec));
2190- ON_CALL(*this, path()).WillByDefault(Invoke(this, &MockDesktopFileReader::doPath));
2191- ON_CALL(*this, stageHint()).WillByDefault(Invoke(this, &MockDesktopFileReader::doStageHint));
2192- ON_CALL(*this, isTouchApp()).WillByDefault(Invoke(this, &MockDesktopFileReader::doIsTouchApp));
2193- ON_CALL(*this, loaded()).WillByDefault(Invoke(this, &MockDesktopFileReader::doLoaded));
2194- }
2195+ MockDesktopFileReader(const QString &appId, const QFileInfo& fileInfo);
2196+ virtual ~MockDesktopFileReader();
2197
2198 MOCK_CONST_METHOD0(file, QString());
2199 MOCK_CONST_METHOD0(appId, QString ());
2200@@ -53,80 +40,28 @@
2201 MOCK_CONST_METHOD0(isTouchApp, bool());
2202 MOCK_CONST_METHOD0(loaded, bool());
2203
2204- QString doFile() const
2205- {
2206- return DesktopFileReader::file();
2207- }
2208-
2209- QString doAppId() const
2210- {
2211- return DesktopFileReader::appId();
2212- }
2213-
2214- QString doName() const
2215- {
2216- return DesktopFileReader::name();
2217- }
2218-
2219- QString doComment() const
2220- {
2221- return DesktopFileReader::comment();
2222- }
2223-
2224- QString doIcon() const
2225- {
2226- return DesktopFileReader::icon();
2227- }
2228-
2229- QString doExec() const
2230- {
2231- return DesktopFileReader::exec();
2232- }
2233-
2234- QString doPath() const
2235- {
2236- return DesktopFileReader::path();
2237- }
2238-
2239- QString doStageHint() const
2240- {
2241- return DesktopFileReader::stageHint();
2242- }
2243-
2244- bool doIsTouchApp() const
2245- {
2246- return DesktopFileReader::isTouchApp();
2247- }
2248-
2249- bool doLoaded() const
2250- {
2251- return DesktopFileReader::loaded();
2252- }
2253+ QString doFile() const;
2254+ QString doAppId() const;
2255+ QString doName() const;
2256+ QString doComment() const;
2257+ QString doIcon() const;
2258+ QString doExec() const;
2259+ QString doPath() const;
2260+ QString doStageHint() const;
2261+ bool doIsTouchApp() const;
2262+ bool doLoaded() const;
2263 };
2264
2265 struct MockDesktopFileReaderFactory : public qtmir::DesktopFileReader::Factory
2266 {
2267- MockDesktopFileReaderFactory()
2268- {
2269- using namespace ::testing;
2270- ON_CALL(*this, createInstance(_, _))
2271- .WillByDefault(
2272- Invoke(
2273- this,
2274- &MockDesktopFileReaderFactory::doCreateInstance));
2275- }
2276-
2277- virtual qtmir::DesktopFileReader* doCreateInstance(const QString &appId, const QFileInfo &fi)
2278- {
2279- using namespace ::testing;
2280- auto instance = new NiceMock<MockDesktopFileReader>(appId, fi);
2281- ON_CALL(*instance, loaded()).WillByDefault(Return(true));
2282-
2283- return instance;
2284- }
2285+ MockDesktopFileReaderFactory();
2286+ virtual ~MockDesktopFileReaderFactory();
2287+
2288+ virtual qtmir::DesktopFileReader* doCreateInstance(const QString &appId, const QFileInfo &fi);
2289
2290 MOCK_METHOD2(createInstance, qtmir::DesktopFileReader*(const QString &appId, const QFileInfo &fi));
2291 };
2292-}
2293+
2294+} // namespace qtmir
2295
2296 #endif // MOCK_DESKTOP_FILE_READER_H
2297
2298=== added file 'tests/framework/mock_display.cpp'
2299--- tests/framework/mock_display.cpp 1970-01-01 00:00:00 +0000
2300+++ tests/framework/mock_display.cpp 2015-12-04 18:37:28 +0000
2301@@ -0,0 +1,35 @@
2302+/*
2303+ * Copyright (C) 2015 Canonical, Ltd.
2304+ *
2305+ * This program is free software: you can redistribute it and/or modify it under
2306+ * the terms of the GNU Lesser General Public License version 3, as published by
2307+ * the Free Software Foundation.
2308+ *
2309+ * This program is distributed in the hope that it will be useful, but WITHOUT
2310+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
2311+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2312+ * Lesser General Public License for more details.
2313+ *
2314+ * You should have received a copy of the GNU Lesser General Public License
2315+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2316+ */
2317+
2318+#include "mock_display.h"
2319+#include <mir/graphics/event_handler_register.h>
2320+#include <mir/graphics/display_configuration.h>
2321+
2322+MockDisplaySyncGroup::MockDisplaySyncGroup()
2323+{
2324+}
2325+
2326+MockDisplaySyncGroup::~MockDisplaySyncGroup()
2327+{
2328+}
2329+
2330+MockDisplay::MockDisplay()
2331+{
2332+}
2333+
2334+MockDisplay::~MockDisplay()
2335+{
2336+}
2337
2338=== renamed file 'tests/common/mock_display.h' => 'tests/framework/mock_display.h'
2339--- tests/common/mock_display.h 2015-08-20 10:16:54 +0000
2340+++ tests/framework/mock_display.h 2015-12-04 18:37:28 +0000
2341@@ -26,6 +26,9 @@
2342 class MockDisplaySyncGroup : public mir::graphics::DisplaySyncGroup
2343 {
2344 public:
2345+ MockDisplaySyncGroup();
2346+ virtual ~MockDisplaySyncGroup();
2347+
2348 MOCK_METHOD1(for_each_display_buffer, void(std::function<void(mir::graphics::DisplayBuffer&)> const& f));
2349 MOCK_METHOD0(post, void());
2350 };
2351@@ -33,6 +36,9 @@
2352 struct MockDisplay : public mir::graphics::Display
2353 {
2354 public:
2355+ MockDisplay();
2356+ virtual ~MockDisplay();
2357+
2358 MOCK_METHOD1(for_each_display_sync_group, void(std::function<void(mir::graphics::DisplaySyncGroup&)> const&));
2359 MOCK_CONST_METHOD0(configuration, std::unique_ptr<mir::graphics::DisplayConfiguration>());
2360 MOCK_METHOD1(configure, void(mir::graphics::DisplayConfiguration const&));
2361@@ -48,6 +54,4 @@
2362 MOCK_METHOD0(create_gl_context, std::unique_ptr<mir::graphics::GLContext>());
2363 };
2364
2365-
2366-
2367 #endif // MOCKDISPLAY_H
2368
2369=== added file 'tests/framework/mock_display_configuration.cpp'
2370--- tests/framework/mock_display_configuration.cpp 1970-01-01 00:00:00 +0000
2371+++ tests/framework/mock_display_configuration.cpp 2015-12-04 18:37:28 +0000
2372@@ -0,0 +1,25 @@
2373+/*
2374+ * Copyright (C) 2015 Canonical, Ltd.
2375+ *
2376+ * This program is free software: you can redistribute it and/or modify it under
2377+ * the terms of the GNU Lesser General Public License version 3, as published by
2378+ * the Free Software Foundation.
2379+ *
2380+ * This program is distributed in the hope that it will be useful, but WITHOUT
2381+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
2382+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2383+ * Lesser General Public License for more details.
2384+ *
2385+ * You should have received a copy of the GNU Lesser General Public License
2386+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2387+ */
2388+
2389+#include "mock_display_configuration.h"
2390+
2391+MockDisplayConfiguration::MockDisplayConfiguration()
2392+{
2393+}
2394+
2395+MockDisplayConfiguration::~MockDisplayConfiguration()
2396+{
2397+}
2398
2399=== renamed file 'tests/common/mock_display_configuration.h' => 'tests/framework/mock_display_configuration.h'
2400--- tests/common/mock_display_configuration.h 2015-08-20 10:16:54 +0000
2401+++ tests/framework/mock_display_configuration.h 2015-12-04 18:37:28 +0000
2402@@ -25,6 +25,9 @@
2403 class MockDisplayConfiguration : public mir::graphics::DisplayConfiguration
2404 {
2405 public:
2406+ MockDisplayConfiguration();
2407+ virtual ~MockDisplayConfiguration();
2408+
2409 MOCK_CONST_METHOD1(for_each_card, void(std::function<void(mir::graphics::DisplayConfigurationCard const&)>));
2410
2411 MOCK_CONST_METHOD1(for_each_output, void(std::function<void(mir::graphics::DisplayConfigurationOutput const&)>));
2412@@ -32,4 +35,5 @@
2413
2414 MOCK_CONST_METHOD0(valid, bool());
2415 };
2416+
2417 #endif // MOCK_DISPLAY_CONFIGURATION_H
2418
2419=== added file 'tests/framework/mock_gl_display_buffer.cpp'
2420--- tests/framework/mock_gl_display_buffer.cpp 1970-01-01 00:00:00 +0000
2421+++ tests/framework/mock_gl_display_buffer.cpp 2015-12-04 18:37:28 +0000
2422@@ -0,0 +1,30 @@
2423+/*
2424+ * Copyright (C) 2015 Canonical, Ltd.
2425+ *
2426+ * This program is free software: you can redistribute it and/or modify it under
2427+ * the terms of the GNU Lesser General Public License version 3, as published by
2428+ * the Free Software Foundation.
2429+ *
2430+ * This program is distributed in the hope that it will be useful, but WITHOUT
2431+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
2432+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2433+ * Lesser General Public License for more details.
2434+ *
2435+ * You should have received a copy of the GNU Lesser General Public License
2436+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2437+ */
2438+
2439+#include "mock_gl_display_buffer.h"
2440+
2441+MockGLDisplayBuffer::MockGLDisplayBuffer()
2442+{
2443+ using namespace testing;
2444+ ON_CALL(*this, view_area())
2445+ .WillByDefault(Return(mir::geometry::Rectangle{{0,0},{0,0}}));
2446+ ON_CALL(*this, native_display_buffer())
2447+ .WillByDefault(Return(dynamic_cast<mir::graphics::NativeDisplayBuffer*>(this)));
2448+}
2449+
2450+MockGLDisplayBuffer::~MockGLDisplayBuffer()
2451+{
2452+}
2453
2454=== renamed file 'tests/common/mock_gl_display_buffer.h' => 'tests/framework/mock_gl_display_buffer.h'
2455--- tests/common/mock_gl_display_buffer.h 2015-10-14 23:14:48 +0000
2456+++ tests/framework/mock_gl_display_buffer.h 2015-12-04 18:37:28 +0000
2457@@ -27,14 +27,9 @@
2458 public mir::graphics::NativeDisplayBuffer
2459 {
2460 public:
2461- MockGLDisplayBuffer()
2462- {
2463- using namespace testing;
2464- ON_CALL(*this, view_area())
2465- .WillByDefault(Return(mir::geometry::Rectangle{{0,0},{0,0}}));
2466- ON_CALL(*this, native_display_buffer())
2467- .WillByDefault(Return(dynamic_cast<mir::graphics::NativeDisplayBuffer*>(this)));
2468- }
2469+ MockGLDisplayBuffer();
2470+ virtual ~MockGLDisplayBuffer();
2471+
2472 MOCK_CONST_METHOD0(view_area, mir::geometry::Rectangle());
2473 MOCK_METHOD1(post_renderables_if_optimizable, bool(mir::graphics::RenderableList const&));
2474 MOCK_CONST_METHOD0(orientation, MirOrientation());
2475@@ -45,5 +40,4 @@
2476 MOCK_METHOD0(swap_buffers, void());
2477 };
2478
2479-
2480 #endif // MOCK_GL_DISPLAY_BUFFER_H
2481
2482=== added file 'tests/framework/mock_main_loop.cpp'
2483--- tests/framework/mock_main_loop.cpp 1970-01-01 00:00:00 +0000
2484+++ tests/framework/mock_main_loop.cpp 2015-12-04 18:37:28 +0000
2485@@ -0,0 +1,28 @@
2486+/*
2487+ * Copyright (C) 2015 Canonical, Ltd.
2488+ *
2489+ * This program is free software: you can redistribute it and/or modify it under
2490+ * the terms of the GNU Lesser General Public License version 3, as published by
2491+ * the Free Software Foundation.
2492+ *
2493+ * This program is distributed in the hope that it will be useful, but WITHOUT
2494+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
2495+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2496+ * Lesser General Public License for more details.
2497+ *
2498+ * You should have received a copy of the GNU Lesser General Public License
2499+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2500+ */
2501+
2502+#include "mock_main_loop.h"
2503+
2504+MockMainLoop::MockMainLoop()
2505+{
2506+}
2507+
2508+MockMainLoop::~MockMainLoop()
2509+{
2510+}
2511+
2512+void MockMainLoop::run() {}
2513+void MockMainLoop::stop() {}
2514\ No newline at end of file
2515
2516=== renamed file 'tests/common/mock_main_loop.h' => 'tests/framework/mock_main_loop.h'
2517--- tests/common/mock_main_loop.h 2015-08-20 10:16:54 +0000
2518+++ tests/framework/mock_main_loop.h 2015-12-04 18:37:28 +0000
2519@@ -17,19 +17,17 @@
2520 #ifndef MOCKMAINLOOP_H
2521 #define MOCKMAINLOOP_H
2522
2523-#include <gmock/gmock.h>
2524-
2525 #include <mir/main_loop.h>
2526-
2527-#include <memory>
2528+#include "gmock_fixes.h"
2529
2530 class MockMainLoop : public mir::MainLoop
2531 {
2532 public:
2533- ~MockMainLoop() noexcept {}
2534+ MockMainLoop();
2535+ ~MockMainLoop() noexcept;
2536
2537- void run() override {}
2538- void stop() override {}
2539+ void run() override;
2540+ void stop() override;
2541
2542 MOCK_METHOD2(register_signal_handler,
2543 void(std::initializer_list<int>,
2544@@ -49,5 +47,4 @@
2545 MOCK_METHOD1(create_alarm, std::unique_ptr<mir::time::Alarm>(std::shared_ptr<mir::LockableCallback> const& callback));
2546 };
2547
2548-
2549 #endif // MOCKMAINLOOP_H
2550
2551=== added file 'tests/framework/mock_mir_session.cpp'
2552--- tests/framework/mock_mir_session.cpp 1970-01-01 00:00:00 +0000
2553+++ tests/framework/mock_mir_session.cpp 2015-12-04 18:37:28 +0000
2554@@ -0,0 +1,63 @@
2555+/*
2556+ * Copyright (C) 2015 Canonical, Ltd.
2557+ *
2558+ * This program is free software: you can redistribute it and/or modify it under
2559+ * the terms of the GNU Lesser General Public License version 3, as published by
2560+ * the Free Software Foundation.
2561+ *
2562+ * This program is distributed in the hope that it will be useful, but WITHOUT
2563+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
2564+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2565+ * Lesser General Public License for more details.
2566+ *
2567+ * You should have received a copy of the GNU Lesser General Public License
2568+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2569+ */
2570+
2571+#include "mock_mir_session.h"
2572+
2573+namespace mir
2574+{
2575+namespace scene
2576+{
2577+
2578+MockSession::MockSession()
2579+{
2580+}
2581+
2582+MockSession::MockSession(const std::string &sessionName, pid_t processId)
2583+ : m_sessionName(sessionName), m_sessionId(processId)
2584+{
2585+}
2586+
2587+MockSession::~MockSession()
2588+{
2589+}
2590+
2591+std::string MockSession::name() const
2592+{
2593+ return m_sessionName;
2594+}
2595+
2596+pid_t MockSession::process_id() const
2597+{
2598+ return m_sessionId;
2599+}
2600+
2601+void MockSession::resume_prompt_session() {}
2602+
2603+void MockSession::suspend_prompt_session() {}
2604+
2605+void MockSession::stop_prompt_session() {}
2606+
2607+void MockSession::start_prompt_session() {}
2608+
2609+std::shared_ptr<scene::Surface> MockSession::surface_after(const std::shared_ptr<scene::Surface> &) const
2610+{
2611+ return {};
2612+}
2613+
2614+void MockSession::configure_streams(scene::Surface &, const std::vector<mir::shell::StreamSpecification> &) {}
2615+
2616+} // namespace scene
2617+} // namespace mir
2618
2619=== modified file 'tests/framework/mock_mir_session.h'
2620--- tests/modules/common/mock_mir_session.h 2015-10-07 14:38:44 +0000
2621+++ tests/framework/mock_mir_session.h 2015-12-04 18:37:28 +0000
2622@@ -29,20 +29,13 @@
2623
2624 struct MockSession : public Session
2625 {
2626- MockSession() {}
2627- MockSession(std::string const& sessionName, pid_t processId)
2628- : m_sessionName(sessionName), m_sessionId(processId)
2629- {}
2630-
2631- std::string name() const override
2632- {
2633- return m_sessionName;
2634- }
2635-
2636- pid_t process_id() const override
2637- {
2638- return m_sessionId;
2639- }
2640+ MockSession();
2641+ MockSession(std::string const& sessionName, pid_t processId);
2642+ virtual ~MockSession();
2643+
2644+ std::string name() const override;
2645+
2646+ pid_t process_id() const override;
2647
2648 MOCK_METHOD0(force_requests_to_complete, void());
2649
2650@@ -62,16 +55,16 @@
2651 MOCK_METHOD1(send_display_config, void(graphics::DisplayConfiguration const&));
2652 MOCK_METHOD3(configure_surface, int(frontend::SurfaceId, MirSurfaceAttrib, int));
2653
2654- void start_prompt_session() override {};
2655- void stop_prompt_session() override {};
2656- void suspend_prompt_session() override {};
2657- void resume_prompt_session() override {};
2658- std::shared_ptr<Surface> surface_after(std::shared_ptr<Surface> const&) const override { return {}; }
2659+ void start_prompt_session() override;
2660+ void stop_prompt_session() override;
2661+ void suspend_prompt_session() override;
2662+ void resume_prompt_session() override;
2663+ std::shared_ptr<Surface> surface_after(std::shared_ptr<Surface> const&) const override;
2664
2665 MOCK_CONST_METHOD1(get_buffer_stream, std::shared_ptr<frontend::BufferStream>(frontend::BufferStreamId));
2666 MOCK_METHOD1(destroy_buffer_stream, void(frontend::BufferStreamId));
2667 MOCK_METHOD1(create_buffer_stream, frontend::BufferStreamId(graphics::BufferProperties const&));
2668- void configure_streams(Surface&, std::vector<shell::StreamSpecification> const&) override {};
2669+ void configure_streams(Surface&, std::vector<shell::StreamSpecification> const&) override;;
2670
2671 private:
2672 std::string m_sessionName;
2673
2674=== added file 'tests/framework/mock_proc_info.cpp'
2675--- tests/framework/mock_proc_info.cpp 1970-01-01 00:00:00 +0000
2676+++ tests/framework/mock_proc_info.cpp 2015-12-04 18:37:28 +0000
2677@@ -0,0 +1,35 @@
2678+/*
2679+ * Copyright (C) 2015 Canonical, Ltd.
2680+ *
2681+ * This program is free software: you can redistribute it and/or modify it under
2682+ * the terms of the GNU Lesser General Public License version 3, as published by
2683+ * the Free Software Foundation.
2684+ *
2685+ * This program is distributed in the hope that it will be useful, but WITHOUT
2686+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
2687+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2688+ * Lesser General Public License for more details.
2689+ *
2690+ * You should have received a copy of the GNU Lesser General Public License
2691+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2692+ */
2693+
2694+#include "mock_proc_info.h"
2695+
2696+namespace qtmir
2697+{
2698+
2699+MockProcInfo::MockProcInfo()
2700+{
2701+}
2702+
2703+MockProcInfo::~MockProcInfo()
2704+{
2705+}
2706+
2707+std::unique_ptr<qtmir::ProcInfo::CommandLine> MockProcInfo::commandLine(pid_t pid)
2708+{
2709+ return std::unique_ptr<CommandLine>(new CommandLine{command_line(pid)});
2710+}
2711+
2712+} // namespace qtmir
2713
2714=== modified file 'tests/framework/mock_proc_info.h'
2715--- tests/modules/common/mock_proc_info.h 2015-10-08 11:20:30 +0000
2716+++ tests/framework/mock_proc_info.h 2015-12-04 18:37:28 +0000
2717@@ -21,16 +21,17 @@
2718
2719 #include <gmock/gmock.h>
2720
2721-namespace testing
2722-{
2723+namespace qtmir {
2724+
2725 struct MockProcInfo : public qtmir::ProcInfo
2726 {
2727+ MockProcInfo();
2728+ virtual ~MockProcInfo();
2729+
2730 MOCK_METHOD1(command_line, QByteArray(pid_t));
2731- std::unique_ptr<CommandLine> commandLine(pid_t pid)
2732- {
2733- return std::unique_ptr<CommandLine>(new CommandLine{command_line(pid)});
2734- }
2735+ std::unique_ptr<CommandLine> commandLine(pid_t pid);
2736 };
2737-}
2738+
2739+} // namespace qtmir
2740
2741 #endif // MOCK_PROC_INFO_H
2742
2743=== added file 'tests/framework/mock_prompt_session.cpp'
2744--- tests/framework/mock_prompt_session.cpp 1970-01-01 00:00:00 +0000
2745+++ tests/framework/mock_prompt_session.cpp 2015-12-04 18:37:28 +0000
2746@@ -0,0 +1,33 @@
2747+/*
2748+ * Copyright (C) 2015 Canonical, Ltd.
2749+ *
2750+ * This program is free software: you can redistribute it and/or modify it under
2751+ * the terms of the GNU Lesser General Public License version 3, as published by
2752+ * the Free Software Foundation.
2753+ *
2754+ * This program is distributed in the hope that it will be useful, but WITHOUT
2755+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
2756+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2757+ * Lesser General Public License for more details.
2758+ *
2759+ * You should have received a copy of the GNU Lesser General Public License
2760+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2761+ */
2762+
2763+#include "mock_prompt_session.h"
2764+
2765+namespace mir
2766+{
2767+namespace scene
2768+{
2769+
2770+MockPromptSession::MockPromptSession()
2771+{
2772+}
2773+
2774+MockPromptSession::~MockPromptSession()
2775+{
2776+}
2777+
2778+} // namespace scene
2779+} // namespace mir
2780
2781=== modified file 'tests/framework/mock_prompt_session.h'
2782--- tests/modules/common/mock_prompt_session.h 2015-08-11 12:08:32 +0000
2783+++ tests/framework/mock_prompt_session.h 2015-12-04 18:37:28 +0000
2784@@ -26,6 +26,9 @@
2785 struct MockPromptSession : public PromptSession
2786 {
2787 public:
2788+ MockPromptSession();
2789+ virtual ~MockPromptSession();
2790+
2791 MOCK_METHOD1(start, void(std::shared_ptr<Session> const&));
2792 MOCK_METHOD1(stop, void(std::shared_ptr<Session> const&));
2793 MOCK_METHOD1(suspend, void(std::shared_ptr<Session> const&));
2794
2795=== added file 'tests/framework/mock_prompt_session_manager.cpp'
2796--- tests/framework/mock_prompt_session_manager.cpp 1970-01-01 00:00:00 +0000
2797+++ tests/framework/mock_prompt_session_manager.cpp 2015-12-04 18:37:28 +0000
2798@@ -0,0 +1,33 @@
2799+/*
2800+ * Copyright (C) 2015 Canonical, Ltd.
2801+ *
2802+ * This program is free software: you can redistribute it and/or modify it under
2803+ * the terms of the GNU Lesser General Public License version 3, as published by
2804+ * the Free Software Foundation.
2805+ *
2806+ * This program is distributed in the hope that it will be useful, but WITHOUT
2807+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
2808+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2809+ * Lesser General Public License for more details.
2810+ *
2811+ * You should have received a copy of the GNU Lesser General Public License
2812+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2813+ */
2814+
2815+#include "mock_prompt_session_manager.h"
2816+
2817+namespace mir
2818+{
2819+namespace scene
2820+{
2821+
2822+MockPromptSessionManager::MockPromptSessionManager()
2823+{
2824+}
2825+
2826+MockPromptSessionManager::~MockPromptSessionManager()
2827+{
2828+}
2829+
2830+} // namespace scene
2831+} // namespace mir
2832
2833=== modified file 'tests/framework/mock_prompt_session_manager.h'
2834--- tests/modules/common/mock_prompt_session_manager.h 2015-08-11 12:08:32 +0000
2835+++ tests/framework/mock_prompt_session_manager.h 2015-12-04 18:37:28 +0000
2836@@ -28,6 +28,9 @@
2837 class MockPromptSessionManager: public PromptSessionManager
2838 {
2839 public:
2840+ MockPromptSessionManager();
2841+ virtual ~MockPromptSessionManager();
2842+
2843 MOCK_CONST_METHOD2(start_prompt_session_for, std::shared_ptr<PromptSession>(std::shared_ptr<mir::scene::Session> const&,
2844 mir::scene::PromptSessionCreationParameters const&));
2845
2846
2847=== added file 'tests/framework/mock_renderable.cpp'
2848--- tests/framework/mock_renderable.cpp 1970-01-01 00:00:00 +0000
2849+++ tests/framework/mock_renderable.cpp 2015-12-04 18:37:28 +0000
2850@@ -0,0 +1,33 @@
2851+/*
2852+ * Copyright (C) 2015 Canonical, Ltd.
2853+ *
2854+ * This program is free software: you can redistribute it and/or modify it under
2855+ * the terms of the GNU Lesser General Public License version 3, as published by
2856+ * the Free Software Foundation.
2857+ *
2858+ * This program is distributed in the hope that it will be useful, but WITHOUT
2859+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
2860+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2861+ * Lesser General Public License for more details.
2862+ *
2863+ * You should have received a copy of the GNU Lesser General Public License
2864+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2865+ */
2866+
2867+#include "mock_renderable.h"
2868+
2869+namespace mir
2870+{
2871+namespace graphics
2872+{
2873+
2874+MockRenderable::MockRenderable()
2875+{
2876+}
2877+
2878+MockRenderable::~MockRenderable()
2879+{
2880+}
2881+
2882+} // namespace graphics
2883+} // namespace mir
2884
2885=== modified file 'tests/framework/mock_renderable.h'
2886--- tests/modules/common/mock_renderable.h 2015-08-11 12:08:32 +0000
2887+++ tests/framework/mock_renderable.h 2015-12-04 18:37:28 +0000
2888@@ -25,7 +25,8 @@
2889
2890 struct MockRenderable : public Renderable
2891 {
2892- MockRenderable() {};
2893+ MockRenderable();
2894+ virtual ~MockRenderable();
2895
2896 MOCK_CONST_METHOD0(id, ID());
2897 MOCK_CONST_METHOD0(buffer, std::shared_ptr<Buffer>());
2898
2899=== added file 'tests/framework/mock_session.cpp'
2900--- tests/framework/mock_session.cpp 1970-01-01 00:00:00 +0000
2901+++ tests/framework/mock_session.cpp 2015-12-04 18:37:28 +0000
2902@@ -0,0 +1,69 @@
2903+/*
2904+ * Copyright (C) 2015 Canonical, Ltd.
2905+ *
2906+ * This program is free software: you can redistribute it and/or modify it under
2907+ * the terms of the GNU Lesser General Public License version 3, as published by
2908+ * the Free Software Foundation.
2909+ *
2910+ * This program is distributed in the hope that it will be useful, but WITHOUT
2911+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
2912+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2913+ * Lesser General Public License for more details.
2914+ *
2915+ * You should have received a copy of the GNU Lesser General Public License
2916+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2917+ */
2918+
2919+#include "mock_session.h"
2920+
2921+namespace qtmir
2922+{
2923+
2924+MockSession::MockSession()
2925+ : SessionInterface(0)
2926+{
2927+ m_state = Starting;
2928+ ON_CALL(*this, suspend()).WillByDefault(::testing::Invoke(this, &MockSession::doSuspend));
2929+ ON_CALL(*this, resume()).WillByDefault(::testing::Invoke(this, &MockSession::doResume));
2930+ ON_CALL(*this, stop()).WillByDefault(::testing::Invoke(this, &MockSession::doStop));
2931+ ON_CALL(*this, state()).WillByDefault(::testing::Invoke(this, &MockSession::doState));
2932+}
2933+
2934+MockSession::~MockSession()
2935+{
2936+
2937+}
2938+
2939+SessionInterface::State MockSession::doState() const
2940+{
2941+ return m_state;
2942+}
2943+
2944+void MockSession::doStop()
2945+{
2946+ setState(Stopped);
2947+}
2948+
2949+void MockSession::doResume()
2950+{
2951+ if (m_state == Suspending || m_state == Suspended) {
2952+ setState(Running);
2953+ }
2954+}
2955+
2956+void MockSession::doSuspend()
2957+{
2958+ if (m_state == Running) {
2959+ setState(Suspending);
2960+ }
2961+}
2962+
2963+void MockSession::setState(SessionInterface::State state)
2964+{
2965+ if (m_state != state) {
2966+ m_state = state;
2967+ Q_EMIT stateChanged(m_state);
2968+ }
2969+}
2970+
2971+} // namespace qtmir
2972
2973=== modified file 'tests/framework/mock_session.h'
2974--- tests/modules/common/mock_session.h 2015-08-31 09:51:28 +0000
2975+++ tests/framework/mock_session.h 2015-12-04 18:37:28 +0000
2976@@ -24,13 +24,8 @@
2977
2978 class MockSession : public SessionInterface {
2979 public:
2980- MockSession() : SessionInterface(0) {
2981- m_state = Starting;
2982- ON_CALL(*this, suspend()).WillByDefault(::testing::Invoke(this, &MockSession::doSuspend));
2983- ON_CALL(*this, resume()).WillByDefault(::testing::Invoke(this, &MockSession::doResume));
2984- ON_CALL(*this, stop()).WillByDefault(::testing::Invoke(this, &MockSession::doStop));
2985- ON_CALL(*this, state()).WillByDefault(::testing::Invoke(this, &MockSession::doState));
2986- }
2987+ MockSession();
2988+ virtual ~MockSession();
2989
2990 MOCK_METHOD0(release, void());
2991
2992@@ -49,6 +44,7 @@
2993
2994 MOCK_METHOD0(suspend, void());
2995 MOCK_METHOD0(resume, void());
2996+ MOCK_METHOD0(close, void());
2997 MOCK_METHOD0(stop, void());
2998
2999 MOCK_METHOD1(addChildSession, void(SessionInterface* session));
3000@@ -63,29 +59,12 @@
3001
3002 MOCK_CONST_METHOD0(childSessions, SessionModel*());
3003
3004- void setState(State state) {
3005- if (m_state != state) {
3006- m_state = state;
3007- Q_EMIT stateChanged(m_state);
3008- }
3009- }
3010+ void setState(State state);
3011
3012- void doSuspend() {
3013- if (m_state == Running) {
3014- setState(Suspending);
3015- }
3016- }
3017- void doResume() {
3018- if (m_state == Suspending || m_state == Suspended) {
3019- setState(Running);
3020- }
3021- }
3022- void doStop() {
3023- setState(Stopped);
3024- }
3025- State doState() const {
3026- return m_state;
3027- }
3028+ void doSuspend();
3029+ void doResume();
3030+ void doStop();
3031+ State doState() const;
3032
3033 protected:
3034 MOCK_METHOD1(setFullscreen, void(bool fullscreen));
3035@@ -94,7 +73,6 @@
3036 MOCK_METHOD1(removePromptSession, void(const std::shared_ptr<mir::scene::PromptSession>& session));
3037
3038 private:
3039-
3040 State m_state;
3041 };
3042
3043
3044=== added file 'tests/framework/mock_settings.cpp'
3045--- tests/framework/mock_settings.cpp 1970-01-01 00:00:00 +0000
3046+++ tests/framework/mock_settings.cpp 2015-12-04 18:37:28 +0000
3047@@ -0,0 +1,40 @@
3048+/*
3049+ * Copyright (C) 2015 Canonical, Ltd.
3050+ *
3051+ * This program is free software: you can redistribute it and/or modify it under
3052+ * the terms of the GNU Lesser General Public License version 3, as published by
3053+ * the Free Software Foundation.
3054+ *
3055+ * This program is distributed in the hope that it will be useful, but WITHOUT
3056+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
3057+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3058+ * Lesser General Public License for more details.
3059+ *
3060+ * You should have received a copy of the GNU Lesser General Public License
3061+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3062+ */
3063+
3064+#include "mock_settings.h"
3065+
3066+namespace qtmir
3067+{
3068+
3069+MockSettings::MockSettings()
3070+{
3071+ using namespace ::testing;
3072+
3073+ QVariantList lifecycleExemptAppIds;
3074+ lifecycleExemptAppIds << "com.ubuntu.music";
3075+ ON_CALL(*this, get(_))
3076+ .WillByDefault(
3077+ Return(lifecycleExemptAppIds));
3078+
3079+}
3080+
3081+MockSettings::~MockSettings()
3082+{
3083+
3084+}
3085+
3086+} // namespace qtmir
3087+
3088
3089=== modified file 'tests/framework/mock_settings.h'
3090--- tests/modules/common/mock_settings.h 2015-03-24 23:38:33 +0000
3091+++ tests/framework/mock_settings.h 2015-12-04 18:37:28 +0000
3092@@ -18,24 +18,20 @@
3093 #define MOCK_SETTINGS_H
3094
3095 #include <Unity/Application/settings_interface.h>
3096-
3097+#include <QVariant>
3098+
3099 #include <gmock/gmock.h>
3100
3101-namespace testing
3102+namespace qtmir
3103 {
3104 struct MockSettings : public qtmir::SettingsInterface
3105 {
3106- MockSettings()
3107- {
3108- QVariantList lifecycleExemptAppIds;
3109- lifecycleExemptAppIds << "com.ubuntu.music";
3110- ON_CALL(*this, get(_))
3111- .WillByDefault(
3112- Return(lifecycleExemptAppIds));
3113+ MockSettings();
3114+ virtual ~MockSettings();
3115
3116- }
3117 MOCK_CONST_METHOD1(get, QVariant(const QString &));
3118 };
3119
3120-} // namespace testing
3121+} // namespace qtmir
3122+
3123 #endif // MOCK_SETTINGS_H
3124
3125=== added file 'tests/framework/mock_shared_wakelock.cpp'
3126--- tests/framework/mock_shared_wakelock.cpp 1970-01-01 00:00:00 +0000
3127+++ tests/framework/mock_shared_wakelock.cpp 2015-12-04 18:37:28 +0000
3128@@ -0,0 +1,61 @@
3129+/*
3130+ * Copyright (C) 2015 Canonical, Ltd.
3131+ *
3132+ * This program is free software: you can redistribute it and/or modify it under
3133+ * the terms of the GNU Lesser General Public License version 3, as published by
3134+ * the Free Software Foundation.
3135+ *
3136+ * This program is distributed in the hope that it will be useful, but WITHOUT
3137+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
3138+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3139+ * Lesser General Public License for more details.
3140+ *
3141+ * You should have received a copy of the GNU Lesser General Public License
3142+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3143+ */
3144+
3145+#include "mock_shared_wakelock.h"
3146+
3147+namespace qtmir
3148+{
3149+
3150+MockSharedWakelock::MockSharedWakelock(const QDBusConnection &)
3151+{
3152+ using namespace ::testing;
3153+
3154+ ON_CALL(*this, enabled()).WillByDefault(Invoke(this, &MockSharedWakelock::doEnabled));
3155+ ON_CALL(*this, acquire(_)).WillByDefault(Invoke(this, &MockSharedWakelock::doAcquire));
3156+ ON_CALL(*this, release(_)).WillByDefault(Invoke(this, &MockSharedWakelock::doRelease));
3157+}
3158+
3159+MockSharedWakelock::~MockSharedWakelock()
3160+{
3161+}
3162+
3163+void MockSharedWakelock::doRelease(const QObject *object)
3164+{
3165+ if (!m_owners.remove(object)) {
3166+ return;
3167+ }
3168+ if (m_owners.isEmpty()) {
3169+ Q_EMIT enabledChanged(false);
3170+ }
3171+}
3172+
3173+void MockSharedWakelock::doAcquire(const QObject *object)
3174+{
3175+ if (m_owners.contains(object)) {
3176+ return;
3177+ }
3178+ m_owners.insert(object);
3179+ if (m_owners.size() == 1) {
3180+ Q_EMIT enabledChanged(true);
3181+ }
3182+}
3183+
3184+bool MockSharedWakelock::doEnabled()
3185+{
3186+ return !m_owners.isEmpty();
3187+}
3188+
3189+} // namespace qtmir
3190
3191=== modified file 'tests/framework/mock_shared_wakelock.h'
3192--- tests/modules/common/mock_shared_wakelock.h 2015-03-05 09:36:02 +0000
3193+++ tests/framework/mock_shared_wakelock.h 2015-12-04 18:37:28 +0000
3194@@ -21,51 +21,26 @@
3195
3196 #include <gmock/gmock.h>
3197
3198-namespace testing
3199+namespace qtmir
3200 {
3201 class MockSharedWakelock : public qtmir::SharedWakelock
3202 {
3203 public:
3204- MockSharedWakelock(const QDBusConnection& /*connection*/= QDBusConnection::systemBus())
3205- {
3206- ON_CALL(*this, enabled()).WillByDefault(Invoke(this, &MockSharedWakelock::doEnabled));
3207- ON_CALL(*this, acquire(_)).WillByDefault(Invoke(this, &MockSharedWakelock::doAcquire));
3208- ON_CALL(*this, release(_)).WillByDefault(Invoke(this, &MockSharedWakelock::doRelease));
3209- }
3210+ MockSharedWakelock(const QDBusConnection& /*connection*/= QDBusConnection::systemBus());
3211+ virtual ~MockSharedWakelock();
3212
3213 MOCK_CONST_METHOD0(enabled, bool());
3214 MOCK_METHOD1(acquire, void(const QObject *));
3215 MOCK_METHOD1(release, void(const QObject *));
3216
3217- bool doEnabled()
3218- {
3219- return !m_owners.isEmpty();
3220- }
3221-
3222- void doAcquire(const QObject *object)
3223- {
3224- if (m_owners.contains(object)) {
3225- return;
3226- }
3227- m_owners.insert(object);
3228- if (m_owners.size() == 1) {
3229- Q_EMIT enabledChanged(true);
3230- }
3231- }
3232-
3233- void doRelease(const QObject *object)
3234- {
3235- if (!m_owners.remove(object)) {
3236- return;
3237- }
3238- if (m_owners.isEmpty()) {
3239- Q_EMIT enabledChanged(false);
3240- }
3241- }
3242+ bool doEnabled();
3243+ void doAcquire(const QObject *object);
3244+ void doRelease(const QObject *object);
3245
3246 private:
3247 QSet<const QObject *> m_owners;
3248 };
3249
3250-} // namespace testing
3251+} // namespace qtmir
3252+
3253 #endif // MOCK_SHARED_WAKELOCK_H
3254
3255=== added file 'tests/framework/mock_surface.cpp'
3256--- tests/framework/mock_surface.cpp 1970-01-01 00:00:00 +0000
3257+++ tests/framework/mock_surface.cpp 2015-12-04 18:37:28 +0000
3258@@ -0,0 +1,39 @@
3259+/*
3260+ * Copyright (C) 2015 Canonical, Ltd.
3261+ *
3262+ * This program is free software: you can redistribute it and/or modify it under
3263+ * the terms of the GNU Lesser General Public License version 3, as published by
3264+ * the Free Software Foundation.
3265+ *
3266+ * This program is distributed in the hope that it will be useful, but WITHOUT
3267+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
3268+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3269+ * Lesser General Public License for more details.
3270+ *
3271+ * You should have received a copy of the GNU Lesser General Public License
3272+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3273+ */
3274+
3275+#include "mock_surface.h"
3276+
3277+namespace mir
3278+{
3279+namespace scene
3280+{
3281+
3282+MockSurface::MockSurface()
3283+{
3284+}
3285+
3286+MockSurface::~MockSurface()
3287+{
3288+}
3289+
3290+void MockSurface::rename(const std::string &) {}
3291+
3292+void MockSurface::set_keymap(const xkb_rule_names &) {}
3293+
3294+void MockSurface::consume(const MirEvent &event) { consume(&event); }
3295+
3296+} // namespace scene
3297+} // namespace mir
3298
3299=== modified file 'tests/framework/mock_surface.h'
3300--- tests/modules/common/mock_surface.h 2015-08-11 12:08:32 +0000
3301+++ tests/framework/mock_surface.h 2015-12-04 18:37:28 +0000
3302@@ -28,7 +28,8 @@
3303
3304 struct MockSurface : public mir::scene::Surface
3305 {
3306- MockSurface() {}
3307+ MockSurface();
3308+ virtual ~MockSurface();
3309
3310 MOCK_CONST_METHOD0(name, std::string());
3311 MOCK_CONST_METHOD0(client_size, geometry::Size());
3312@@ -62,15 +63,15 @@
3313 MOCK_METHOD1(set_reception_mode, void(input::InputReceptionMode mode));
3314 MOCK_METHOD0(request_client_surface_close, void());
3315 MOCK_CONST_METHOD1(buffers_ready_for_compositor, int(void const*));
3316- void set_keymap(xkb_rule_names const &) override {}
3317- void rename(std::string const&) override {}
3318+ void set_keymap(xkb_rule_names const &) override;
3319+ void rename(std::string const&) override;
3320 MOCK_METHOD1(set_streams, void(std::list<StreamInfo> const&));
3321
3322 // from mir::input::surface
3323 MOCK_CONST_METHOD1(input_area_contains, bool(geometry::Point const& point));
3324 MOCK_CONST_METHOD0(reception_mode, input::InputReceptionMode());
3325 MOCK_METHOD1(consume, void(MirEvent const* event));
3326- void consume(MirEvent const& event) override { consume(&event); }
3327+ void consume(MirEvent const& event) override;
3328
3329 // from mir::frontend::surface
3330 MOCK_CONST_METHOD0(pixel_format, MirPixelFormat());
3331
3332=== modified file 'tests/framework/qtmir_test.cpp'
3333--- tests/modules/common/qtmir_test.cpp 2015-10-01 16:48:38 +0000
3334+++ tests/framework/qtmir_test.cpp 2015-12-04 18:37:28 +0000
3335@@ -18,7 +18,8 @@
3336
3337 namespace qtmir {
3338
3339-void PrintTo(const Application::InternalState& state, ::std::ostream* os) {
3340+void PrintTo(const Application::InternalState& state, ::std::ostream* os)
3341+{
3342 switch (state) {
3343 case Application::InternalState::Starting:
3344 *os << "Starting";
3345@@ -71,4 +72,100 @@
3346 }
3347 }
3348
3349+// Initialization of mir::Server needed for by tests
3350+class TestMirServerInit : public virtual mir::Server
3351+{
3352+public:
3353+ TestMirServerInit(std::shared_ptr<StubPromptSessionManager> const& promptSessionManager)
3354+ : mock_prompt_session_manager(promptSessionManager)
3355+ {
3356+ override_the_prompt_session_manager(
3357+ [this]{ return the_mock_prompt_session_manager(); });
3358+ }
3359+
3360+ std::shared_ptr<mir::scene::MockPromptSessionManager> the_mock_prompt_session_manager()
3361+ {
3362+ return mock_prompt_session_manager;
3363+ }
3364+
3365+private:
3366+ std::shared_ptr<StubPromptSessionManager> const mock_prompt_session_manager;
3367+};
3368+
3369+
3370+namespace { char const* argv[] = { nullptr }; }
3371+
3372+class FakeMirServer: private TestMirServerInit, public MirServer
3373+{
3374+public:
3375+ FakeMirServer(std::shared_ptr<StubPromptSessionManager> const& promptSessionManager)
3376+ : TestMirServerInit(promptSessionManager), MirServer(0, argv, QSharedPointer<ScreenController>())
3377+ {
3378+ }
3379+
3380+ using TestMirServerInit::the_mock_prompt_session_manager;
3381+};
3382+
3383 } // namespace qtmir
3384+
3385+namespace testing
3386+{
3387+
3388+QtMirTest::QtMirTest()
3389+ : promptSessionManager(std::make_shared<StubPromptSessionManager>())
3390+ , mirServer(QSharedPointer<MirServer>(new FakeMirServer(promptSessionManager)))
3391+ , taskController(QSharedPointer<TaskController>(
3392+ new TaskController(
3393+ nullptr,
3394+ QSharedPointer<ApplicationController>(&appController, [](ApplicationController*){}))))
3395+ , applicationManager(mirServer,
3396+ taskController,
3397+ QSharedPointer<MockSharedWakelock>(&sharedWakelock, [](MockSharedWakelock *){}),
3398+ QSharedPointer<DesktopFileReader::Factory>(&desktopFileReaderFactory,[](DesktopFileReader::Factory*){}),
3399+ QSharedPointer<ProcInfo>(&procInfo,[](ProcInfo *){}),
3400+ QSharedPointer<MockSettings>(&settings,[](MockSettings *){}))
3401+ , sessionManager(mirServer, &applicationManager)
3402+ , surfaceManager(mirServer, mirShell, &sessionManager)
3403+{
3404+}
3405+
3406+QtMirTest::~QtMirTest()
3407+{
3408+
3409+}
3410+
3411+Application *QtMirTest::startApplication(pid_t procId, const QString &appId)
3412+{
3413+ using namespace testing;
3414+
3415+ ON_CALL(appController,appIdHasProcessId(procId, appId)).WillByDefault(Return(true));
3416+
3417+ // Set up Mocks & signal watcher
3418+ auto mockDesktopFileReader = new NiceMock<MockDesktopFileReader>(appId, QFileInfo());
3419+ ON_CALL(*mockDesktopFileReader, loaded()).WillByDefault(Return(true));
3420+ ON_CALL(*mockDesktopFileReader, appId()).WillByDefault(Return(appId));
3421+
3422+ EXPECT_CALL(desktopFileReaderFactory, createInstance(appId, _))
3423+ .Times(1)
3424+ .WillOnce(Return(mockDesktopFileReader));
3425+
3426+ EXPECT_CALL(appController, startApplicationWithAppIdAndArgs(appId, _))
3427+ .Times(1)
3428+ .WillOnce(Return(true));
3429+
3430+ auto application = applicationManager.startApplication(appId, ApplicationManager::NoFlag);
3431+ applicationManager.onProcessStarting(appId);
3432+
3433+ bool authed = false;
3434+ applicationManager.authorizeSession(procId, authed);
3435+ EXPECT_EQ(authed, true);
3436+
3437+ auto appSession = std::make_shared<mir::scene::MockSession>(appId.toStdString(), procId);
3438+ sessionManager.onSessionStarting(appSession);
3439+
3440+ Mock::VerifyAndClearExpectations(&appController);
3441+ Mock::VerifyAndClearExpectations(&desktopFileReaderFactory);
3442+ return application;
3443+}
3444+
3445+} // namespace testing
3446
3447=== modified file 'tests/framework/qtmir_test.h'
3448--- tests/modules/common/qtmir_test.h 2015-11-19 12:56:02 +0000
3449+++ tests/framework/qtmir_test.h 2015-12-04 18:37:28 +0000
3450@@ -46,45 +46,12 @@
3451
3452 namespace qtmir {
3453
3454+typedef testing::NiceMock<mir::scene::MockPromptSessionManager> StubPromptSessionManager;
3455+
3456 // For better output in ASSERT_* and EXPECT_* error messages
3457 void PrintTo(const Application::InternalState& state, ::std::ostream* os);
3458 void PrintTo(const SessionInterface::State& state, ::std::ostream* os);
3459
3460-// Initialization of mir::Server needed for by tests
3461-class TestMirServerInit : public virtual mir::Server
3462-{
3463-public:
3464- TestMirServerInit()
3465- {
3466- override_the_prompt_session_manager(
3467- [this]{ return the_mock_prompt_session_manager(); });
3468- }
3469-
3470- std::shared_ptr<mir::scene::MockPromptSessionManager> the_mock_prompt_session_manager()
3471- {
3472- return mock_prompt_session_manager;
3473- }
3474-
3475-private:
3476- typedef testing::NiceMock<mir::scene::MockPromptSessionManager> StubPromptSessionManager;
3477- std::shared_ptr<StubPromptSessionManager> const mock_prompt_session_manager
3478- {std::make_shared<StubPromptSessionManager>()};
3479-};
3480-
3481-
3482-namespace { char const* argv[] = { nullptr }; }
3483-
3484-class FakeMirServer: private TestMirServerInit, public MirServer
3485-{
3486-public:
3487- FakeMirServer()
3488- : MirServer(0, argv, QSharedPointer<ScreenController>())
3489- {
3490- }
3491-
3492- using TestMirServerInit::the_mock_prompt_session_manager;
3493-};
3494-
3495 } // namespace qtmir
3496
3497 namespace testing {
3498@@ -92,77 +59,18 @@
3499 class QtMirTest : public ::testing::Test
3500 {
3501 public:
3502- QtMirTest()
3503- : mirServer{
3504- QSharedPointer<FakeMirServer> (new FakeMirServer)
3505- }
3506- , taskController{
3507- QSharedPointer<TaskController> (
3508- new TaskController(
3509- nullptr,
3510- QSharedPointer<ApplicationController>(
3511- &appController,
3512- [](ApplicationController*){})
3513- )
3514- )
3515- }
3516- , applicationManager{
3517- mirServer,
3518- taskController,
3519- QSharedPointer<MockSharedWakelock>(&sharedWakelock, [](MockSharedWakelock *){}),
3520- QSharedPointer<DesktopFileReader::Factory>(
3521- &desktopFileReaderFactory,
3522- [](DesktopFileReader::Factory*){}),
3523- QSharedPointer<ProcInfo>(&procInfo,[](ProcInfo *){}),
3524- QSharedPointer<MockSettings>(&settings,[](MockSettings *){})
3525- }
3526- , sessionManager{
3527- mirServer,
3528- &applicationManager,
3529- }
3530- , surfaceManager{
3531- mirServer,
3532- mirShell,
3533- &sessionManager
3534- }
3535- {
3536- }
3537-
3538- Application* startApplication(pid_t procId, QString const& appId)
3539- {
3540- using namespace testing;
3541-
3542- ON_CALL(appController,appIdHasProcessId(procId, appId)).WillByDefault(Return(true));
3543-
3544- // Set up Mocks & signal watcher
3545- auto mockDesktopFileReader = new NiceMock<MockDesktopFileReader>(appId, QFileInfo());
3546- ON_CALL(*mockDesktopFileReader, loaded()).WillByDefault(Return(true));
3547- ON_CALL(*mockDesktopFileReader, appId()).WillByDefault(Return(appId));
3548-
3549- ON_CALL(desktopFileReaderFactory, createInstance(appId, _)).WillByDefault(Return(mockDesktopFileReader));
3550-
3551- EXPECT_CALL(appController, startApplicationWithAppIdAndArgs(appId, _))
3552- .Times(1)
3553- .WillOnce(Return(true));
3554-
3555- auto application = applicationManager.startApplication(appId, ApplicationManager::NoFlag);
3556- applicationManager.onProcessStarting(appId);
3557-
3558- bool authed = false;
3559- applicationManager.authorizeSession(procId, authed);
3560- EXPECT_EQ(authed, true);
3561-
3562- auto appSession = std::make_shared<mir::scene::MockSession>(appId.toStdString(), procId);
3563- sessionManager.onSessionStarting(appSession);
3564- return application;
3565- }
3566-
3567- testing::NiceMock<testing::MockApplicationController> appController;
3568- testing::NiceMock<testing::MockProcInfo> procInfo;
3569- testing::NiceMock<testing::MockDesktopFileReaderFactory> desktopFileReaderFactory;
3570- testing::NiceMock<testing::MockSharedWakelock> sharedWakelock;
3571- testing::NiceMock<testing::MockSettings> settings;
3572- QSharedPointer<FakeMirServer> mirServer;
3573+ QtMirTest();
3574+ virtual ~QtMirTest();
3575+
3576+ Application* startApplication(pid_t procId, QString const& appId);
3577+
3578+ testing::NiceMock<MockApplicationController> appController;
3579+ testing::NiceMock<MockProcInfo> procInfo;
3580+ testing::NiceMock<MockDesktopFileReaderFactory> desktopFileReaderFactory;
3581+ testing::NiceMock<MockSharedWakelock> sharedWakelock;
3582+ testing::NiceMock<MockSettings> settings;
3583+ std::shared_ptr<StubPromptSessionManager> promptSessionManager;
3584+ QSharedPointer<MirServer> mirServer;
3585 MirShell *mirShell{nullptr};
3586 QSharedPointer<TaskController> taskController;
3587 ApplicationManager applicationManager;
3588
3589=== added file 'tests/framework/stub_input_channel.cpp'
3590--- tests/framework/stub_input_channel.cpp 1970-01-01 00:00:00 +0000
3591+++ tests/framework/stub_input_channel.cpp 2015-12-04 18:37:28 +0000
3592@@ -0,0 +1,52 @@
3593+/*
3594+ * Copyright (C) 2015 Canonical, Ltd.
3595+ *
3596+ * This program is free software: you can redistribute it and/or modify it under
3597+ * the terms of the GNU Lesser General Public License version 3, as published by
3598+ * the Free Software Foundation.
3599+ *
3600+ * This program is distributed in the hope that it will be useful, but WITHOUT
3601+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
3602+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3603+ * Lesser General Public License for more details.
3604+ *
3605+ * You should have received a copy of the GNU Lesser General Public License
3606+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3607+ */
3608+
3609+#include "stub_input_channel.h"
3610+
3611+namespace mir
3612+{
3613+namespace test
3614+{
3615+namespace doubles
3616+{
3617+
3618+StubInputChannel::StubInputChannel(int fd)
3619+ : input_fd(fd)
3620+{
3621+}
3622+
3623+StubInputChannel::StubInputChannel()
3624+ : StubInputChannel(0)
3625+{
3626+}
3627+
3628+StubInputChannel::~StubInputChannel()
3629+{
3630+}
3631+
3632+int StubInputChannel::client_fd() const
3633+{
3634+ return input_fd;
3635+}
3636+
3637+int StubInputChannel::server_fd() const
3638+{
3639+ return input_fd;
3640+}
3641+
3642+} // namespace doubles
3643+} // namespace test
3644+} // namespace mir
3645
3646=== modified file 'tests/framework/stub_input_channel.h'
3647--- tests/modules/common/stub_input_channel.h 2015-08-11 12:08:32 +0000
3648+++ tests/framework/stub_input_channel.h 2015-12-04 18:37:28 +0000
3649@@ -28,24 +28,14 @@
3650
3651 struct StubInputChannel : public input::InputChannel
3652 {
3653- StubInputChannel(int fd)
3654- : input_fd(fd)
3655- {
3656- }
3657-
3658- StubInputChannel()
3659- : StubInputChannel(0)
3660- {
3661- }
3662-
3663- int client_fd() const override
3664- {
3665- return input_fd;
3666- }
3667- int server_fd() const override
3668- {
3669- return input_fd;
3670- }
3671+ StubInputChannel(int fd);
3672+
3673+ StubInputChannel();
3674+
3675+ virtual ~StubInputChannel();
3676+
3677+ int client_fd() const override;
3678+ int server_fd() const override;
3679 int input_fd;
3680 };
3681
3682
3683=== added file 'tests/framework/stub_scene_surface.cpp'
3684--- tests/framework/stub_scene_surface.cpp 1970-01-01 00:00:00 +0000
3685+++ tests/framework/stub_scene_surface.cpp 2015-12-04 18:37:28 +0000
3686@@ -0,0 +1,103 @@
3687+/*
3688+ * Copyright (C) 2015 Canonical, Ltd.
3689+ *
3690+ * This program is free software: you can redistribute it and/or modify it under
3691+ * the terms of the GNU Lesser General Public License version 3, as published by
3692+ * the Free Software Foundation.
3693+ *
3694+ * This program is distributed in the hope that it will be useful, but WITHOUT
3695+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
3696+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3697+ * Lesser General Public License for more details.
3698+ *
3699+ * You should have received a copy of the GNU Lesser General Public License
3700+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3701+ */
3702+
3703+#include "stub_scene_surface.h"
3704+
3705+namespace mir
3706+{
3707+namespace test
3708+{
3709+namespace doubles
3710+{
3711+
3712+StubSceneSurface::StubSceneSurface(int fd)
3713+ : channel(std::make_shared<StubInputChannel>(fd)), fd(fd)
3714+{
3715+}
3716+
3717+StubSceneSurface::~StubSceneSurface()
3718+{
3719+}
3720+
3721+std::shared_ptr<mir::input::InputChannel> StubSceneSurface::input_channel() const
3722+{
3723+ return channel;
3724+}
3725+
3726+mir::input::InputReceptionMode StubSceneSurface::reception_mode() const
3727+{
3728+ return input_mode;
3729+}
3730+
3731+std::string StubSceneSurface::name() const { return {}; }
3732+
3733+mir::geometry::Point StubSceneSurface::top_left() const { return {}; }
3734+
3735+mir::geometry::Size StubSceneSurface::client_size() const { return {};}
3736+
3737+mir::geometry::Size StubSceneSurface::size() const { return {}; }
3738+
3739+mir::geometry::Rectangle StubSceneSurface::input_bounds() const { return {{},{}}; }
3740+
3741+bool StubSceneSurface::input_area_contains(mir::geometry::Point const&) const { return false; }
3742+
3743+mir::graphics::RenderableList StubSceneSurface::generate_renderables(mir::compositor::CompositorID) const { return {};}
3744+
3745+float StubSceneSurface::alpha() const { return 0.0f; }
3746+
3747+MirSurfaceType StubSceneSurface::type() const { return mir_surface_type_normal; }
3748+
3749+MirSurfaceState StubSceneSurface::state() const { return mir_surface_state_unknown; }
3750+
3751+void StubSceneSurface::hide() {}
3752+
3753+void StubSceneSurface::show() {}
3754+
3755+void StubSceneSurface::move_to(const mir::geometry::Point &) {}
3756+
3757+void StubSceneSurface::set_input_region(const std::vector<mir::geometry::Rectangle> &) {}
3758+
3759+void StubSceneSurface::resize(const mir::geometry::Size &) {}
3760+
3761+void StubSceneSurface::set_transformation(const glm::mat4 &) {}
3762+
3763+void StubSceneSurface::set_alpha(float) {}
3764+
3765+void StubSceneSurface::set_orientation(MirOrientation) {}
3766+
3767+void StubSceneSurface::add_observer(const std::shared_ptr<mir::scene::SurfaceObserver> &) {}
3768+
3769+void StubSceneSurface::remove_observer(const std::weak_ptr<mir::scene::SurfaceObserver> &) {}
3770+
3771+void StubSceneSurface::set_reception_mode(mir::input::InputReceptionMode mode) { input_mode = mode; }
3772+
3773+void StubSceneSurface::consume(const MirEvent &) {}
3774+
3775+void StubSceneSurface::set_cursor_image(const std::shared_ptr<mir::graphics::CursorImage> &) {}
3776+
3777+std::shared_ptr<mir::graphics::CursorImage> StubSceneSurface::cursor_image() const { return {}; }
3778+
3779+bool StubSceneSurface::supports_input() const { return true; }
3780+
3781+int StubSceneSurface::client_input_fd() const { return fd;}
3782+
3783+int StubSceneSurface::configure(MirSurfaceAttrib, int) { return 0; }
3784+
3785+int StubSceneSurface::query(MirSurfaceAttrib) const { return 0; }
3786+
3787+} // namespace doubles
3788+} // namespace test
3789+} // namespace mir
3790
3791=== modified file 'tests/framework/stub_scene_surface.h'
3792--- tests/modules/common/stub_scene_surface.h 2015-09-30 09:27:52 +0000
3793+++ tests/framework/stub_scene_surface.h 2015-12-04 18:37:28 +0000
3794@@ -38,55 +38,47 @@
3795 int fd;
3796 mir::input::InputReceptionMode input_mode{mir::input::InputReceptionMode::normal};
3797
3798- StubSceneSurface(int fd)
3799- : channel(std::make_shared<StubInputChannel>(fd)), fd(fd)
3800- {
3801- }
3802-
3803- std::shared_ptr<mir::input::InputChannel> input_channel() const override
3804- {
3805- return channel;
3806- }
3807-
3808- mir::input::InputReceptionMode reception_mode() const override
3809- {
3810- return input_mode;
3811- }
3812-
3813- std::string name() const override { return {}; }
3814- geometry::Point top_left() const override { return {}; }
3815- geometry::Size client_size() const override { return {};}
3816- geometry::Size size() const override { return {}; }
3817- geometry::Rectangle input_bounds() const override { return {{},{}}; }
3818- bool input_area_contains(mir::geometry::Point const&) const override { return false; }
3819-
3820- graphics::RenderableList generate_renderables(compositor::CompositorID) const override { return {};}
3821- float alpha() const override { return 0.0f;}
3822- MirSurfaceType type() const override { return mir_surface_type_normal; }
3823- MirSurfaceState state() const override { return mir_surface_state_unknown; }
3824-
3825- void hide() override {}
3826- void show() override {}
3827- void move_to(geometry::Point const&) override {}
3828- void set_input_region(std::vector<geometry::Rectangle> const&) override {}
3829- void resize(geometry::Size const&) override {}
3830- void set_transformation(glm::mat4 const&) override {}
3831- void set_alpha(float) override {}
3832- void set_orientation(MirOrientation) override {}
3833-
3834- void add_observer(std::shared_ptr<scene::SurfaceObserver> const&) override {}
3835- void remove_observer(std::weak_ptr<scene::SurfaceObserver> const&) override {}
3836-
3837- void set_reception_mode(input::InputReceptionMode mode) override { input_mode = mode; }
3838- void consume(MirEvent const&) override {}
3839-
3840- void set_cursor_image(std::shared_ptr<graphics::CursorImage> const& /* image */) override {}
3841- std::shared_ptr<graphics::CursorImage> cursor_image() const override { return {}; }
3842-
3843- bool supports_input() const override { return true;}
3844- int client_input_fd() const override { return fd;}
3845- int configure(MirSurfaceAttrib, int) override { return 0; }
3846- int query(MirSurfaceAttrib) const override { return 0; }
3847+ StubSceneSurface(int fd);
3848+ virtual ~StubSceneSurface();
3849+
3850+ std::shared_ptr<mir::input::InputChannel> input_channel() const override;
3851+
3852+ mir::input::InputReceptionMode reception_mode() const override;
3853+
3854+ std::string name() const override;
3855+ geometry::Point top_left() const override;
3856+ geometry::Size client_size() const override;
3857+ geometry::Size size() const override;
3858+ geometry::Rectangle input_bounds() const override;
3859+ bool input_area_contains(mir::geometry::Point const&) const override;
3860+
3861+ graphics::RenderableList generate_renderables(compositor::CompositorID) const override;
3862+ float alpha() const override;
3863+ MirSurfaceType type() const override;
3864+ MirSurfaceState state() const override;
3865+
3866+ void hide() override;
3867+ void show() override;
3868+ void move_to(geometry::Point const&) override;
3869+ void set_input_region(std::vector<geometry::Rectangle> const&) override;
3870+ void resize(geometry::Size const&) override;
3871+ void set_transformation(glm::mat4 const&) override;
3872+ void set_alpha(float) override;
3873+ void set_orientation(MirOrientation) override;
3874+
3875+ void add_observer(std::shared_ptr<scene::SurfaceObserver> const&) override;
3876+ void remove_observer(std::weak_ptr<scene::SurfaceObserver> const&) override;
3877+
3878+ void set_reception_mode(input::InputReceptionMode mode) override;
3879+ void consume(MirEvent const&) override;
3880+
3881+ void set_cursor_image(std::shared_ptr<graphics::CursorImage> const& /* image */) override;
3882+ std::shared_ptr<graphics::CursorImage> cursor_image() const override;
3883+
3884+ bool supports_input() const override;
3885+ int client_input_fd() const override;
3886+ int configure(MirSurfaceAttrib, int) override;
3887+ int query(MirSurfaceAttrib) const override;
3888 };
3889
3890 }
3891
3892=== modified file 'tests/mirserver/Screen/CMakeLists.txt'
3893--- tests/mirserver/Screen/CMakeLists.txt 2015-08-20 10:16:54 +0000
3894+++ tests/mirserver/Screen/CMakeLists.txt 2015-12-04 18:37:28 +0000
3895@@ -5,7 +5,7 @@
3896 )
3897
3898 include_directories(
3899- ${CMAKE_SOURCE_DIR}/tests/common
3900+ ${CMAKE_SOURCE_DIR}/tests/framework
3901 ${CMAKE_SOURCE_DIR}/src/platforms/mirserver
3902 ${CMAKE_SOURCE_DIR}/src/common
3903 ${Qt5Gui_PRIVATE_INCLUDE_DIRS}
3904
3905=== modified file 'tests/mirserver/ScreenController/CMakeLists.txt'
3906--- tests/mirserver/ScreenController/CMakeLists.txt 2015-10-14 22:59:04 +0000
3907+++ tests/mirserver/ScreenController/CMakeLists.txt 2015-12-04 18:37:28 +0000
3908@@ -8,7 +8,7 @@
3909 )
3910
3911 include_directories(
3912- ${CMAKE_SOURCE_DIR}/tests/common
3913+ ${CMAKE_SOURCE_DIR}/tests/framework
3914 ${CMAKE_SOURCE_DIR}/src/platforms/mirserver
3915 ${CMAKE_SOURCE_DIR}/src/common
3916 ${Qt5Gui_PRIVATE_INCLUDE_DIRS}
3917@@ -22,6 +22,9 @@
3918 ScreenControllerTest
3919 qpa-mirserver
3920
3921+ -L${CMAKE_BINARY_DIR}/tests/framework
3922+ qtmir-test-framework-static
3923+
3924 ${GTEST_BOTH_LIBRARIES}
3925 ${GMOCK_LIBRARIES}
3926 )
3927
3928=== modified file 'tests/modules/Application/CMakeLists.txt'
3929--- tests/modules/Application/CMakeLists.txt 2015-08-19 20:17:56 +0000
3930+++ tests/modules/Application/CMakeLists.txt 2015-12-04 18:37:28 +0000
3931@@ -1,27 +1,33 @@
3932 set(
3933 APPLICATION_TEST_SOURCES
3934 application_test.cpp
3935- ${CMAKE_SOURCE_DIR}/tests/modules/common/fake_session.h
3936- ${CMAKE_SOURCE_DIR}/tests/modules/common/qtmir_test.cpp
3937 )
3938
3939 include_directories(
3940- ${APPLICATION_API_INCLUDE_DIRS}
3941 ${CMAKE_SOURCE_DIR}/src/platforms/mirserver
3942 ${CMAKE_SOURCE_DIR}/src/modules
3943- ${CMAKE_SOURCE_DIR}/tests/modules/common
3944+ ${CMAKE_SOURCE_DIR}/tests/framework
3945 ${MIRSERVER_INCLUDE_DIRS}
3946+
3947+ ${Qt5Core_INCLUDE_DIRS}
3948+ ${Qt5GUI_INCLUDE_DIRS}
3949+ ${Qt5Quick_INCLUDE_DIRS}
3950+ ${Qt5DBus_INCLUDE_DIRS}
3951 )
3952
3953 add_executable(application_test ${APPLICATION_TEST_SOURCES})
3954
3955+add_dependencies(application_test qtmir-test-framework-static)
3956+
3957 target_link_libraries(
3958 application_test
3959
3960+ Qt5::Test
3961+
3962 unityapplicationplugin
3963- qpa-mirserver
3964
3965- Qt5::Test
3966+ -L${CMAKE_BINARY_DIR}/tests/framework
3967+ qtmir-test-framework-static
3968
3969 ${GTEST_BOTH_LIBRARIES}
3970 ${GMOCK_LIBRARIES}
3971
3972=== modified file 'tests/modules/ApplicationManager/CMakeLists.txt'
3973--- tests/modules/ApplicationManager/CMakeLists.txt 2015-08-31 09:51:28 +0000
3974+++ tests/modules/ApplicationManager/CMakeLists.txt 2015-12-04 18:37:28 +0000
3975@@ -2,27 +2,29 @@
3976 APPLICATION_MANAGER_TEST_SOURCES
3977 application_manager_test.cpp
3978 ${CMAKE_SOURCE_DIR}/src/common/debughelpers.cpp
3979- ${CMAKE_SOURCE_DIR}/tests/modules/common/qtmir_test.cpp
3980- ../common/fake_mirsurface.h
3981 )
3982
3983 include_directories(
3984 ${APPLICATION_API_INCLUDE_DIRS}
3985 ${CMAKE_SOURCE_DIR}/src/platforms/mirserver
3986 ${CMAKE_SOURCE_DIR}/src/modules
3987- ${CMAKE_SOURCE_DIR}/tests/modules/common
3988+ ${CMAKE_SOURCE_DIR}/tests/framework
3989 ${MIRSERVER_INCLUDE_DIRS}
3990 )
3991
3992 add_executable(applicationmanager_test ${APPLICATION_MANAGER_TEST_SOURCES})
3993
3994+add_dependencies(applicationmanager_test qtmir-test-framework-static)
3995+
3996 target_link_libraries(
3997 applicationmanager_test
3998
3999- qpa-mirserver
4000+ Qt5::Test
4001+
4002 unityapplicationplugin
4003
4004- Qt5::Test
4005+ -L${CMAKE_BINARY_DIR}/tests/framework
4006+ qtmir-test-framework-static
4007
4008 ${GTEST_BOTH_LIBRARIES}
4009 ${GMOCK_LIBRARIES}
4010
4011=== modified file 'tests/modules/ApplicationManager/application_manager_test.cpp'
4012--- tests/modules/ApplicationManager/application_manager_test.cpp 2015-11-17 14:16:22 +0000
4013+++ tests/modules/ApplicationManager/application_manager_test.cpp 2015-12-04 18:37:28 +0000
4014@@ -1870,3 +1870,158 @@
4015 EXPECT_EQ(0, applicationManager.count());
4016 EXPECT_TRUE(dir.exists());
4017 }
4018+
4019+/*
4020+ * Test that there is an attempt at polite exiting of the app by requesting closure of the surface.
4021+ */
4022+TEST_F(ApplicationManagerTests,requestSurfaceCloseOnStop)
4023+{
4024+ using namespace ::testing;
4025+
4026+ const QString appId("testAppId");
4027+ quint64 procId = 5551;
4028+ Application* app = startApplication(procId, appId);
4029+ std::shared_ptr<mir::scene::Session> session = app->session()->session();
4030+
4031+ FakeMirSurface *surface = new FakeMirSurface;
4032+ onSessionCreatedSurface(session.get(), surface);
4033+ surface->drawFirstFrame();
4034+
4035+ QSignalSpy spy(surface, SIGNAL(closeRequested()));
4036+
4037+ // Stop app
4038+ applicationManager.stopApplication(appId);
4039+
4040+ EXPECT_EQ(1, spy.count());
4041+}
4042+
4043+
4044+// * Test that if there is no surface available to the app when it is stopped, that it is forced to close.
4045+TEST_F(ApplicationManagerTests,forceAppDeleteWhenRemovedWithMissingSurface)
4046+{
4047+ using namespace ::testing;
4048+
4049+ int argc = 0;
4050+ char* argv[0];
4051+ QCoreApplication qtApp(argc, argv); // app for deleteLater event
4052+
4053+ const QString appId("testAppId");
4054+ quint64 procId = 5551;
4055+ Application* app = startApplication(procId, appId);
4056+
4057+ QSignalSpy spy(app, SIGNAL(destroyed(QObject*)));
4058+ QObject::connect(app, &QObject::destroyed, app, [&qtApp](){ qtApp.quit(); });
4059+
4060+ // Stop app
4061+ applicationManager.stopApplication(appId);
4062+ qtApp.exec();
4063+ EXPECT_EQ(1, spy.count());
4064+}
4065+
4066+/*
4067+ * Test that if an application is started while it is still attempting to close, it is queued to start again.
4068+ */
4069+TEST_F(ApplicationManagerTests,applicationStartQueuedOnStartStopStart)
4070+{
4071+ using namespace ::testing;
4072+
4073+ int argc = 0;
4074+ char* argv[0];
4075+ QCoreApplication qtApp(argc, argv); // app for deleteLater event
4076+
4077+ const QString appId("testAppId");
4078+ quint64 procId = 5551;
4079+ Application* app = startApplication(procId, appId);
4080+ std::shared_ptr<mir::scene::Session> session = app->session()->session();
4081+
4082+ FakeMirSurface *surface = new FakeMirSurface;
4083+ onSessionCreatedSurface(session.get(), surface);
4084+ surface->drawFirstFrame();
4085+
4086+ EXPECT_EQ(Application::InternalState::Running, app->internalState());
4087+
4088+ // Stop app
4089+ applicationManager.stopApplication(appId);
4090+
4091+ EXPECT_EQ(Application::InternalState::Closing, app->internalState());
4092+
4093+ // // Set up Mocks & signal watcher
4094+ auto mockDesktopFileReader = new NiceMock<MockDesktopFileReader>(appId, QFileInfo());
4095+ ON_CALL(*mockDesktopFileReader, loaded()).WillByDefault(Return(true));
4096+ ON_CALL(*mockDesktopFileReader, appId()).WillByDefault(Return(appId));
4097+ ON_CALL(desktopFileReaderFactory, createInstance(appId, _)).WillByDefault(Return(mockDesktopFileReader));
4098+
4099+ EXPECT_EQ(nullptr, applicationManager.startApplication(appId, ApplicationManager::NoFlag));
4100+
4101+ QSignalSpy spy(&applicationManager, SIGNAL(applicationAdded(const QString&)));
4102+ applicationManager.onProcessStopped(appId);
4103+
4104+ QObject::connect(&applicationManager, &ApplicationManager::applicationAdded,
4105+ &applicationManager, [&qtApp, appId](const QString& startedApp) {
4106+ if (startedApp == appId) {
4107+ qtApp.quit();
4108+ }
4109+ });
4110+
4111+ qtApp.exec();
4112+ EXPECT_EQ(1, spy.count());
4113+}
4114+
4115+/*
4116+ * Test that there is an attempt at polite exiting of the app by requesting closure of the surface.
4117+ */
4118+TEST_F(ApplicationManagerTests,suspendedApplicationResumesClosesAndDeletes)
4119+{
4120+ using namespace ::testing;
4121+
4122+ const QString appId("testAppId");
4123+ quint64 procId = 5551;
4124+ Application* app = startApplication(procId, appId);
4125+ std::shared_ptr<mir::scene::Session> session = app->session()->session();
4126+
4127+ FakeMirSurface *surface = new FakeMirSurface;
4128+ onSessionCreatedSurface(session.get(), surface);
4129+ surface->drawFirstFrame();
4130+ EXPECT_EQ(Application::InternalState::Running, app->internalState());
4131+ EXPECT_EQ(SessionInterface::Running, app->session()->state());
4132+
4133+ // Suspend the application.
4134+ suspend(app);
4135+ EXPECT_EQ(Application::InternalState::Suspended, app->internalState());
4136+
4137+ // Stop app
4138+ applicationManager.stopApplication(appId);
4139+ EXPECT_EQ(Application::InternalState::Closing, app->internalState());
4140+ EXPECT_EQ(SessionInterface::Running, app->session()->state());
4141+}
4142+
4143+/*
4144+ * Test that a application which fails to close will eventually be forceable closed.
4145+ */
4146+TEST_F(ApplicationManagerTests,failedApplicationCloseEventualyDeletesApplication)
4147+{
4148+ using namespace ::testing;
4149+
4150+ int argc = 0;
4151+ char* argv[0];
4152+ QCoreApplication qtApp(argc, argv); // app for deleteLater event
4153+
4154+ const QString appId("testAppId");
4155+ quint64 procId = 5551;
4156+ Application* app = startApplication(procId, appId);
4157+ std::shared_ptr<mir::scene::Session> session = app->session()->session();
4158+
4159+ FakeMirSurface *surface = new FakeMirSurface;
4160+ onSessionCreatedSurface(session.get(), surface);
4161+ surface->drawFirstFrame();
4162+
4163+ EXPECT_EQ(Application::InternalState::Running, app->internalState());
4164+
4165+ QSignalSpy spy(app, SIGNAL(destroyed(QObject*)));
4166+ QObject::connect(app, &QObject::destroyed, app, [&qtApp](){ qtApp.quit(); });
4167+
4168+ // Stop app
4169+ applicationManager.stopApplication(appId);
4170+ qtApp.exec();
4171+ EXPECT_EQ(1, spy.count());
4172+}
4173
4174=== modified file 'tests/modules/DesktopFileReader/CMakeLists.txt'
4175--- tests/modules/DesktopFileReader/CMakeLists.txt 2014-12-03 08:56:35 +0000
4176+++ tests/modules/DesktopFileReader/CMakeLists.txt 2015-12-04 18:37:28 +0000
4177@@ -7,8 +7,6 @@
4178
4179 include_directories(
4180 ${CMAKE_SOURCE_DIR}/src/modules
4181- ${CMAKE_SOURCE_DIR}/tests/modules/common
4182- ${MIRSERVER_INCLUDE_DIRS}
4183 )
4184
4185 add_executable(desktop_file_reader_test ${DESKTOP_FILE_READER_TEST_SOURCES})
4186@@ -16,13 +14,9 @@
4187 target_link_libraries(
4188 desktop_file_reader_test
4189
4190- qpa-mirserver
4191 unityapplicationplugin
4192
4193- Qt5::Gui
4194-
4195 ${GTEST_BOTH_LIBRARIES}
4196- ${GMOCK_LIBRARIES}
4197 )
4198
4199 add_test(DesktopFileReader desktop_file_reader_test)
4200
4201=== modified file 'tests/modules/SessionManager/CMakeLists.txt'
4202--- tests/modules/SessionManager/CMakeLists.txt 2015-08-31 09:51:28 +0000
4203+++ tests/modules/SessionManager/CMakeLists.txt 2015-12-04 18:37:28 +0000
4204@@ -3,28 +3,30 @@
4205 session_manager_test.cpp
4206 session_test.cpp
4207 ${CMAKE_SOURCE_DIR}/src/common/debughelpers.cpp
4208- ${CMAKE_SOURCE_DIR}/tests/modules/common/qtmir_test.cpp
4209- ${CMAKE_SOURCE_DIR}/tests/modules/common/fake_mirsurface.h
4210 )
4211
4212 include_directories(
4213 ${APPLICATION_API_INCLUDE_DIRS}
4214 ${CMAKE_SOURCE_DIR}/src/platforms/mirserver
4215 ${CMAKE_SOURCE_DIR}/src/modules
4216- ${CMAKE_SOURCE_DIR}/tests/modules/common
4217+ ${CMAKE_SOURCE_DIR}/tests/framework
4218 ${MIRSERVER_INCLUDE_DIRS}
4219 )
4220
4221 add_executable(sessionmanager_test ${SESSION_MANAGER_TEST_SOURCES})
4222
4223+add_dependencies(sessionmanager_test qtmir-test-framework-static)
4224+
4225 target_link_libraries(
4226 sessionmanager_test
4227
4228- qpa-mirserver
4229 unityapplicationplugin
4230
4231 Qt5::Test
4232
4233+ -L${CMAKE_BINARY_DIR}/tests/framework
4234+ qtmir-test-framework-static
4235+
4236 ${GTEST_BOTH_LIBRARIES}
4237 ${GMOCK_LIBRARIES}
4238 )
4239
4240=== modified file 'tests/modules/SessionManager/session_manager_test.cpp'
4241--- tests/modules/SessionManager/session_manager_test.cpp 2015-08-11 12:08:32 +0000
4242+++ tests/modules/SessionManager/session_manager_test.cpp 2015-12-04 18:37:28 +0000
4243@@ -60,7 +60,7 @@
4244 EXPECT_TRUE(qtmirAppSession != nullptr);
4245
4246 auto promptSession = std::make_shared<ms::MockPromptSession>();
4247- ON_CALL(*mirServer->the_mock_prompt_session_manager(), application_for(_)).WillByDefault(Return(mirAppSession));
4248+ ON_CALL(*promptSessionManager, application_for(_)).WillByDefault(Return(mirAppSession));
4249
4250 sessionManager.onPromptSessionStarting(promptSession);
4251
4252@@ -83,8 +83,8 @@
4253 SessionInterface* qtmirAppSession = sessionManager.findSession(mirAppSession.get());
4254 EXPECT_TRUE(qtmirAppSession != nullptr);
4255
4256- EXPECT_CALL(*mirServer->the_mock_prompt_session_manager(), application_for(_)).WillRepeatedly(Return(mirAppSession));
4257- EXPECT_CALL(*mirServer->the_mock_prompt_session_manager(), helper_for(_)).WillRepeatedly(Return(nullptr));
4258+ EXPECT_CALL(*promptSessionManager, application_for(_)).WillRepeatedly(Return(mirAppSession));
4259+ EXPECT_CALL(*promptSessionManager, helper_for(_)).WillRepeatedly(Return(nullptr));
4260
4261 std::shared_ptr<ms::PromptSession> mirPromptSession = std::make_shared<ms::MockPromptSession>();
4262
4263@@ -93,7 +93,7 @@
4264 sessionManager.onSessionStarting(mirProviderSession);
4265 SessionInterface* qtmirProviderSession = sessionManager.findSession(mirProviderSession.get());
4266
4267- EXPECT_CALL(*mirServer->the_mock_prompt_session_manager(), for_each_provider_in(mirPromptSession,_)).WillRepeatedly(WithArgs<1>(Invoke(
4268+ EXPECT_CALL(*promptSessionManager, for_each_provider_in(mirPromptSession,_)).WillRepeatedly(WithArgs<1>(Invoke(
4269 [&](std::function<void(std::shared_ptr<ms::Session> const& prompt_provider)> const& f) {
4270 f(mirProviderSession);
4271 })));
4272@@ -109,7 +109,7 @@
4273
4274 EXPECT_THAT(listChildSessions(qtmirAppSession), ElementsAre(qtmirProviderSession));
4275
4276- EXPECT_CALL(*mirServer->the_mock_prompt_session_manager(), for_each_provider_in(mirPromptSession,_)).WillRepeatedly(InvokeWithoutArgs([]{}));
4277+ EXPECT_CALL(*promptSessionManager, for_each_provider_in(mirPromptSession,_)).WillRepeatedly(InvokeWithoutArgs([]{}));
4278
4279 EXPECT_EQ(qtmirProviderSession->live(), true);
4280 sessionManager.onPromptProviderRemoved(mirPromptSession.get(), mirProviderSession);
4281
4282=== modified file 'tests/modules/SessionManager/session_test.cpp'
4283--- tests/modules/SessionManager/session_test.cpp 2015-10-08 11:20:30 +0000
4284+++ tests/modules/SessionManager/session_test.cpp 2015-12-04 18:37:28 +0000
4285@@ -236,7 +236,7 @@
4286 auto mirPromptSession = std::make_shared<ms::MockPromptSession>();
4287 session->appendPromptSession(mirPromptSession);
4288
4289- EXPECT_CALL(*mirServer->the_mock_prompt_session_manager(), suspend_prompt_session(_)).Times(1);
4290+ EXPECT_CALL(*promptSessionManager, suspend_prompt_session(_)).Times(1);
4291
4292 EXPECT_CALL(*mirSession, set_lifecycle_state(mir_lifecycle_state_will_suspend));
4293 session->suspend();
4294@@ -244,7 +244,7 @@
4295 session->doSuspend();
4296 EXPECT_EQ(Session::Suspended, session->state());
4297
4298- Mock::VerifyAndClear(mirServer->the_mock_prompt_session_manager().get());
4299+ Mock::VerifyAndClear(promptSessionManager.get());
4300 }
4301
4302 TEST_F(SessionTests, ResumePromptSessionWhenSessionResumes)
4303@@ -256,7 +256,7 @@
4304
4305 auto mirSession = std::make_shared<MockSession>(appId.toStdString(), procId);
4306
4307- auto session = std::make_shared<qtmir::Session>(mirSession, mirServer->the_prompt_session_manager());
4308+ auto session = std::make_shared<qtmir::Session>(mirSession, promptSessionManager);
4309 {
4310 FakeMirSurface *surface = new FakeMirSurface;
4311 session->setSurface(surface);
4312@@ -273,11 +273,11 @@
4313 auto mirPromptSession = std::make_shared<ms::MockPromptSession>();
4314 session->appendPromptSession(mirPromptSession);
4315
4316- EXPECT_CALL(*mirServer->the_mock_prompt_session_manager(), resume_prompt_session(_)).Times(1);
4317+ EXPECT_CALL(*promptSessionManager, resume_prompt_session(_)).Times(1);
4318
4319 EXPECT_CALL(*mirSession, set_lifecycle_state(mir_lifecycle_state_resumed));
4320 session->resume();
4321 EXPECT_EQ(Session::Running, session->state());
4322
4323- Mock::VerifyAndClear(mirServer->the_mock_prompt_session_manager().get());
4324+ Mock::VerifyAndClear(promptSessionManager.get());
4325 }
4326
4327=== modified file 'tests/modules/SharedWakelock/CMakeLists.txt'
4328--- tests/modules/SharedWakelock/CMakeLists.txt 2015-03-04 23:32:28 +0000
4329+++ tests/modules/SharedWakelock/CMakeLists.txt 2015-12-04 18:37:28 +0000
4330@@ -5,7 +5,6 @@
4331
4332 include_directories(
4333 ${CMAKE_SOURCE_DIR}/src/modules
4334- ${CMAKE_SOURCE_DIR}/tests/modules/common
4335 ${QTDBUSTEST_INCLUDE_DIRS}
4336 ${QTDBUSMOCK_INCLUDE_DIRS}
4337 )
4338
4339=== modified file 'tests/modules/SurfaceManager/CMakeLists.txt'
4340--- tests/modules/SurfaceManager/CMakeLists.txt 2015-11-17 14:47:38 +0000
4341+++ tests/modules/SurfaceManager/CMakeLists.txt 2015-12-04 18:37:28 +0000
4342@@ -3,14 +3,12 @@
4343 mirsurfaceitem_test.cpp
4344 mirsurface_test.cpp
4345 ${CMAKE_SOURCE_DIR}/src/common/debughelpers.cpp
4346- ${CMAKE_SOURCE_DIR}/tests/modules/common/fake_mirsurface.h
4347- ${CMAKE_SOURCE_DIR}/tests/modules/common/fake_session.h
4348 )
4349
4350 include_directories(
4351 ${CMAKE_SOURCE_DIR}/src/modules
4352 ${CMAKE_SOURCE_DIR}/src/platforms/mirserver
4353- ${CMAKE_SOURCE_DIR}/tests/modules/common
4354+ ${CMAKE_SOURCE_DIR}/tests/framework
4355 ${MIRSERVER_INCLUDE_DIRS}
4356 )
4357
4358@@ -19,11 +17,13 @@
4359 target_link_libraries(
4360 surfacemanager_test
4361
4362- qpa-mirserver
4363 unityapplicationplugin
4364
4365 Qt5::Test
4366
4367+ -L${CMAKE_BINARY_DIR}/tests/framework
4368+ qtmir-test-framework-static
4369+
4370 ${GTEST_BOTH_LIBRARIES}
4371 ${GMOCK_LIBRARIES}
4372 )
4373
4374=== modified file 'tests/modules/SurfaceManager/mirsurfaceitem_test.cpp'
4375--- tests/modules/SurfaceManager/mirsurfaceitem_test.cpp 2015-11-25 15:38:39 +0000
4376+++ tests/modules/SurfaceManager/mirsurfaceitem_test.cpp 2015-12-04 18:37:28 +0000
4377@@ -24,7 +24,7 @@
4378 // the test subject
4379 #include <Unity/Application/mirsurfaceitem.h>
4380
4381-// tests/modules/common
4382+// tests/framework
4383 #include <fake_mirsurface.h>
4384
4385 using namespace qtmir;
4386
4387=== modified file 'tests/modules/TaskController/CMakeLists.txt'
4388--- tests/modules/TaskController/CMakeLists.txt 2015-06-15 17:01:28 +0000
4389+++ tests/modules/TaskController/CMakeLists.txt 2015-12-04 18:37:28 +0000
4390@@ -7,18 +7,22 @@
4391 include_directories(
4392 ${APPLICATION_API_INCLUDE_DIRS}
4393 ${CMAKE_SOURCE_DIR}/src/modules
4394- ${CMAKE_SOURCE_DIR}/tests/modules/common
4395+ ${CMAKE_SOURCE_DIR}/tests/framework
4396 ${MIRSERVER_INCLUDE_DIRS}
4397 )
4398
4399 add_executable(taskcontroller_test ${TASK_CONTROLLER_TEST_SOURCES})
4400
4401+add_dependencies(taskcontroller_test qtmir-test-framework-static)
4402+
4403 target_link_libraries(
4404 taskcontroller_test
4405
4406- qpa-mirserver
4407 unityapplicationplugin
4408
4409+ -L${CMAKE_BINARY_DIR}/tests/framework
4410+ qtmir-test-framework-static
4411+
4412 ${GTEST_BOTH_LIBRARIES}
4413 ${GMOCK_LIBRARIES}
4414 )

Subscribers

People subscribed via source and target branches