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

Proposed by Daniel d'Andrada on 2016-01-04
Status: Merged
Approved by: Nick Dedekind on 2016-01-07
Approved revision: no longer in the source branch.
Merged at revision: 442
Proposed branch: lp:~dandrader/qtmir/removeUselessClass
Merge into: lp:qtmir
Prerequisite: lp:~nick-dedekind/qtmir/qtmir-test-build
Diff against target: 2344 lines (+673/-573)
24 files modified
src/modules/Unity/Application/CMakeLists.txt (+4/-3)
src/modules/Unity/Application/application.cpp (+17/-12)
src/modules/Unity/Application/application.h (+3/-4)
src/modules/Unity/Application/application_manager.cpp (+5/-9)
src/modules/Unity/Application/application_manager.h (+2/-2)
src/modules/Unity/Application/taskcontroller.cpp (+0/-119)
src/modules/Unity/Application/taskcontroller.h (+0/-63)
src/modules/Unity/Application/timer.cpp (+109/-0)
src/modules/Unity/Application/timer.h (+88/-0)
src/modules/Unity/Application/timesource.cpp (+48/-0)
src/modules/Unity/Application/timesource.h (+61/-0)
src/modules/Unity/Application/upstart/taskcontroller.cpp (+34/-34)
src/modules/Unity/Application/upstart/taskcontroller.h (+15/-15)
tests/framework/CMakeLists.txt (+1/-1)
tests/framework/fake_desktopfilereader.cpp (+9/-1)
tests/framework/fake_desktopfilereader.h (+1/-0)
tests/framework/mock_task_controller.cpp (+29/-29)
tests/framework/mock_task_controller.h (+20/-20)
tests/framework/qtmir_test.cpp (+5/-9)
tests/framework/qtmir_test.h (+5/-5)
tests/modules/ApplicationManager/application_manager_test.cpp (+217/-121)
tests/modules/CMakeLists.txt (+0/-1)
tests/modules/TaskController/CMakeLists.txt (+0/-30)
tests/modules/TaskController/taskcontroller_test.cpp (+0/-95)
To merge this branch: bzr merge lp:~dandrader/qtmir/removeUselessClass
Reviewer Review Type Date Requested Status
Michał Sawicz Abstain on 2016-02-11
Nick Dedekind (community) 2016-01-04 Approve on 2016-01-07
PS Jenkins bot continuous-integration Needs Fixing on 2016-01-05
Review via email: mp+281538@code.launchpad.net

Commit Message

Remove the useless TaskController

It was just forwarding calls between ApplicationManager and ApplicationCrontroller.
Had no logic of its own.

ApplicationCrontroller was then renamed to TaskController as the latter has a better API and it also keeps ApplicationManager code more or less untouched.

Tests have been improved a bit by better emulating TaskController behavior

Description of the Change

Also fixes a test failure you get in trunk if you build qtmir with -DCMAKE_BUILD_TYPE=Debug

"""
ASSERT: "!m_session || m_session->state() == Session::Stopped" in file /home/dandrader/qtmir/trunk/src/modules/Unity/Application/application.cpp, line 610
Aborted (core dumped)
"""

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

* 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?
N/A

To post a comment you must log in.
Nick Dedekind (nick-dedekind) wrote :

2 Comments attached.
There's a lot of code not related to removing the task controller. Perhaps this should be in a different MP.

review: Needs Fixing
Daniel d'Andrada (dandrader) wrote :

On 05/01/2016 12:37, Nick Dedekind wrote:
> Review: Needs Fixing
>
> 2 Comments attached.
> There's a lot of code not related to removing the task controller. Perhaps this should be in a different MP.

You mean the Timer stuff? The test updates had to be done. But yes, it's
a lot of code churn in the end.

> Diff comments:
>
>> +
>> +/////////////////////////////////// FakeTimerFactory //////////////////////////////////
> The Factories don't seem to be used anywhere.

Yes, removed them.

>
>>
>> === modified file 'tests/modules/ApplicationManager/application_manager_test.cpp'
>> --- tests/modules/ApplicationManager/application_manager_test.cpp 2015-12-07 12:23:29 +0000
>> +++ tests/modules/ApplicationManager/application_manager_test.cpp 2016-01-04 18:32:30 +0000
>> @@ -2125,11 +2189,20 @@
>>
>> EXPECT_EQ(Application::InternalState::Running, app->internalState());
>>
>> - QSignalSpy spy(app, SIGNAL(destroyed(QObject*)));
>> - QObject::connect(app, &QObject::destroyed, app, [&qtApp](){ qtApp.quit(); });
> you no longer test that the app is deleted. can you rename the test please?

Yes, checking that TaskController::stop() is being called amounted to
the same. Brought back the QObject::destroyed check and found out that
the test was missing a bit of code to properly exercise the code paths
that are executed on real usage.

Nick Dedekind (nick-dedekind) wrote :

Test project /home/nick/Work/reviews/qtmir/removeUselessClass/builddir
      Start 1: QtEventFeeder,
 1/12 Test #1: QtEventFeeder, ................... Passed 0.04 sec
      Start 2: Clipboard,
 2/12 Test #2: Clipboard, ....................... Passed 0.01 sec
      Start 3: Screen,
 3/12 Test #3: Screen, .......................... Passed 0.01 sec
      Start 4: ScreenController,
 4/12 Test #4: ScreenController, ................ Passed 0.04 sec
      Start 5: WindowManager,
 5/12 Test #5: WindowManager, ................... Passed 0.01 sec
      Start 6: Application,
 6/12 Test #6: Application, .....................***Failed 0.50 sec
      Start 7: ApplicationManager
 7/12 Test #7: ApplicationManager ...............***Failed 0.27 sec
      Start 8: DesktopFileReader
 8/12 Test #8: DesktopFileReader ................ Passed 0.02 sec
      Start 9: General
 9/12 Test #9: General .......................... Passed 0.00 sec
      Start 10: SharedWakelock,
10/12 Test #10: SharedWakelock, .................. Passed 16.71 sec
      Start 11: SessionManager,
11/12 Test #11: SessionManager, .................. Passed 0.51 sec
      Start 12: SurfaceManager
12/12 Test #12: SurfaceManager ................... Passed 0.35 sec

review: Needs Fixing
Daniel d'Andrada (dandrader) wrote :

On 06/01/2016 14:28, Nick Dedekind wrote:
> Review: Needs Fixing
>
> Test project /home/nick/Work/reviews/qtmir/removeUselessClass/builddir
> Start 1: QtEventFeeder,
> 1/12 Test #1: QtEventFeeder, ................... Passed 0.04 sec
> Start 2: Clipboard,
> 2/12 Test #2: Clipboard, ....................... Passed 0.01 sec
> Start 3: Screen,
> 3/12 Test #3: Screen, .......................... Passed 0.01 sec
> Start 4: ScreenController,
> 4/12 Test #4: ScreenController, ................ Passed 0.04 sec
> Start 5: WindowManager,
> 5/12 Test #5: WindowManager, ................... Passed 0.01 sec
> Start 6: Application,
> 6/12 Test #6: Application, .....................***Failed 0.50 sec
> Start 7: ApplicationManager
> 7/12 Test #7: ApplicationManager ...............***Failed 0.27 sec
> Start 8: DesktopFileReader
> 8/12 Test #8: DesktopFileReader ................ Passed 0.02 sec
> Start 9: General
> 9/12 Test #9: General .......................... Passed 0.00 sec
> Start 10: SharedWakelock,
> 10/12 Test #10: SharedWakelock, .................. Passed 16.71 sec
> Start 11: SessionManager,
> 11/12 Test #11: SessionManager, .................. Passed 0.51 sec
> Start 12: SurfaceManager
> 12/12 Test #12: SurfaceManager ................... Passed 0.35 sec
>

Weird, then all pass here.

Could you please provide details on the failures?

Nick Dedekind (nick-dedekind) wrote :

> On 06/01/2016 14:28, Nick Dedekind wrote:
> > Review: Needs Fixing
> >
> > Test project /home/nick/Work/reviews/qtmir/removeUselessClass/builddir
> > Start 1: QtEventFeeder,
> > 1/12 Test #1: QtEventFeeder, ................... Passed 0.04 sec
> > Start 2: Clipboard,
> > 2/12 Test #2: Clipboard, ....................... Passed 0.01 sec
> > Start 3: Screen,
> > 3/12 Test #3: Screen, .......................... Passed 0.01 sec
> > Start 4: ScreenController,
> > 4/12 Test #4: ScreenController, ................ Passed 0.04 sec
> > Start 5: WindowManager,
> > 5/12 Test #5: WindowManager, ................... Passed 0.01 sec
> > Start 6: Application,
> > 6/12 Test #6: Application, .....................***Failed 0.50 sec
> > Start 7: ApplicationManager
> > 7/12 Test #7: ApplicationManager ...............***Failed 0.27 sec
> > Start 8: DesktopFileReader
> > 8/12 Test #8: DesktopFileReader ................ Passed 0.02 sec
> > Start 9: General
> > 9/12 Test #9: General .......................... Passed 0.00 sec
> > Start 10: SharedWakelock,
> > 10/12 Test #10: SharedWakelock, .................. Passed 16.71 sec
> > Start 11: SessionManager,
> > 11/12 Test #11: SessionManager, .................. Passed 0.51 sec
> > Start 12: SurfaceManager
> > 12/12 Test #12: SurfaceManager ................... Passed 0.35 sec
> >
>
> Weird, then all pass here.
>
> Could you please provide details on the failures?

I think I had some cached mocs. Works fine.

Nick Dedekind (nick-dedekind) wrote :

Looks good. Tests pass and device still working.

review: Approve
394. By Nick Dedekind on 2016-02-01

merged with trunk

395. By Nick Dedekind on 2016-02-10

merged with trunk

Michał Sawicz (saviq) wrote :

/«BUILDDIR»/qtmir-0.4.7+16.04.20160210/tests/modules/ApplicationManager/application_manager_test.cpp: In member function 'virtual void ApplicationManagerTests_CloseWhenSuspendedProcessFailed_Test::TestBody()':
/«BUILDDIR»/qtmir-0.4.7+16.04.20160210/tests/modules/ApplicationManager/application_manager_test.cpp:2305:51: error: no matching function for call to 'qtmir::ApplicationManager::onProcessFailed(const QString&, bool)'

review: Needs Fixing
396. By Daniel d'Andrada on 2016-02-11

Remove the useless TaskController

It was just forwarding calls between ApplicationManager and ApplicationCrontroller.
Had no logic of its own.

ApplicationCrontroller was then renamed to TaskController as the latter has a better API and it also keeps ApplicationManager code more or less untouched.

Tests have been improved a bit by better emulating TaskController behavior

Daniel d'Andrada (dandrader) wrote :

On 11/02/2016 09:19, Michał Sawicz wrote:
> Review: Needs Fixing
>
> /«BUILDDIR»/qtmir-0.4.7+16.04.20160210/tests/modules/ApplicationManager/application_manager_test.cpp: In member function 'virtual void ApplicationManagerTests_CloseWhenSuspendedProcessFailed_Test::TestBody()':
> /«BUILDDIR»/qtmir-0.4.7+16.04.20160210/tests/modules/ApplicationManager/application_manager_test.cpp:2305:51: error: no matching function for call to 'qtmir::ApplicationManager::onProcessFailed(const QString&, bool)'

Done.

Michał Sawicz (saviq) :
review: Abstain

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/modules/Unity/Application/CMakeLists.txt'
2--- src/modules/Unity/Application/CMakeLists.txt 2015-10-13 09:00:00 +0000
3+++ src/modules/Unity/Application/CMakeLists.txt 2016-02-11 11:52:55 +0000
4@@ -31,7 +31,6 @@
5 plugin.cpp
6 applicationscreenshotprovider.cpp
7 dbuswindowstack.cpp
8- taskcontroller.cpp
9 mirsurfacemanager.cpp
10 ubuntukeyboardinfo.cpp
11 mirsurface.cpp
12@@ -42,7 +41,9 @@
13 session.cpp
14 sessionmanager.cpp
15 sharedwakelock.cpp
16- upstart/applicationcontroller.cpp
17+ upstart/taskcontroller.cpp
18+ timer.cpp
19+ timesource.cpp
20 tracepoints.c
21 settings.cpp
22 # We need to run moc on these headers
23@@ -53,7 +54,7 @@
24 ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/Mir.h
25 # Feed the automoc monster
26 session_interface.h
27- applicationcontroller.h
28+ taskcontroller.h
29 settings_interface.h
30 )
31
32
33=== modified file 'src/modules/Unity/Application/application.cpp'
34--- src/modules/Unity/Application/application.cpp 2016-02-03 18:10:07 +0000
35+++ src/modules/Unity/Application/application.cpp 2016-02-11 11:52:55 +0000
36@@ -20,7 +20,7 @@
37 #include "desktopfilereader.h"
38 #include "session.h"
39 #include "sharedwakelock.h"
40-#include "taskcontroller.h"
41+#include "timer.h"
42
43 // common
44 #include <debughelpers.h>
45@@ -52,7 +52,7 @@
46 , m_session(nullptr)
47 , m_requestedState(RequestedRunning)
48 , m_processState(ProcessUnknown)
49- , m_closeTimer(0)
50+ , m_closeTimer(nullptr)
51 , m_exemptFromLifecycle(false)
52 {
53 qCDebug(QTMIR_APPLICATIONS) << "Application::Application - appId=" << desktopFileReader->appId();
54@@ -66,6 +66,8 @@
55 m_supportedOrientations = m_desktopData->supportedOrientations();
56
57 m_rotatesWindowContents = m_desktopData->rotatesWindowContents();
58+
59+ setCloseTimer(new Timer);
60 }
61
62 Application::~Application()
63@@ -101,6 +103,7 @@
64 delete m_session;
65 }
66 delete m_desktopData;
67+ delete m_closeTimer;
68 }
69
70
71@@ -436,11 +439,11 @@
72
73 void Application::doClose()
74 {
75- Q_ASSERT(m_closeTimer == 0);
76+ Q_ASSERT(!m_closeTimer->isRunning());;
77 Q_ASSERT(m_session != nullptr);
78
79 m_session->close();
80- m_closeTimer = startTimer(3000);
81+ m_closeTimer->start();
82 setInternalState(InternalState::Closing);
83 }
84
85@@ -685,14 +688,6 @@
86 Q_EMIT stopProcessRequested();
87 }
88
89-void Application::timerEvent(QTimerEvent *event)
90-{
91- if (event->timerId() == m_closeTimer) {
92- m_closeTimer = 0;
93- stop();
94- }
95-}
96-
97 bool Application::isTouchApp() const
98 {
99 return m_desktopData->isTouchApp();
100@@ -793,4 +788,14 @@
101 }
102 }
103
104+void Application::setCloseTimer(AbstractTimer *timer)
105+{
106+ delete m_closeTimer;
107+
108+ m_closeTimer = timer;
109+ m_closeTimer->setInterval(3000);
110+ m_closeTimer->setSingleShot(true);
111+ connect(m_closeTimer, &Timer::timeout, this, &Application::stop);
112+}
113+
114 } // namespace qtmir
115
116=== modified file 'src/modules/Unity/Application/application.h'
117--- src/modules/Unity/Application/application.h 2015-12-07 12:23:29 +0000
118+++ src/modules/Unity/Application/application.h 2016-02-11 11:52:55 +0000
119@@ -43,6 +43,7 @@
120 class DesktopFileReader;
121 class Session;
122 class SharedWakelock;
123+class AbstractTimer;
124
125 class Application : public unity::shell::application::ApplicationInfoInterface
126 {
127@@ -133,6 +134,7 @@
128
129 // for tests
130 InternalState internalState() const { return m_state; }
131+ void setCloseTimer(AbstractTimer *timer);
132
133 Q_SIGNALS:
134 void fullscreenChanged(bool fullscreen);
135@@ -150,9 +152,6 @@
136
137 void respawn();
138
139-protected:
140- void timerEvent(QTimerEvent *event);
141-
142 private:
143
144 QString longAppId() const;
145@@ -187,7 +186,7 @@
146 SessionInterface *m_session;
147 RequestedState m_requestedState;
148 ProcessState m_processState;
149- int m_closeTimer;
150+ AbstractTimer *m_closeTimer;
151 bool m_exemptFromLifecycle;
152
153 friend class ApplicationManager;
154
155=== modified file 'src/modules/Unity/Application/application_manager.cpp'
156--- src/modules/Unity/Application/application_manager.cpp 2016-01-22 16:32:39 +0000
157+++ src/modules/Unity/Application/application_manager.cpp 2016-02-11 11:52:55 +0000
158@@ -22,8 +22,7 @@
159 #include "session.h"
160 #include "sharedwakelock.h"
161 #include "proc_info.h"
162-#include "taskcontroller.h"
163-#include "upstart/applicationcontroller.h"
164+#include "upstart/taskcontroller.h"
165 #include "tracepoints.h" // generated from tracepoints.tp
166 #include "settings.h"
167
168@@ -32,7 +31,6 @@
169 #include "nativeinterface.h"
170 #include "sessionlistener.h"
171 #include "sessionauthorizer.h"
172-#include "taskcontroller.h"
173 #include "logging.h"
174
175 // mir
176@@ -125,8 +123,7 @@
177 SessionListener *sessionListener = static_cast<SessionListener*>(nativeInterface->nativeResourceForIntegration("SessionListener"));
178 SessionAuthorizer *sessionAuthorizer = static_cast<SessionAuthorizer*>(nativeInterface->nativeResourceForIntegration("SessionAuthorizer"));
179
180- QSharedPointer<upstart::ApplicationController> appController(new upstart::ApplicationController());
181- QSharedPointer<TaskController> taskController(new TaskController(nullptr, appController));
182+ QSharedPointer<TaskController> taskController(new upstart::TaskController());
183 QSharedPointer<DesktopFileReader::Factory> fileReaderFactory(new DesktopFileReader::Factory());
184 QSharedPointer<ProcInfo> procInfo(new ProcInfo());
185 QSharedPointer<SharedWakelock> sharedWakelock(new SharedWakelock);
186@@ -461,15 +458,14 @@
187 m_closingApplications.removeAll(application);
188 });
189 m_closingApplications.append(application);
190- application->close();
191 return true;
192 }
193
194-void ApplicationManager::onProcessFailed(const QString &appId, const bool duringStartup)
195+void ApplicationManager::onProcessFailed(const QString &appId, TaskController::Error error)
196 {
197 // Applications fail if they fail to launch, crash or are killed.
198
199- qCDebug(QTMIR_APPLICATIONS) << "ApplicationManager::onProcessFailed - appId=" << appId << "duringStartup=" << duringStartup;
200+ qCDebug(QTMIR_APPLICATIONS) << "ApplicationManager::onProcessFailed - appId=" << appId;
201
202 Application *application = findApplication(appId);
203 if (!application) {
204@@ -478,7 +474,7 @@
205 return;
206 }
207
208- Q_UNUSED(duringStartup); // FIXME(greyback) upstart reports app that fully started up & crashes as failing during startup??
209+ Q_UNUSED(error); // FIXME(greyback) upstart reports app that fully started up & crashes as failing during startup??
210 application->setProcessState(Application::ProcessFailed);
211 application->setPid(0);
212 }
213
214=== modified file 'src/modules/Unity/Application/application_manager.h'
215--- src/modules/Unity/Application/application_manager.h 2015-12-07 12:23:29 +0000
216+++ src/modules/Unity/Application/application_manager.h 2016-02-11 11:52:55 +0000
217@@ -30,6 +30,7 @@
218 // local
219 #include "application.h"
220 #include "desktopfilereader.h"
221+#include "taskcontroller.h"
222
223 namespace mir {
224 namespace scene {
225@@ -47,7 +48,6 @@
226 class MirSurfaceManager;
227 class ProcInfo;
228 class SharedWakelock;
229-class TaskController;
230 class SettingsInterface;
231
232 class ApplicationManager : public unity::shell::application::ApplicationManagerInterface
233@@ -127,7 +127,7 @@
234 void onProcessStarting(const QString& appId);
235 void onProcessStopped(const QString& appId);
236 void onProcessSuspended(const QString& appId);
237- void onProcessFailed(const QString& appId, const bool duringStartup);
238+ void onProcessFailed(const QString& appId, TaskController::Error error);
239 void onFocusRequested(const QString& appId);
240 void onResumeRequested(const QString& appId);
241
242
243=== removed file 'src/modules/Unity/Application/taskcontroller.cpp'
244--- src/modules/Unity/Application/taskcontroller.cpp 2015-10-08 11:20:30 +0000
245+++ src/modules/Unity/Application/taskcontroller.cpp 1970-01-01 00:00:00 +0000
246@@ -1,119 +0,0 @@
247-/*
248- * Copyright (C) 2013-2015 Canonical, Ltd.
249- *
250- * This program is free software: you can redistribute it and/or modify it under
251- * the terms of the GNU Lesser General Public License version 3, as published by
252- * the Free Software Foundation.
253- *
254- * This program is distributed in the hope that it will be useful, but WITHOUT
255- * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
256- * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
257- * Lesser General Public License for more details.
258- *
259- * You should have received a copy of the GNU Lesser General Public License
260- * along with this program. If not, see <http://www.gnu.org/licenses/>.
261- */
262-
263-// local
264-#include "taskcontroller.h"
265-#include "logging.h"
266-
267-// Qt
268-#include <QStringList>
269-
270-// STL
271-#include <mutex>
272-
273-// std
274-#include <csignal>
275-#include <unistd.h>
276-
277-namespace qtmir
278-{
279-
280-TaskController::TaskController(
281- QObject *parent,
282- const QSharedPointer<ApplicationController> &appController) :
283- QObject(parent),
284- m_appController(appController)
285-{
286- connect(m_appController.data(),
287- &ApplicationController::applicationAboutToBeStarted,
288- this,
289- &TaskController::processStarting);
290-
291- connect(m_appController.data(),
292- &ApplicationController::applicationStopped,
293- this,
294- &TaskController::processStopped);
295-
296- connect(m_appController.data(),
297- &ApplicationController::applicationPaused,
298- this,
299- &TaskController::processSuspended);
300-
301- connect(m_appController.data(),
302- &ApplicationController::applicationFocusRequest,
303- this,
304- &TaskController::focusRequested);
305-
306- connect(m_appController.data(),
307- &ApplicationController::applicationResumeRequested,
308- this,
309- &TaskController::resumeRequested);
310-
311- connect(m_appController.data(),
312- &ApplicationController::applicationError,
313- this,
314- &TaskController::onApplicationError);
315-}
316-
317-TaskController::~TaskController()
318-{
319-}
320-
321-bool TaskController::start(const QString& appId, const QStringList& arguments)
322-{
323- qCDebug(QTMIR_APPLICATIONS) << "TaskController::start - appId=" << appId;
324- return m_appController->startApplicationWithAppIdAndArgs(appId, arguments);
325-}
326-
327-bool TaskController::stop(const QString& appId)
328-{
329- qCDebug(QTMIR_APPLICATIONS) << "TaskController::stop - appId=" << appId;
330- auto result = m_appController->stopApplicationWithAppId(appId);
331- if (!result)
332- qCDebug(QTMIR_APPLICATIONS) << "TaskController::stopApplication - FAILED to stop appId=" << appId;
333-
334- return result;
335-}
336-
337-bool TaskController::appIdHasProcessId(const QString& appId, const pid_t pid) const
338-{
339- qCDebug(QTMIR_APPLICATIONS) << "TaskController::isApplicationPid - appId=" << appId << "pid=" << pid;
340- return m_appController->appIdHasProcessId(pid, appId);
341-}
342-
343-QFileInfo TaskController::findDesktopFileForAppId(const QString &appId) const
344-{
345- return m_appController->findDesktopFileForAppId(appId);
346-}
347-
348-bool TaskController::suspend(const QString &appId)
349-{
350- qCDebug(QTMIR_APPLICATIONS) << "TaskController::suspend - appId=" << appId;
351- return m_appController->pauseApplicationWithAppId(appId);
352-}
353-
354-bool TaskController::resume(const QString &appId)
355-{
356- qCDebug(QTMIR_APPLICATIONS) << "TaskController::resume - appId=" << appId;
357- return m_appController->resumeApplicationWithAppId(appId);
358-}
359-
360-void TaskController::onApplicationError(const QString& id, ApplicationController::Error error)
361-{
362- Q_EMIT processFailed(id, (error == ApplicationController::Error::APPLICATION_FAILED_TO_START) );
363-}
364-
365-} // namespace qtmir
366
367=== renamed file 'src/modules/Unity/Application/applicationcontroller.h' => 'src/modules/Unity/Application/taskcontroller.h'
368--- src/modules/Unity/Application/applicationcontroller.h 2015-08-11 12:08:32 +0000
369+++ src/modules/Unity/Application/taskcontroller.h 2016-02-11 11:52:55 +0000
370@@ -15,8 +15,8 @@
371 *
372 */
373
374-#ifndef APPLICATION_CONTROLLER_H
375-#define APPLICATION_CONTROLLER_H
376+#ifndef QTMIR_TASK_CONTROLLER_H
377+#define QTMIR_TASK_CONTROLLER_H
378
379 #include <QObject>
380 #include <QString>
381@@ -26,7 +26,7 @@
382 namespace qtmir
383 {
384
385-class ApplicationController : public QObject
386+class TaskController : public QObject
387 {
388 Q_OBJECT
389
390@@ -37,36 +37,36 @@
391 APPLICATION_FAILED_TO_START
392 };
393
394- ApplicationController(const ApplicationController&) = delete;
395- virtual ~ApplicationController() = default;
396+ TaskController(const TaskController&) = delete;
397+ virtual ~TaskController() = default;
398
399- ApplicationController& operator=(const ApplicationController&) = delete;
400+ TaskController& operator=(const TaskController&) = delete;
401
402 virtual pid_t primaryPidForAppId(const QString &appId) = 0;
403- virtual bool appIdHasProcessId(pid_t pid, const QString &appId) = 0;
404-
405- virtual bool stopApplicationWithAppId(const QString &appId) = 0;
406- virtual bool startApplicationWithAppIdAndArgs(const QString &appId, const QStringList &arguments) = 0;
407-
408- virtual bool pauseApplicationWithAppId(const QString &appId) = 0;
409- virtual bool resumeApplicationWithAppId(const QString &appId) = 0;
410+ virtual bool appIdHasProcessId(const QString &appId, pid_t pid) = 0;
411+
412+ virtual bool stop(const QString &appId) = 0;
413+ virtual bool start(const QString &appId, const QStringList &arguments) = 0;
414+
415+ virtual bool suspend(const QString &appId) = 0;
416+ virtual bool resume(const QString &appId) = 0;
417
418 virtual QFileInfo findDesktopFileForAppId(const QString &appId) const = 0;
419
420 Q_SIGNALS:
421- void applicationAboutToBeStarted(const QString &appId);
422+ void processStarting(const QString &appId);
423 void applicationStarted(const QString &appId);
424- void applicationStopped(const QString &appId);
425- void applicationPaused(const QString &appId);
426- void applicationFocusRequest(const QString &appId);
427- void applicationResumeRequested(const QString &appId);
428+ void processStopped(const QString &appId);
429+ void processSuspended(const QString &appId);
430+ void focusRequested(const QString &appId);
431+ void resumeRequested(const QString &appId);
432
433- void applicationError(const QString &appId, ApplicationController::Error error);
434+ void processFailed(const QString &appId, TaskController::Error error);
435
436 protected:
437- ApplicationController() = default;
438+ TaskController() = default;
439 };
440
441 } // namespace qtmir
442
443-#endif // APPLICATION_CONTROLLER_H
444+#endif // QTMIR_TASK_CONTROLLER_H
445
446=== removed file 'src/modules/Unity/Application/taskcontroller.h'
447--- src/modules/Unity/Application/taskcontroller.h 2015-10-08 11:20:30 +0000
448+++ src/modules/Unity/Application/taskcontroller.h 1970-01-01 00:00:00 +0000
449@@ -1,63 +0,0 @@
450-/*
451- * Copyright (C) 2013-2015 Canonical, Ltd.
452- *
453- * This program is free software: you can redistribute it and/or modify it under
454- * the terms of the GNU Lesser General Public License version 3, as published by
455- * the Free Software Foundation.
456- *
457- * This program is distributed in the hope that it will be useful, but WITHOUT
458- * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
459- * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
460- * Lesser General Public License for more details.
461- *
462- * You should have received a copy of the GNU Lesser General Public License
463- * along with this program. If not, see <http://www.gnu.org/licenses/>.
464- */
465-
466-#ifndef TASKCONTROLLER_H
467-#define TASKCONTROLLER_H
468-
469-#include <QObject>
470-
471-#include "application.h"
472-#include "applicationcontroller.h"
473-
474-namespace qtmir
475-{
476-
477-class TaskController : public QObject
478-{
479- Q_OBJECT
480-public:
481- TaskController(
482- QObject *parent,
483- const QSharedPointer<ApplicationController> &appController);
484- ~TaskController();
485-
486- bool start(const QString &appId, const QStringList &args);
487- bool stop(const QString &appId);
488-
489- bool suspend(const QString &appId);
490- bool resume(const QString &appId);
491-
492- bool appIdHasProcessId(const QString &appId, const pid_t pid) const;
493- QFileInfo findDesktopFileForAppId(const QString &appId) const;
494-
495-Q_SIGNALS:
496- void processStarting(const QString &appId);
497- void processStopped(const QString &appId);
498- void processSuspended(const QString &appId);
499- void processFailed(const QString &appId, const bool duringStartup);
500- void focusRequested(const QString &appId);
501- void resumeRequested(const QString &appId);
502-
503-private Q_SLOTS:
504- void onApplicationError(const QString &id, ApplicationController::Error error);
505-
506-private:
507- const QSharedPointer<ApplicationController> m_appController;
508-};
509-
510-} // namespace qtmir
511-
512-#endif // TASKCONTROLLER_H
513
514=== added file 'src/modules/Unity/Application/timer.cpp'
515--- src/modules/Unity/Application/timer.cpp 1970-01-01 00:00:00 +0000
516+++ src/modules/Unity/Application/timer.cpp 2016-02-11 11:52:55 +0000
517@@ -0,0 +1,109 @@
518+/*
519+ * Copyright (C) 2015 Canonical, Ltd.
520+ *
521+ * This program is free software; you can redistribute it and/or modify
522+ * it under the terms of the GNU General Public License as published by
523+ * the Free Software Foundation; version 3.
524+ *
525+ * This program is distributed in the hope that it will be useful,
526+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
527+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
528+ * GNU General Public License for more details.
529+ *
530+ * You should have received a copy of the GNU General Public License
531+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
532+ */
533+
534+#include "timer.h"
535+
536+using namespace qtmir;
537+
538+Timer::Timer(QObject *parent) : AbstractTimer(parent)
539+{
540+ m_timer.setSingleShot(false);
541+ connect(&m_timer, &QTimer::timeout, this, &AbstractTimer::timeout);
542+}
543+
544+int Timer::interval() const
545+{
546+ return m_timer.interval();
547+}
548+
549+void Timer::setInterval(int msecs)
550+{
551+ m_timer.setInterval(msecs);
552+}
553+
554+void Timer::start()
555+{
556+ m_timer.start();
557+ AbstractTimer::start();
558+}
559+
560+void Timer::stop()
561+{
562+ m_timer.stop();
563+ AbstractTimer::stop();
564+}
565+
566+bool Timer::isSingleShot() const
567+{
568+ return m_timer.isSingleShot();
569+}
570+
571+void Timer::setSingleShot(bool value)
572+{
573+ m_timer.setSingleShot(value);
574+}
575+
576+/////////////////////////////////// FakeTimer //////////////////////////////////
577+
578+FakeTimer::FakeTimer(const SharedTimeSource &timeSource, QObject *parent)
579+ : qtmir::AbstractTimer(parent)
580+ , m_interval(0)
581+ , m_singleShot(false)
582+ , m_timeSource(timeSource)
583+{
584+}
585+
586+void FakeTimer::update()
587+{
588+ if (!isRunning()) {
589+ return;
590+ }
591+
592+ if (m_nextTimeoutTime <= m_timeSource->msecsSinceReference()) {
593+ if (isSingleShot()) {
594+ stop();
595+ } else {
596+ m_nextTimeoutTime += interval();
597+ }
598+ Q_EMIT timeout();
599+ }
600+}
601+
602+void FakeTimer::start()
603+{
604+ AbstractTimer::start();
605+ m_nextTimeoutTime = m_timeSource->msecsSinceReference() + (qint64)interval();
606+}
607+
608+int FakeTimer::interval() const
609+{
610+ return m_interval;
611+}
612+
613+void FakeTimer::setInterval(int msecs)
614+{
615+ m_interval = msecs;
616+}
617+
618+bool FakeTimer::isSingleShot() const
619+{
620+ return m_singleShot;
621+}
622+
623+void FakeTimer::setSingleShot(bool value)
624+{
625+ m_singleShot = value;
626+}
627
628=== added file 'src/modules/Unity/Application/timer.h'
629--- src/modules/Unity/Application/timer.h 1970-01-01 00:00:00 +0000
630+++ src/modules/Unity/Application/timer.h 2016-02-11 11:52:55 +0000
631@@ -0,0 +1,88 @@
632+/*
633+ * Copyright (C) 2015 Canonical, Ltd.
634+ *
635+ * This program is free software; you can redistribute it and/or modify
636+ * it under the terms of the GNU General Public License as published by
637+ * the Free Software Foundation; version 3.
638+ *
639+ * This program is distributed in the hope that it will be useful,
640+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
641+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
642+ * GNU General Public License for more details.
643+ *
644+ * You should have received a copy of the GNU General Public License
645+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
646+ */
647+
648+#ifndef QTMIR_TIMER_H
649+#define QTMIR_TIMER_H
650+
651+#include "timesource.h"
652+
653+#include <QObject>
654+#include <QPointer>
655+#include <QTimer>
656+
657+namespace qtmir {
658+
659+/* Defines an interface for a Timer. Useful for tests. */
660+class AbstractTimer : public QObject
661+{
662+ Q_OBJECT
663+public:
664+ AbstractTimer(QObject *parent) : QObject(parent), m_isRunning(false) {}
665+ virtual int interval() const = 0;
666+ virtual void setInterval(int msecs) = 0;
667+ virtual void start() { m_isRunning = true; }
668+ virtual void stop() { m_isRunning = false; }
669+ bool isRunning() const { return m_isRunning; }
670+ virtual bool isSingleShot() const = 0;
671+ virtual void setSingleShot(bool value) = 0;
672+Q_SIGNALS:
673+ void timeout();
674+private:
675+ bool m_isRunning;
676+};
677+
678+/* Essentially a QTimer wrapper */
679+class Timer : public AbstractTimer
680+{
681+ Q_OBJECT
682+public:
683+ Timer(QObject *parent = nullptr);
684+
685+ int interval() const override;
686+ void setInterval(int msecs) override;
687+ void start() override;
688+ void stop() override;
689+ bool isSingleShot() const override;
690+ void setSingleShot(bool value) override;
691+private:
692+ QTimer m_timer;
693+};
694+
695+/* For tests */
696+class FakeTimer : public AbstractTimer
697+{
698+ Q_OBJECT
699+public:
700+ FakeTimer(const SharedTimeSource &timeSource, QObject *parent = nullptr);
701+
702+ void update();
703+ qint64 nextTimeoutTime() const { return m_nextTimeoutTime; }
704+
705+ int interval() const override;
706+ void setInterval(int msecs) override;
707+ void start() override;
708+ bool isSingleShot() const override;
709+ void setSingleShot(bool value) override;
710+private:
711+ int m_interval;
712+ bool m_singleShot;
713+ SharedTimeSource m_timeSource;
714+ qint64 m_nextTimeoutTime;
715+};
716+
717+} // namespace qtmir
718+
719+#endif // QTMIR_TIMER_H
720
721=== added file 'src/modules/Unity/Application/timesource.cpp'
722--- src/modules/Unity/Application/timesource.cpp 1970-01-01 00:00:00 +0000
723+++ src/modules/Unity/Application/timesource.cpp 2016-02-11 11:52:55 +0000
724@@ -0,0 +1,48 @@
725+/*
726+ * Copyright (C) 2015 - Canonical Ltd.
727+ *
728+ * This program is free software: you can redistribute it and/or modify it
729+ * under the terms of the GNU Lesser General Public License, as
730+ * published by the Free Software Foundation; either version 2.1 or 3.0
731+ * of the License.
732+ *
733+ * This program is distributed in the hope that it will be useful, but
734+ * WITHOUT ANY WARRANTY; without even the implied warranties of
735+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
736+ * PURPOSE. See the applicable version of the GNU Lesser General Public
737+ * License for more details.
738+ *
739+ * You should have received a copy of both the GNU Lesser General Public
740+ * License along with this program. If not, see <http://www.gnu.org/licenses/>
741+ *
742+ */
743+
744+#include "timesource.h"
745+
746+#include <QElapsedTimer>
747+
748+namespace qtmir {
749+class RealTimeSourcePrivate {
750+public:
751+ QElapsedTimer timer;
752+};
753+}
754+
755+using namespace qtmir;
756+
757+RealTimeSource::RealTimeSource()
758+ : TimeSource()
759+ , d(new RealTimeSourcePrivate)
760+{
761+ d->timer.start();
762+}
763+
764+RealTimeSource::~RealTimeSource()
765+{
766+ delete d;
767+}
768+
769+qint64 RealTimeSource::msecsSinceReference()
770+{
771+ return d->timer.elapsed();
772+}
773
774=== added file 'src/modules/Unity/Application/timesource.h'
775--- src/modules/Unity/Application/timesource.h 1970-01-01 00:00:00 +0000
776+++ src/modules/Unity/Application/timesource.h 2016-02-11 11:52:55 +0000
777@@ -0,0 +1,61 @@
778+/*
779+ * Copyright (C) 2015 Canonical Ltd.
780+ *
781+ * This program is free software: you can redistribute it and/or modify it
782+ * under the terms of the GNU Lesser General Public License, as
783+ * published by the Free Software Foundation; either version 2.1 or 3.0
784+ * of the License.
785+ *
786+ * This program is distributed in the hope that it will be useful, but
787+ * WITHOUT ANY WARRANTY; without even the implied warranties of
788+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
789+ * PURPOSE. See the applicable version of the GNU Lesser General Public
790+ * License for more details.
791+ *
792+ * You should have received a copy of both the GNU Lesser General Public
793+ * License along with this program. If not, see <http://www.gnu.org/licenses/>
794+ */
795+
796+#ifndef QTMIR_TIMESOURCE_H
797+#define QTMIR_TIMESOURCE_H
798+
799+#include <QSharedPointer>
800+
801+namespace qtmir {
802+/*
803+ Interface for a time source.
804+ */
805+class TimeSource {
806+public:
807+ virtual ~TimeSource() {}
808+ /* Returns the current time in milliseconds since some reference time in the past. */
809+ virtual qint64 msecsSinceReference() = 0;
810+};
811+typedef QSharedPointer<TimeSource> SharedTimeSource;
812+
813+/*
814+ Implementation of a time source
815+ */
816+class RealTimeSourcePrivate;
817+class RealTimeSource : public TimeSource {
818+public:
819+ RealTimeSource();
820+ virtual ~RealTimeSource();
821+ qint64 msecsSinceReference() override;
822+private:
823+ RealTimeSourcePrivate *d;
824+};
825+
826+/*
827+ A fake time source, useful for tests
828+ */
829+class FakeTimeSource : public TimeSource {
830+public:
831+ FakeTimeSource() { m_msecsSinceReference = 0; }
832+ qint64 msecsSinceReference() override { return m_msecsSinceReference; }
833+ qint64 m_msecsSinceReference;
834+};
835+
836+} // namespace qtmir
837+
838+#endif // QTMIR_TIMESOURCE_H
839
840=== renamed file 'src/modules/Unity/Application/upstart/applicationcontroller.cpp' => 'src/modules/Unity/Application/upstart/taskcontroller.cpp'
841--- src/modules/Unity/Application/upstart/applicationcontroller.cpp 2015-05-27 21:07:45 +0000
842+++ src/modules/Unity/Application/upstart/taskcontroller.cpp 2016-02-11 11:52:55 +0000
843@@ -15,7 +15,7 @@
844 *
845 */
846
847-#include "applicationcontroller.h"
848+#include "taskcontroller.h"
849
850 // qtmir
851 #include <logging.h>
852@@ -33,7 +33,7 @@
853 namespace upstart
854 {
855
856-struct ApplicationController::Private
857+struct TaskController::Private
858 {
859 UbuntuAppLaunchAppObserver preStartCallback = nullptr;
860 UbuntuAppLaunchAppObserver startedCallback = nullptr;
861@@ -100,50 +100,50 @@
862
863 } // namespace
864
865-ApplicationController::ApplicationController()
866- : qtmir::ApplicationController(),
867+TaskController::TaskController()
868+ : qtmir::TaskController(),
869 impl(new Private())
870 {
871 impl->preStartCallback = [](const gchar * appId, gpointer userData) {
872- auto thiz = static_cast<ApplicationController*>(userData);
873- Q_EMIT(thiz->applicationAboutToBeStarted(toShortAppIdIfPossible(appId)));
874+ auto thiz = static_cast<TaskController*>(userData);
875+ Q_EMIT(thiz->processStarting(toShortAppIdIfPossible(appId)));
876 };
877
878 impl->startedCallback = [](const gchar * appId, gpointer userData) {
879- auto thiz = static_cast<ApplicationController*>(userData);
880+ auto thiz = static_cast<TaskController*>(userData);
881 Q_EMIT(thiz->applicationStarted(toShortAppIdIfPossible(appId)));
882 };
883
884 impl->stopCallback = [](const gchar * appId, gpointer userData) {
885- auto thiz = static_cast<ApplicationController*>(userData);
886- Q_EMIT(thiz->applicationStopped(toShortAppIdIfPossible(appId)));
887+ auto thiz = static_cast<TaskController*>(userData);
888+ Q_EMIT(thiz->processStopped(toShortAppIdIfPossible(appId)));
889 };
890
891 impl->focusCallback = [](const gchar * appId, gpointer userData) {
892- auto thiz = static_cast<ApplicationController*>(userData);
893- Q_EMIT(thiz->applicationFocusRequest(toShortAppIdIfPossible(appId)));
894+ auto thiz = static_cast<TaskController*>(userData);
895+ Q_EMIT(thiz->focusRequested(toShortAppIdIfPossible(appId)));
896 };
897
898 impl->resumeCallback = [](const gchar * appId, gpointer userData) {
899- auto thiz = static_cast<ApplicationController*>(userData);
900- Q_EMIT(thiz->applicationResumeRequested(toShortAppIdIfPossible(appId)));
901+ auto thiz = static_cast<TaskController*>(userData);
902+ Q_EMIT(thiz->resumeRequested(toShortAppIdIfPossible(appId)));
903 };
904
905 impl->pausedCallback = [](const gchar * appId, GPid *, gpointer userData) {
906- auto thiz = static_cast<ApplicationController*>(userData);
907- Q_EMIT(thiz->applicationPaused(toShortAppIdIfPossible(appId)));
908+ auto thiz = static_cast<TaskController*>(userData);
909+ Q_EMIT(thiz->processSuspended(toShortAppIdIfPossible(appId)));
910 };
911
912 impl->failureCallback = [](const gchar * appId, UbuntuAppLaunchAppFailed failureType, gpointer userData) {
913- ApplicationController::Error error;
914+ TaskController::Error error;
915 switch(failureType)
916 {
917- case UBUNTU_APP_LAUNCH_APP_FAILED_CRASH: error = ApplicationController::Error::APPLICATION_CRASHED;
918- case UBUNTU_APP_LAUNCH_APP_FAILED_START_FAILURE: error = ApplicationController::Error::APPLICATION_FAILED_TO_START;
919+ case UBUNTU_APP_LAUNCH_APP_FAILED_CRASH: error = TaskController::Error::APPLICATION_CRASHED;
920+ case UBUNTU_APP_LAUNCH_APP_FAILED_START_FAILURE: error = TaskController::Error::APPLICATION_FAILED_TO_START;
921 }
922
923- auto thiz = static_cast<ApplicationController*>(userData);
924- Q_EMIT(thiz->applicationError(toShortAppIdIfPossible(appId), error));
925+ auto thiz = static_cast<TaskController*>(userData);
926+ Q_EMIT(thiz->processFailed(toShortAppIdIfPossible(appId), error));
927 };
928
929 ubuntu_app_launch_observer_add_app_starting(impl->preStartCallback, this);
930@@ -155,7 +155,7 @@
931 ubuntu_app_launch_observer_add_app_failed(impl->failureCallback, this);
932 }
933
934-ApplicationController::~ApplicationController()
935+TaskController::~TaskController()
936 {
937 ubuntu_app_launch_observer_delete_app_starting(impl->preStartCallback, this);
938 ubuntu_app_launch_observer_delete_app_started(impl->startedCallback, this);
939@@ -166,30 +166,30 @@
940 ubuntu_app_launch_observer_delete_app_failed(impl->failureCallback, this);
941 }
942
943-pid_t ApplicationController::primaryPidForAppId(const QString& appId)
944+pid_t TaskController::primaryPidForAppId(const QString& appId)
945 {
946 GPid pid = ubuntu_app_launch_get_primary_pid(toLongAppIdIfPossible(appId).toLatin1().constData());
947 if (!pid)
948- qDebug() << "ApplicationController::primaryPidForAppId FAILED to get PID for appId=" << appId;
949+ qDebug() << "TaskController::primaryPidForAppId FAILED to get PID for appId=" << appId;
950
951 return pid;
952 }
953
954-bool ApplicationController::appIdHasProcessId(pid_t pid, const QString& appId)
955+bool TaskController::appIdHasProcessId(const QString& appId, pid_t pid)
956 {
957 return ubuntu_app_launch_pid_in_app_id(pid, toLongAppIdIfPossible(appId).toLatin1().constData());
958 }
959
960-bool ApplicationController::stopApplicationWithAppId(const QString& appId)
961+bool TaskController::stop(const QString& appId)
962 {
963 auto result = ubuntu_app_launch_stop_application(toLongAppIdIfPossible(appId).toLatin1().constData());
964 if (!result)
965- qDebug() << "ApplicationController::stopApplication FAILED to stop appId=" << appId;
966+ qDebug() << "TaskController::stopApplication FAILED to stop appId=" << appId;
967
968 return result;
969 }
970
971-bool ApplicationController::startApplicationWithAppIdAndArgs(const QString& appId, const QStringList& arguments)
972+bool TaskController::start(const QString& appId, const QStringList& arguments)
973 {
974 // Convert arguments QStringList into format suitable for ubuntu-app-launch
975 // The last item should be null, which is done by g_new0, we just don't fill it.
976@@ -206,33 +206,33 @@
977 g_strfreev(upstartArgs);
978
979 if (!result)
980- qDebug() << "Application::Controller::startApplicationWithAppIdAndArgs FAILED to start appId" << appId;
981+ qDebug() << "TaskController::start FAILED to start appId" << appId;
982
983 return result;
984 }
985
986-bool ApplicationController::pauseApplicationWithAppId(const QString& appId)
987+bool TaskController::suspend(const QString& appId)
988 {
989 auto result = ubuntu_app_launch_pause_application(toLongAppIdIfPossible(appId).toLatin1().constData());
990 if (!result)
991- qDebug() << "ApplicationController::pauseApplication FAILED to pause appId=" << appId;
992+ qDebug() << "TaskController::pauseApplication FAILED to pause appId=" << appId;
993
994 return result;
995 }
996
997-bool ApplicationController::resumeApplicationWithAppId(const QString& appId)
998+bool TaskController::resume(const QString& appId)
999 {
1000 auto result = ubuntu_app_launch_resume_application(toLongAppIdIfPossible(appId).toLatin1().constData());
1001 if (!result)
1002- qDebug() << "ApplicationController::resumeApplication FAILED to resume appId=" << appId;
1003+ qDebug() << "TaskController::resumeApplication FAILED to resume appId=" << appId;
1004
1005 return result;
1006 }
1007
1008
1009-QFileInfo ApplicationController::findDesktopFileForAppId(const QString &appId) const
1010+QFileInfo TaskController::findDesktopFileForAppId(const QString &appId) const
1011 {
1012- qCDebug(QTMIR_APPLICATIONS) << "ApplicationController::desktopFilePathForAppId - appId=" << appId;
1013+ qCDebug(QTMIR_APPLICATIONS) << "TaskController::desktopFilePathForAppId - appId=" << appId;
1014
1015 // Search for the correct desktop file using a simple heuristic
1016 int dashPos = -1;
1017
1018=== renamed file 'src/modules/Unity/Application/upstart/applicationcontroller.h' => 'src/modules/Unity/Application/upstart/taskcontroller.h'
1019--- src/modules/Unity/Application/upstart/applicationcontroller.h 2014-09-18 22:03:02 +0000
1020+++ src/modules/Unity/Application/upstart/taskcontroller.h 2016-02-11 11:52:55 +0000
1021@@ -1,5 +1,5 @@
1022 /*
1023- * Copyright (C) 2013 Canonical, Ltd.
1024+ * Copyright (C) 2013,2015 Canonical, Ltd.
1025 *
1026 * This program is free software: you can redistribute it and/or modify it under
1027 * the terms of the GNU Lesser General Public License version 3, as published by
1028@@ -15,30 +15,30 @@
1029 *
1030 */
1031
1032-#ifndef UPSTART_APPLICATION_CONTROLLER_H
1033-#define UPSTART_APPLICATION_CONTROLLER_H
1034+#ifndef QTMIR_UPSTART_TASK_CONTROLLER_H
1035+#define QTMIR_UPSTART_TASK_CONTROLLER_H
1036
1037-#include "../applicationcontroller.h"
1038+#include "../taskcontroller.h"
1039
1040 namespace qtmir
1041 {
1042 namespace upstart
1043 {
1044
1045-class ApplicationController : public qtmir::ApplicationController
1046+class TaskController : public qtmir::TaskController
1047 {
1048 public:
1049- ApplicationController();
1050- ~ApplicationController();
1051+ TaskController();
1052+ ~TaskController();
1053
1054 pid_t primaryPidForAppId(const QString& appId) override;
1055- bool appIdHasProcessId(pid_t pid, const QString& appId) override;
1056-
1057- bool stopApplicationWithAppId(const QString& appId) override;
1058- bool startApplicationWithAppIdAndArgs(const QString& appId, const QStringList& arguments) override;
1059-
1060- bool pauseApplicationWithAppId(const QString& appId) override;
1061- bool resumeApplicationWithAppId(const QString& appId) override;
1062+ bool appIdHasProcessId(const QString& appId, pid_t pid) override;
1063+
1064+ bool stop(const QString& appId) override;
1065+ bool start(const QString& appId, const QStringList& arguments) override;
1066+
1067+ bool suspend(const QString& appId) override;
1068+ bool resume(const QString& appId) override;
1069
1070 QFileInfo findDesktopFileForAppId(const QString &appId) const override;
1071
1072@@ -50,4 +50,4 @@
1073 } // namespace upstart
1074 } // namespace qtmir
1075
1076-#endif // UPSTART_APPLICATION_CONTROLLER_H
1077+#endif // QTMIR_UPSTART_TASK_CONTROLLER_H
1078
1079=== modified file 'tests/framework/CMakeLists.txt'
1080--- tests/framework/CMakeLists.txt 2016-02-11 11:52:55 +0000
1081+++ tests/framework/CMakeLists.txt 2016-02-11 11:52:55 +0000
1082@@ -13,7 +13,7 @@
1083 fake_desktopfilereader.cpp
1084 fake_mirsurface.cpp
1085 fake_session.cpp
1086- mock_application_controller.cpp
1087+ mock_task_controller.cpp
1088 mock_desktop_file_reader.cpp
1089 mock_display.cpp
1090 mock_display_configuration.cpp
1091
1092=== modified file 'tests/framework/fake_desktopfilereader.cpp'
1093--- tests/framework/fake_desktopfilereader.cpp 2016-02-11 11:52:55 +0000
1094+++ tests/framework/fake_desktopfilereader.cpp 2016-02-11 11:52:55 +0000
1095@@ -16,9 +16,17 @@
1096
1097 #include "fake_desktopfilereader.h"
1098
1099+#include <QDebug>
1100+
1101 namespace qtmir
1102 {
1103
1104+FakeDesktopFileReader::FakeDesktopFileReader(const QString &appId)
1105+ : DesktopFileReader()
1106+ , m_appId(appId)
1107+{
1108+}
1109+
1110 FakeDesktopFileReader::FakeDesktopFileReader()
1111 : DesktopFileReader()
1112 , m_appId("foo-app")
1113@@ -29,7 +37,7 @@
1114 {
1115 }
1116
1117-QString FakeDesktopFileReader::file() const { return QString(); }
1118+QString FakeDesktopFileReader::file() const { return m_appId + ".desktop"; }
1119
1120 QString FakeDesktopFileReader::appId() const { return m_appId; }
1121
1122
1123=== modified file 'tests/framework/fake_desktopfilereader.h'
1124--- tests/framework/fake_desktopfilereader.h 2016-02-11 11:52:55 +0000
1125+++ tests/framework/fake_desktopfilereader.h 2016-02-11 11:52:55 +0000
1126@@ -24,6 +24,7 @@
1127 class FakeDesktopFileReader : public qtmir::DesktopFileReader
1128 {
1129 public:
1130+ FakeDesktopFileReader(const QString &appId);
1131 FakeDesktopFileReader();
1132 virtual ~FakeDesktopFileReader();
1133
1134
1135=== renamed file 'tests/framework/mock_application_controller.cpp' => 'tests/framework/mock_task_controller.cpp'
1136--- tests/framework/mock_application_controller.cpp 2016-02-11 11:52:55 +0000
1137+++ tests/framework/mock_task_controller.cpp 2016-02-11 11:52:55 +0000
1138@@ -14,49 +14,49 @@
1139 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1140 */
1141
1142-#include "mock_application_controller.h"
1143+#include "mock_task_controller.h"
1144
1145 namespace qtmir
1146 {
1147
1148-MockApplicationController::MockApplicationController()
1149+MockTaskController::MockTaskController()
1150 {
1151 using namespace ::testing;
1152 ON_CALL(*this, primaryPidForAppId(_))
1153 .WillByDefault(
1154- Invoke(this, &MockApplicationController::doPrimaryPidForAppId));
1155+ Invoke(this, &MockTaskController::doPrimaryPidForAppId));
1156
1157 ON_CALL(*this, appIdHasProcessId(_, _))
1158 .WillByDefault(
1159- Invoke(this, &MockApplicationController::doAppIdHasProcessId));
1160+ Invoke(this, &MockTaskController::doAppIdHasProcessId));
1161
1162 ON_CALL(*this, findDesktopFileForAppId(_))
1163 .WillByDefault(
1164- Invoke(this, &MockApplicationController::doFindDesktopFileForAppId));
1165-
1166- ON_CALL(*this, stopApplicationWithAppId(_))
1167- .WillByDefault(
1168- Invoke(this, &MockApplicationController::doStopApplicationWithAppId));
1169-
1170- ON_CALL(*this, startApplicationWithAppIdAndArgs(_, _))
1171- .WillByDefault(
1172- Invoke(this, &MockApplicationController::doStartApplicationWithAppIdAndArgs));
1173-
1174- ON_CALL(*this, pauseApplicationWithAppId(_))
1175- .WillByDefault(
1176- Invoke(this, &MockApplicationController::doPauseApplicationWithAppId));
1177-
1178- ON_CALL(*this, resumeApplicationWithAppId(_))
1179- .WillByDefault(
1180- Invoke(this, &MockApplicationController::doResumeApplicationWithAppId));
1181+ Invoke(this, &MockTaskController::doFindDesktopFileForAppId));
1182+
1183+ ON_CALL(*this, stop(_))
1184+ .WillByDefault(
1185+ Invoke(this, &MockTaskController::doStop));
1186+
1187+ ON_CALL(*this, start(_, _))
1188+ .WillByDefault(
1189+ Invoke(this, &MockTaskController::doStart));
1190+
1191+ ON_CALL(*this, suspend(_))
1192+ .WillByDefault(
1193+ Invoke(this, &MockTaskController::doSuspend));
1194+
1195+ ON_CALL(*this, resume(_))
1196+ .WillByDefault(
1197+ Invoke(this, &MockTaskController::doResume));
1198 }
1199
1200-MockApplicationController::~MockApplicationController()
1201+MockTaskController::~MockTaskController()
1202 {
1203
1204 }
1205
1206-pid_t MockApplicationController::doPrimaryPidForAppId(const QString &appId)
1207+pid_t MockTaskController::doPrimaryPidForAppId(const QString &appId)
1208 {
1209 auto it = children.find(appId);
1210 if (it == children.end())
1211@@ -66,7 +66,7 @@
1212 }
1213
1214
1215-bool MockApplicationController::doAppIdHasProcessId(pid_t pid, const QString &appId)
1216+bool MockTaskController::doAppIdHasProcessId(const QString &appId, pid_t pid)
1217 {
1218 auto it = children.find(appId);
1219 if (it == children.end())
1220@@ -76,14 +76,14 @@
1221 }
1222
1223
1224-QFileInfo MockApplicationController::doFindDesktopFileForAppId(const QString &appId) const
1225+QFileInfo MockTaskController::doFindDesktopFileForAppId(const QString &appId) const
1226 {
1227 QString path = QString("/usr/share/applications/%1.desktop").arg(appId);
1228 return QFileInfo(path);
1229 }
1230
1231
1232-bool MockApplicationController::doStopApplicationWithAppId(const QString &appId)
1233+bool MockTaskController::doStop(const QString &appId)
1234 {
1235 Q_UNUSED(appId);
1236
1237@@ -91,7 +91,7 @@
1238 }
1239
1240
1241-bool MockApplicationController::doStartApplicationWithAppIdAndArgs(const QString &appId, const QStringList &args)
1242+bool MockTaskController::doStart(const QString &appId, const QStringList &args)
1243 {
1244 Q_UNUSED(args);
1245
1246@@ -112,14 +112,14 @@
1247 }
1248
1249
1250-bool MockApplicationController::doPauseApplicationWithAppId(const QString &appId)
1251+bool MockTaskController::doSuspend(const QString &appId)
1252 {
1253 Q_UNUSED(appId);
1254
1255 return false;
1256 }
1257
1258-bool MockApplicationController::doResumeApplicationWithAppId(const QString &appId)
1259+bool MockTaskController::doResume(const QString &appId)
1260 {
1261 Q_UNUSED(appId);
1262
1263
1264=== renamed file 'tests/framework/mock_application_controller.h' => 'tests/framework/mock_task_controller.h'
1265--- tests/framework/mock_application_controller.h 2016-02-11 11:52:55 +0000
1266+++ tests/framework/mock_task_controller.h 2016-02-11 11:52:55 +0000
1267@@ -14,10 +14,10 @@
1268 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1269 */
1270
1271-#ifndef MOCK_APPLICATION_CONTROLLER_H
1272-#define MOCK_APPLICATION_CONTROLLER_H
1273+#ifndef MOCK_TASK_CONTROLLER_H
1274+#define MOCK_TASK_CONTROLLER_H
1275
1276-#include <Unity/Application/applicationcontroller.h>
1277+#include <Unity/Application/taskcontroller.h>
1278 #include <QMap>
1279
1280 #include <core/posix/fork.h>
1281@@ -26,33 +26,33 @@
1282
1283 namespace qtmir
1284 {
1285-struct MockApplicationController : public qtmir::ApplicationController
1286+struct MockTaskController : public qtmir::TaskController
1287 {
1288- MockApplicationController();
1289- virtual ~MockApplicationController();
1290+ MockTaskController();
1291+ virtual ~MockTaskController();
1292
1293 MOCK_METHOD1(primaryPidForAppId, pid_t(const QString& appId));
1294- MOCK_METHOD2(appIdHasProcessId, bool(pid_t, const QString&));
1295+ MOCK_METHOD2(appIdHasProcessId, bool(const QString&, pid_t));
1296 MOCK_CONST_METHOD1(findDesktopFileForAppId, QFileInfo(const QString &appId));
1297
1298- MOCK_METHOD1(stopApplicationWithAppId, bool(const QString&));
1299- MOCK_METHOD2(startApplicationWithAppIdAndArgs, bool(const QString&, const QStringList&));
1300- MOCK_METHOD1(pauseApplicationWithAppId, bool(const QString&));
1301- MOCK_METHOD1(resumeApplicationWithAppId, bool(const QString&));
1302+ MOCK_METHOD1(stop, bool(const QString&));
1303+ MOCK_METHOD2(start, bool(const QString&, const QStringList&));
1304+ MOCK_METHOD1(suspend, bool(const QString&));
1305+ MOCK_METHOD1(resume, bool(const QString&));
1306
1307 pid_t doPrimaryPidForAppId(const QString& appId);
1308
1309- bool doAppIdHasProcessId(pid_t pid, const QString& appId);
1310+ bool doAppIdHasProcessId(const QString& appId, pid_t pid);
1311
1312 QFileInfo doFindDesktopFileForAppId(const QString& appId) const;
1313
1314- bool doStopApplicationWithAppId(const QString& appId);
1315-
1316- bool doStartApplicationWithAppIdAndArgs(const QString& appId, const QStringList& args);
1317-
1318- bool doPauseApplicationWithAppId(const QString& appId);
1319-
1320- bool doResumeApplicationWithAppId(const QString& appId);
1321+ bool doStop(const QString& appId);
1322+
1323+ bool doStart(const QString& appId, const QStringList& args);
1324+
1325+ bool doSuspend(const QString& appId);
1326+
1327+ bool doResume(const QString& appId);
1328
1329 private:
1330 QMap<QString, core::posix::ChildProcess> children;
1331@@ -60,4 +60,4 @@
1332
1333 } // namespace qtmir
1334
1335-#endif // MOCK_APPLICATION_CONTROLLER_H
1336+#endif // MOCK_TASK_CONTROLLER_H
1337
1338=== modified file 'tests/framework/qtmir_test.cpp'
1339--- tests/framework/qtmir_test.cpp 2016-02-11 11:52:55 +0000
1340+++ tests/framework/qtmir_test.cpp 2016-02-11 11:52:55 +0000
1341@@ -120,12 +120,8 @@
1342 QtMirTest::QtMirTest()
1343 : promptSessionManager(std::make_shared<StubPromptSessionManager>())
1344 , mirServer(QSharedPointer<MirServer>(new FakeMirServer(promptSessionManager)))
1345- , taskController(QSharedPointer<TaskController>(
1346- new TaskController(
1347- nullptr,
1348- QSharedPointer<ApplicationController>(&appController, [](ApplicationController*){}))))
1349 , applicationManager(mirServer,
1350- taskController,
1351+ taskControllerSharedPointer,
1352 QSharedPointer<MockSharedWakelock>(&sharedWakelock, [](MockSharedWakelock *){}),
1353 QSharedPointer<DesktopFileReader::Factory>(&desktopFileReaderFactory,[](DesktopFileReader::Factory*){}),
1354 QSharedPointer<ProcInfo>(&procInfo,[](ProcInfo *){}),
1355@@ -144,7 +140,7 @@
1356 {
1357 using namespace testing;
1358
1359- ON_CALL(appController,appIdHasProcessId(procId, appId)).WillByDefault(Return(true));
1360+ ON_CALL(*taskController,appIdHasProcessId(appId, procId)).WillByDefault(Return(true));
1361
1362 // Set up Mocks & signal watcher
1363 auto mockDesktopFileReader = new NiceMock<MockDesktopFileReader>(appId, QFileInfo());
1364@@ -155,7 +151,7 @@
1365 .Times(1)
1366 .WillOnce(Return(mockDesktopFileReader));
1367
1368- EXPECT_CALL(appController, startApplicationWithAppIdAndArgs(appId, _))
1369+ EXPECT_CALL(*taskController, start(appId, _))
1370 .Times(1)
1371 .WillOnce(Return(true));
1372
1373@@ -169,8 +165,8 @@
1374 auto appSession = std::make_shared<mir::scene::MockSession>(appId.toStdString(), procId);
1375 applicationManager.onSessionStarting(appSession);
1376 sessionManager.onSessionStarting(appSession);
1377-
1378- Mock::VerifyAndClearExpectations(&appController);
1379+
1380+ Mock::VerifyAndClearExpectations(taskController);
1381 Mock::VerifyAndClearExpectations(&desktopFileReaderFactory);
1382 return application;
1383 }
1384
1385=== modified file 'tests/framework/qtmir_test.h'
1386--- tests/framework/qtmir_test.h 2016-02-11 11:52:55 +0000
1387+++ tests/framework/qtmir_test.h 2016-02-11 11:52:55 +0000
1388@@ -21,18 +21,17 @@
1389
1390 #include <gtest/gtest.h>
1391
1392+#include <QSharedPointer>
1393+
1394 #include <Unity/Application/application.h>
1395 #include <Unity/Application/application_manager.h>
1396-#include <Unity/Application/applicationcontroller.h>
1397 #include <Unity/Application/mirsurfacemanager.h>
1398 #include <Unity/Application/sessionmanager.h>
1399 #include <Unity/Application/session_interface.h>
1400 #include <Unity/Application/sharedwakelock.h>
1401-#include <Unity/Application/taskcontroller.h>
1402 #include <Unity/Application/proc_info.h>
1403 #include <mirserver.h>
1404
1405-#include "mock_application_controller.h"
1406 #include "mock_desktop_file_reader.h"
1407 #include "mock_proc_info.h"
1408 #include "mock_mir_session.h"
1409@@ -40,6 +39,7 @@
1410 #include "mock_prompt_session.h"
1411 #include "mock_shared_wakelock.h"
1412 #include "mock_settings.h"
1413+#include "mock_task_controller.h"
1414
1415 namespace ms = mir::scene;
1416 using namespace qtmir;
1417@@ -64,7 +64,8 @@
1418
1419 Application* startApplication(pid_t procId, QString const& appId);
1420
1421- testing::NiceMock<MockApplicationController> appController;
1422+ QSharedPointer<qtmir::TaskController> taskControllerSharedPointer{new testing::NiceMock<qtmir::MockTaskController>};
1423+ testing::NiceMock<qtmir::MockTaskController> *taskController{static_cast<testing::NiceMock<qtmir::MockTaskController>*>(taskControllerSharedPointer.data())};
1424 testing::NiceMock<MockProcInfo> procInfo;
1425 testing::NiceMock<MockDesktopFileReaderFactory> desktopFileReaderFactory;
1426 testing::NiceMock<MockSharedWakelock> sharedWakelock;
1427@@ -73,7 +74,6 @@
1428 QSharedPointer<MirServer> mirServer;
1429
1430 MirShell *mirShell{nullptr};
1431- QSharedPointer<TaskController> taskController;
1432 ApplicationManager applicationManager;
1433 SessionManager sessionManager;
1434 MirSurfaceManager surfaceManager;
1435
1436=== modified file 'tests/modules/ApplicationManager/application_manager_test.cpp'
1437--- tests/modules/ApplicationManager/application_manager_test.cpp 2016-02-03 18:03:55 +0000
1438+++ tests/modules/ApplicationManager/application_manager_test.cpp 2016-02-11 11:52:55 +0000
1439@@ -21,10 +21,13 @@
1440 #include <QSignalSpy>
1441
1442 #include <Unity/Application/applicationscreenshotprovider.h>
1443-
1444- #include <fake_mirsurface.h>
1445- #include <mock_surface.h>
1446- #include <qtmir_test.h>
1447+#include <Unity/Application/timer.h>
1448+
1449+#include <fake_desktopfilereader.h>
1450+#include <fake_mirsurface.h>
1451+#include <mock_surface.h>
1452+#include <qtmir_test.h>
1453+
1454
1455 using namespace qtmir;
1456 using mir::scene::MockSession;
1457@@ -126,7 +129,7 @@
1458 Application * beforeFailure = applicationManager.findApplication(app_id);
1459 applicationManager.onProcessStarting(app_id);
1460 onSessionStopping(mirSession);
1461- applicationManager.onProcessFailed(app_id, true);
1462+ applicationManager.onProcessFailed(app_id, TaskController::Error::APPLICATION_FAILED_TO_START);
1463 Application * afterFailure = applicationManager.findApplication(app_id);
1464
1465 EXPECT_EQ(true, authed);
1466@@ -140,8 +143,8 @@
1467
1468 const QString shortAppId("com.canonical.test_test");
1469
1470- EXPECT_CALL(appController, startApplicationWithAppIdAndArgs(_, _)).Times(1);
1471- EXPECT_CALL(appController, findDesktopFileForAppId(shortAppId)).Times(1);
1472+ EXPECT_CALL(*taskController, start(_, _)).Times(1);
1473+ EXPECT_CALL(*taskController, findDesktopFileForAppId(shortAppId)).Times(1);
1474
1475 EXPECT_CALL(desktopFileReaderFactory, createInstance(_, _)).Times(1);
1476
1477@@ -160,8 +163,8 @@
1478 const QString longAppId("com.canonical.test_test_0.1.235");
1479 const QString shortAppId("com.canonical.test_test");
1480
1481- EXPECT_CALL(appController, startApplicationWithAppIdAndArgs(_, _)).Times(1);
1482- EXPECT_CALL(appController, findDesktopFileForAppId(shortAppId)).Times(1);
1483+ EXPECT_CALL(*taskController, start(_, _)).Times(1);
1484+ EXPECT_CALL(*taskController, findDesktopFileForAppId(shortAppId)).Times(1);
1485
1486 EXPECT_CALL(desktopFileReaderFactory, createInstance(_, _)).Times(1);
1487
1488@@ -231,7 +234,7 @@
1489 .Times(1)
1490 .WillOnce(Return(first_cmdLine));
1491
1492- ON_CALL(appController,appIdHasProcessId(_,_)).WillByDefault(Return(false));
1493+ ON_CALL(*taskController,appIdHasProcessId(_,_)).WillByDefault(Return(false));
1494
1495 EXPECT_CALL(procInfo,command_line(second_procId))
1496 .Times(1)
1497@@ -271,7 +274,7 @@
1498
1499 ON_CALL(procInfo,command_line(_)).WillByDefault(Return(a_cmd));
1500
1501- ON_CALL(appController,appIdHasProcessId(_,_)).WillByDefault(Return(false));
1502+ ON_CALL(*taskController,appIdHasProcessId(_,_)).WillByDefault(Return(false));
1503
1504 bool authed = true;
1505
1506@@ -293,7 +296,7 @@
1507 using namespace ::testing;
1508 QString appId("sideStage");
1509
1510- EXPECT_CALL(appController, findDesktopFileForAppId(appId)).Times(1);
1511+ EXPECT_CALL(*taskController, findDesktopFileForAppId(appId)).Times(1);
1512
1513 auto mockDesktopFileReader = new NiceMock<MockDesktopFileReader>(appId, QFileInfo());
1514 ON_CALL(*mockDesktopFileReader, loaded()).WillByDefault(Return(true));
1515@@ -320,7 +323,7 @@
1516
1517 ON_CALL(procInfo,command_line(_)).WillByDefault(Return(a_cmd));
1518
1519- ON_CALL(appController,appIdHasProcessId(_,_)).WillByDefault(Return(false));
1520+ ON_CALL(*taskController,appIdHasProcessId(_,_)).WillByDefault(Return(false));
1521
1522 bool authed = true;
1523
1524@@ -349,7 +352,7 @@
1525 FakeMirSurface *aSurface = new FakeMirSurface;
1526
1527 ON_CALL(procInfo, command_line(_)).WillByDefault(Return(a_cmd));
1528- ON_CALL(appController, appIdHasProcessId(_,_)).WillByDefault(Return(false));
1529+ ON_CALL(*taskController, appIdHasProcessId(_,_)).WillByDefault(Return(false));
1530
1531 bool authed = true;
1532
1533@@ -381,7 +384,7 @@
1534 .Times(1)
1535 .WillOnce(Return(cmdLine));
1536
1537- ON_CALL(appController,appIdHasProcessId(_,_)).WillByDefault(Return(false));
1538+ ON_CALL(*taskController,appIdHasProcessId(_,_)).WillByDefault(Return(false));
1539
1540 bool authed = true;
1541
1542@@ -419,7 +422,7 @@
1543 .Times(1)
1544 .WillOnce(Return(first_cmdLine));
1545
1546- ON_CALL(appController,appIdHasProcessId(_,_)).WillByDefault(Return(false));
1547+ ON_CALL(*taskController,appIdHasProcessId(_,_)).WillByDefault(Return(false));
1548
1549 EXPECT_CALL(procInfo,command_line(second_procId))
1550 .Times(1)
1551@@ -469,7 +472,7 @@
1552
1553 ON_CALL(desktopFileReaderFactory, createInstance(appId, _)).WillByDefault(Return(mockDesktopFileReader));
1554
1555- EXPECT_CALL(appController, startApplicationWithAppIdAndArgs(appId, _))
1556+ EXPECT_CALL(*taskController, start(appId, _))
1557 .Times(1)
1558 .WillOnce(Return(true));
1559
1560@@ -667,7 +670,7 @@
1561
1562 ON_CALL(desktopFileReaderFactory, createInstance(appId, _)).WillByDefault(Return(mockDesktopFileReader));
1563
1564- ON_CALL(appController, startApplicationWithAppIdAndArgs(appId, _))
1565+ ON_CALL(*taskController, start(appId, _))
1566 .WillByDefault(Invoke(
1567 [&](const QString &appId, Unused) {
1568 applicationManager.onProcessStarting(appId);
1569@@ -746,7 +749,7 @@
1570
1571 ON_CALL(desktopFileReaderFactory, createInstance(appId, _)).WillByDefault(Return(mockDesktopFileReader));
1572
1573- EXPECT_CALL(appController, startApplicationWithAppIdAndArgs(appId, _))
1574+ EXPECT_CALL(*taskController, start(appId, _))
1575 .Times(1)
1576 .WillOnce(Return(true));
1577
1578@@ -784,7 +787,7 @@
1579
1580 ON_CALL(desktopFileReaderFactory, createInstance(appId, _)).WillByDefault(Return(mockDesktopFileReader));
1581
1582- EXPECT_CALL(appController, startApplicationWithAppIdAndArgs(appId, _))
1583+ EXPECT_CALL(*taskController, start(appId, _))
1584 .Times(1)
1585 .WillOnce(Return(true));
1586
1587@@ -828,7 +831,7 @@
1588
1589 ON_CALL(desktopFileReaderFactory, createInstance(appId, _)).WillByDefault(Return(mockDesktopFileReader));
1590
1591- EXPECT_CALL(appController, startApplicationWithAppIdAndArgs(appId, _))
1592+ EXPECT_CALL(*taskController, start(appId, _))
1593 .Times(1)
1594 .WillOnce(Return(true));
1595
1596@@ -858,16 +861,18 @@
1597 {
1598 using namespace ::testing;
1599 const QString appId("testAppId");
1600+ const QString desktopFilePath("testAppId.desktop");
1601 const pid_t procId = 5551;
1602
1603 // Set up Mocks & signal watcher
1604 auto mockDesktopFileReader = new NiceMock<MockDesktopFileReader>(appId, QFileInfo());
1605 ON_CALL(*mockDesktopFileReader, loaded()).WillByDefault(Return(true));
1606 ON_CALL(*mockDesktopFileReader, appId()).WillByDefault(Return(appId));
1607+ ON_CALL(*mockDesktopFileReader, file()).WillByDefault(Return(desktopFilePath));
1608
1609 ON_CALL(desktopFileReaderFactory, createInstance(appId, _)).WillByDefault(Return(mockDesktopFileReader));
1610
1611- EXPECT_CALL(appController, startApplicationWithAppIdAndArgs(appId, _))
1612+ EXPECT_CALL(*taskController, start(appId, _))
1613 .Times(1)
1614 .WillOnce(Return(true));
1615
1616@@ -881,6 +886,10 @@
1617 QSignalSpy countSpy(&applicationManager, SIGNAL(countChanged()));
1618 QSignalSpy removedSpy(&applicationManager, SIGNAL(applicationRemoved(const QString &)));
1619
1620+ EXPECT_CALL(*taskController, stop(appId))
1621+ .Times(1)
1622+ .WillOnce(Return(true));
1623+
1624 // Stop app
1625 applicationManager.stopApplication(appId);
1626
1627@@ -906,7 +915,7 @@
1628
1629 ON_CALL(desktopFileReaderFactory, createInstance(appId, _)).WillByDefault(Return(mockDesktopFileReader));
1630
1631- EXPECT_CALL(appController, startApplicationWithAppIdAndArgs(appId, _))
1632+ EXPECT_CALL(*taskController, start(appId, _))
1633 .Times(1)
1634 .WillOnce(Return(true));
1635
1636@@ -949,7 +958,7 @@
1637
1638 ON_CALL(desktopFileReaderFactory, createInstance(appId, _)).WillByDefault(Return(mockDesktopFileReader));
1639
1640- EXPECT_CALL(appController, startApplicationWithAppIdAndArgs(appId, _))
1641+ EXPECT_CALL(*taskController, start(appId, _))
1642 .Times(1)
1643 .WillOnce(Return(true));
1644
1645@@ -995,7 +1004,7 @@
1646
1647 ON_CALL(desktopFileReaderFactory, createInstance(appId, _)).WillByDefault(Return(mockDesktopFileReader));
1648
1649- EXPECT_CALL(appController, startApplicationWithAppIdAndArgs(appId, _))
1650+ EXPECT_CALL(*taskController, start(appId, _))
1651 .Times(1)
1652 .WillOnce(Return(true));
1653
1654@@ -1040,7 +1049,7 @@
1655
1656 ON_CALL(desktopFileReaderFactory, createInstance(appId, _)).WillByDefault(Return(mockDesktopFileReader));
1657
1658- EXPECT_CALL(appController, startApplicationWithAppIdAndArgs(appId, _))
1659+ EXPECT_CALL(*taskController, start(appId, _))
1660 .Times(1)
1661 .WillOnce(Return(true));
1662
1663@@ -1061,7 +1070,7 @@
1664 onSessionStopping(session);
1665
1666 // Upstart notifies of crashing / OOM killed app
1667- applicationManager.onProcessFailed(appId, false);
1668+ applicationManager.onProcessFailed(appId, TaskController::Error::APPLICATION_CRASHED);
1669
1670 // Upstart finally notifies the app stopped
1671 applicationManager.onProcessStopped(appId);
1672@@ -1091,7 +1100,7 @@
1673
1674 ON_CALL(desktopFileReaderFactory, createInstance(appId, _)).WillByDefault(Return(mockDesktopFileReader));
1675
1676- EXPECT_CALL(appController, startApplicationWithAppIdAndArgs(appId, _))
1677+ EXPECT_CALL(*taskController, start(appId, _))
1678 .Times(1)
1679 .WillOnce(Return(true));
1680
1681@@ -1116,7 +1125,7 @@
1682 onSessionStopping(session);
1683
1684 // Upstart notifies of crashing / OOM-killed app
1685- applicationManager.onProcessFailed(appId, false);
1686+ applicationManager.onProcessFailed(appId, TaskController::Error::APPLICATION_CRASHED);
1687
1688 EXPECT_EQ(0, focusSpy.count());
1689
1690@@ -1149,7 +1158,7 @@
1691
1692 ON_CALL(desktopFileReaderFactory, createInstance(appId, _)).WillByDefault(Return(mockDesktopFileReader));
1693
1694- EXPECT_CALL(appController, startApplicationWithAppIdAndArgs(appId, _))
1695+ EXPECT_CALL(*taskController, start(appId, _))
1696 .Times(1)
1697 .WillOnce(Return(true));
1698
1699@@ -1174,7 +1183,7 @@
1700 onSessionStopping(session);
1701
1702 // Upstart notifies of crashing app
1703- applicationManager.onProcessFailed(appId, true);
1704+ applicationManager.onProcessFailed(appId, TaskController::Error::APPLICATION_FAILED_TO_START);
1705
1706 EXPECT_EQ(focusSpy.count(), 0);
1707
1708@@ -1202,7 +1211,7 @@
1709
1710 ON_CALL(desktopFileReaderFactory, createInstance(appId, _)).WillByDefault(Return(mockDesktopFileReader));
1711
1712- EXPECT_CALL(appController, startApplicationWithAppIdAndArgs(appId, _))
1713+ EXPECT_CALL(*taskController, start(appId, _))
1714 .Times(1)
1715 .WillOnce(Return(true));
1716
1717@@ -1241,7 +1250,7 @@
1718
1719 ON_CALL(desktopFileReaderFactory, createInstance(appId, _)).WillByDefault(Return(mockDesktopFileReader));
1720
1721- EXPECT_CALL(appController, startApplicationWithAppIdAndArgs(appId, _))
1722+ EXPECT_CALL(*taskController, start(appId, _))
1723 .Times(1)
1724 .WillOnce(Return(true));
1725
1726@@ -1337,7 +1346,7 @@
1727
1728 ON_CALL(desktopFileReaderFactory, createInstance(appId, _)).WillByDefault(Return(mockDesktopFileReader));
1729
1730- EXPECT_CALL(appController, startApplicationWithAppIdAndArgs(appId, _))
1731+ EXPECT_CALL(*taskController, start(appId, _))
1732 .Times(1)
1733 .WillOnce(Return(true));
1734
1735@@ -1393,10 +1402,11 @@
1736 auto mockDesktopFileReader = new NiceMock<MockDesktopFileReader>(appId, QFileInfo());
1737 ON_CALL(*mockDesktopFileReader, loaded()).WillByDefault(Return(true));
1738 ON_CALL(*mockDesktopFileReader, appId()).WillByDefault(Return(appId));
1739+ ON_CALL(*mockDesktopFileReader, file()).WillByDefault(Return(appId + ".desktop"));
1740
1741 ON_CALL(desktopFileReaderFactory, createInstance(appId, _)).WillByDefault(Return(mockDesktopFileReader));
1742
1743- EXPECT_CALL(appController, startApplicationWithAppIdAndArgs(appId, _))
1744+ EXPECT_CALL(*taskController, start(appId, _))
1745 .Times(1)
1746 .WillOnce(Return(true));
1747
1748@@ -1407,55 +1417,23 @@
1749 applicationManager.authorizeSession(procId, authed);
1750 onSessionStarting(session);
1751
1752+ EXPECT_CALL(*taskController, stop(appId))
1753+ .Times(1)
1754+ .WillOnce(Return(true));
1755+
1756 applicationManager.stopApplication(appId);
1757
1758 QSignalSpy countSpy(&applicationManager, SIGNAL(countChanged()));
1759 QSignalSpy removedSpy(&applicationManager, SIGNAL(applicationRemoved(const QString &)));
1760
1761+ // the mir session always ends before upstart notifies the process has stopped
1762+ onSessionStopping(session);
1763+
1764 // Upstart notifies of stopping app
1765 applicationManager.onProcessStopped(appId);
1766
1767- EXPECT_EQ(countSpy.count(), 0);
1768- EXPECT_EQ(removedSpy.count(), 0);
1769-}
1770-
1771-/*
1772- * Test that when an application is stopped correctly by shell, the Mir Session stopped event is ignored
1773- */
1774-TEST_F(ApplicationManagerTests,shellStoppedApp_mirSessionStoppingEventIgnored)
1775-{
1776- using namespace ::testing;
1777- const QString appId("testAppId");
1778- const pid_t procId = 5551;
1779-
1780- // Set up Mocks & signal watcher
1781- auto mockDesktopFileReader = new NiceMock<MockDesktopFileReader>(appId, QFileInfo());
1782- ON_CALL(*mockDesktopFileReader, loaded()).WillByDefault(Return(true));
1783- ON_CALL(*mockDesktopFileReader, appId()).WillByDefault(Return(appId));
1784-
1785- ON_CALL(desktopFileReaderFactory, createInstance(appId, _)).WillByDefault(Return(mockDesktopFileReader));
1786-
1787- EXPECT_CALL(appController, startApplicationWithAppIdAndArgs(appId, _))
1788- .Times(1)
1789- .WillOnce(Return(true));
1790-
1791- applicationManager.startApplication(appId, ApplicationManager::NoFlag);
1792- applicationManager.onProcessStarting(appId);
1793- std::shared_ptr<mir::scene::Session> session = std::make_shared<MockSession>("", procId);
1794- bool authed = true;
1795- applicationManager.authorizeSession(procId, authed);
1796- onSessionStarting(session);
1797-
1798- applicationManager.stopApplication(appId);
1799-
1800- QSignalSpy countSpy(&applicationManager, SIGNAL(countChanged()));
1801- QSignalSpy removedSpy(&applicationManager, SIGNAL(applicationRemoved(const QString &)));
1802-
1803- // Mir notifies of stopping app/Session
1804- onSessionStopping(session);
1805-
1806- EXPECT_EQ(countSpy.count(), 0);
1807- EXPECT_EQ(removedSpy.count(), 0);
1808+ EXPECT_EQ(0, countSpy.count());
1809+ EXPECT_EQ(0, removedSpy.count());
1810 }
1811
1812 /*
1813@@ -1475,8 +1453,8 @@
1814 .Times(1)
1815 .WillOnce(Return(cmdLine));
1816
1817- ON_CALL(appController,appIdHasProcessId(procId1, appId)).WillByDefault(Return(true));
1818- ON_CALL(appController,appIdHasProcessId(procId2, _)).WillByDefault(Return(false));
1819+ ON_CALL(*taskController,appIdHasProcessId(appId, procId1)).WillByDefault(Return(true));
1820+ ON_CALL(*taskController,appIdHasProcessId(_, procId2)).WillByDefault(Return(false));
1821
1822 // Set up Mocks & signal watcher
1823 auto mockDesktopFileReader = new NiceMock<MockDesktopFileReader>(appId, QFileInfo());
1824@@ -1485,7 +1463,7 @@
1825
1826 ON_CALL(desktopFileReaderFactory, createInstance(appId, _)).WillByDefault(Return(mockDesktopFileReader));
1827
1828- EXPECT_CALL(appController, startApplicationWithAppIdAndArgs(appId, _))
1829+ EXPECT_CALL(*taskController, start(appId, _))
1830 .Times(1)
1831 .WillOnce(Return(true));
1832
1833@@ -1535,8 +1513,8 @@
1834 .Times(1)
1835 .WillOnce(Return(cmdLine));
1836
1837- ON_CALL(appController,appIdHasProcessId(procId1, appId)).WillByDefault(Return(true));
1838- ON_CALL(appController,appIdHasProcessId(procId2, _)).WillByDefault(Return(false));
1839+ ON_CALL(*taskController,appIdHasProcessId(appId, procId1)).WillByDefault(Return(true));
1840+ ON_CALL(*taskController,appIdHasProcessId(_, procId2)).WillByDefault(Return(false));
1841
1842 // Set up Mocks & signal watcher
1843 auto mockDesktopFileReader = new NiceMock<MockDesktopFileReader>(appId, QFileInfo());
1844@@ -1545,7 +1523,7 @@
1845
1846 ON_CALL(desktopFileReaderFactory, createInstance(appId, _)).WillByDefault(Return(mockDesktopFileReader));
1847
1848- EXPECT_CALL(appController, startApplicationWithAppIdAndArgs(appId, _))
1849+ EXPECT_CALL(*taskController, start(appId, _))
1850 .Times(1)
1851 .WillOnce(Return(true));
1852
1853@@ -1603,7 +1581,7 @@
1854
1855 ON_CALL(desktopFileReaderFactory, createInstance(appId, _)).WillByDefault(Return(mockDesktopFileReader));
1856
1857- EXPECT_CALL(appController, startApplicationWithAppIdAndArgs(appId, _))
1858+ EXPECT_CALL(*taskController, start(appId, _))
1859 .Times(1)
1860 .WillOnce(Return(true));
1861
1862@@ -1621,7 +1599,7 @@
1863 suspend(app);
1864
1865 onSessionStopping(session);
1866- applicationManager.onProcessFailed(appId, false);
1867+ applicationManager.onProcessFailed(appId, TaskController::Error::APPLICATION_CRASHED);
1868 applicationManager.onProcessStopped(appId);
1869
1870 EXPECT_EQ(Application::Stopped, app->state());
1871@@ -1642,14 +1620,32 @@
1872 TEST_F(ApplicationManagerTests, threadedScreenshot)
1873 {
1874 using namespace testing;
1875- const pid_t procId1 = 5551;
1876+ const QString appId("webapp");
1877+ const QString desktopFilePath("webapp.desktop");
1878+ const pid_t procId = 5551;
1879
1880 std::mutex mutex;
1881 std::condition_variable cv;
1882 bool done = false;
1883
1884- auto application = startApplication(procId1, "webapp");
1885- auto session = std::dynamic_pointer_cast<MockSession>(application->session()->session());
1886+ auto mockDesktopFileReader = new NiceMock<MockDesktopFileReader>(appId, QFileInfo());
1887+ ON_CALL(*mockDesktopFileReader, loaded()).WillByDefault(Return(true));
1888+ ON_CALL(*mockDesktopFileReader, appId()).WillByDefault(Return(appId));
1889+ ON_CALL(*mockDesktopFileReader, file()).WillByDefault(Return(desktopFilePath));
1890+
1891+ ON_CALL(desktopFileReaderFactory, createInstance(appId, _)).WillByDefault(Return(mockDesktopFileReader));
1892+
1893+ EXPECT_CALL(*taskController, start(appId, _))
1894+ .Times(1)
1895+ .WillOnce(Return(true));
1896+
1897+ applicationManager.startApplication(appId, ApplicationManager::NoFlag);
1898+ applicationManager.onProcessStarting(appId);
1899+ auto session = std::make_shared<MockSession>("", procId);
1900+ bool authed = true;
1901+ applicationManager.authorizeSession(procId, authed);
1902+ onSessionStarting(session);
1903+
1904 ON_CALL(*session, take_snapshot(_)).WillByDefault(Invoke(
1905 [&](mir::scene::SnapshotCallback const& callback)
1906 {
1907@@ -1675,7 +1671,7 @@
1908 ApplicationScreenshotProvider screenshotProvider(&applicationManager);
1909 QSize actualSize;
1910 QSize requestedSize;
1911- QString imageId("webapp/123456");
1912+ QString imageId(appId + "/123456");
1913 screenshotProvider.requestImage(imageId, &actualSize, requestedSize);
1914 }
1915
1916@@ -1685,7 +1681,11 @@
1917 EXPECT_TRUE(done);
1918 }
1919
1920- applicationManager.stopApplication(application->appId());
1921+ EXPECT_CALL(*taskController, stop(appId))
1922+ .Times(1)
1923+ .WillOnce(Return(true));
1924+
1925+ applicationManager.stopApplication(appId);
1926 }
1927
1928 /*
1929@@ -1751,7 +1751,7 @@
1930
1931 ON_CALL(desktopFileReaderFactory, createInstance(appId, _)).WillByDefault(Return(mockDesktopFileReader));
1932
1933- EXPECT_CALL(appController, startApplicationWithAppIdAndArgs(appId, _))
1934+ EXPECT_CALL(*taskController, start(appId, _))
1935 .Times(1)
1936 .WillOnce(Return(true));
1937
1938@@ -1819,7 +1819,7 @@
1939
1940 ON_CALL(desktopFileReaderFactory, createInstance(appId, _)).WillByDefault(Return(mockDesktopFileReader));
1941
1942- EXPECT_CALL(appController, startApplicationWithAppIdAndArgs(appId, _))
1943+ EXPECT_CALL(*taskController, start(appId, _))
1944 .Times(1)
1945 .WillOnce(Return(true));
1946
1947@@ -1858,10 +1858,11 @@
1948 auto mockDesktopFileReader = new NiceMock<MockDesktopFileReader>(appId, QFileInfo());
1949 ON_CALL(*mockDesktopFileReader, loaded()).WillByDefault(Return(true));
1950 ON_CALL(*mockDesktopFileReader, appId()).WillByDefault(Return(appId));
1951+ ON_CALL(*mockDesktopFileReader, file()).WillByDefault(Return(appId + ".desktop"));
1952
1953 ON_CALL(desktopFileReaderFactory, createInstance(appId, _)).WillByDefault(Return(mockDesktopFileReader));
1954
1955- EXPECT_CALL(appController, startApplicationWithAppIdAndArgs(appId, _))
1956+ EXPECT_CALL(*taskController, start(appId, _))
1957 .Times(1)
1958 .WillOnce(Return(true));
1959
1960@@ -1877,6 +1878,10 @@
1961 QDir dir(path);
1962 dir.mkpath(path);
1963
1964+ EXPECT_CALL(*taskController, stop(appId))
1965+ .Times(1)
1966+ .WillOnce(Return(true));
1967+
1968 // Stop app
1969 applicationManager.stopApplication(appId);
1970
1971@@ -1900,7 +1905,7 @@
1972
1973 ON_CALL(desktopFileReaderFactory, createInstance(appId, _)).WillByDefault(Return(mockDesktopFileReader));
1974
1975- EXPECT_CALL(appController, startApplicationWithAppIdAndArgs(appId, _))
1976+ EXPECT_CALL(*taskController, start(appId, _))
1977 .Times(1)
1978 .WillOnce(Return(true));
1979
1980@@ -1925,7 +1930,7 @@
1981 // Report app crash
1982 onSessionStopping(session);
1983 // Upstart notifies of **crashing** app
1984- applicationManager.onProcessFailed(appId, true);
1985+ applicationManager.onProcessFailed(appId, TaskController::Error::APPLICATION_FAILED_TO_START);
1986 applicationManager.onProcessStopped(appId);
1987
1988 EXPECT_EQ(0, applicationManager.count());
1989@@ -1948,7 +1953,7 @@
1990
1991 ON_CALL(desktopFileReaderFactory, createInstance(appId, _)).WillByDefault(Return(mockDesktopFileReader));
1992
1993- EXPECT_CALL(appController, startApplicationWithAppIdAndArgs(appId, _))
1994+ EXPECT_CALL(*taskController, start(appId, _))
1995 .Times(1)
1996 .WillOnce(Return(true));
1997
1998@@ -2015,13 +2020,42 @@
1999
2000 const QString appId("testAppId");
2001 quint64 procId = 5551;
2002- Application* app = startApplication(procId, appId);
2003+
2004+ auto mockDesktopFileReader = new NiceMock<MockDesktopFileReader>(appId, QFileInfo());
2005+ ON_CALL(*mockDesktopFileReader, loaded()).WillByDefault(Return(true));
2006+ ON_CALL(*mockDesktopFileReader, appId()).WillByDefault(Return(appId));
2007+ ON_CALL(*mockDesktopFileReader, file()).WillByDefault(Return(appId + ".desktop"));
2008+
2009+ ON_CALL(desktopFileReaderFactory, createInstance(appId, _)).WillByDefault(Return(mockDesktopFileReader));
2010+
2011+ EXPECT_CALL(*taskController, start(appId, _))
2012+ .Times(1)
2013+ .WillOnce(Return(true));
2014+
2015+ auto app = applicationManager.startApplication(appId, ApplicationManager::NoFlag);
2016+ applicationManager.onProcessStarting(appId);
2017+ std::shared_ptr<mir::scene::Session> session = std::make_shared<MockSession>("", procId);
2018+ bool authed = true;
2019+ applicationManager.authorizeSession(procId, authed);
2020+ onSessionStarting(session);
2021
2022 QSignalSpy spy(app, SIGNAL(destroyed(QObject*)));
2023 QObject::connect(app, &QObject::destroyed, app, [&qtApp](){ qtApp.quit(); });
2024
2025 // Stop app
2026+
2027+ EXPECT_CALL(*taskController, stop(appId))
2028+ .Times(1)
2029+ .WillOnce(Return(true));
2030+
2031 applicationManager.stopApplication(appId);
2032+
2033+ // the mir session always ends before upstart notifies the process has stopped
2034+ onSessionStopping(session);
2035+
2036+ // Upstart notifies of stopping app
2037+ applicationManager.onProcessStopped(appId);
2038+
2039 qtApp.exec();
2040 EXPECT_EQ(1, spy.count());
2041 }
2042@@ -2039,8 +2073,22 @@
2043
2044 const QString appId("testAppId");
2045 quint64 procId = 5551;
2046- Application* app = startApplication(procId, appId);
2047- std::shared_ptr<mir::scene::Session> session = app->session()->session();
2048+
2049+ ON_CALL(desktopFileReaderFactory, createInstance(appId, _))
2050+ .WillByDefault(Invoke(
2051+ [](const QString &appId, const QFileInfo&) { return new FakeDesktopFileReader(appId); }
2052+ ));
2053+
2054+ EXPECT_CALL(*taskController, start(appId, _))
2055+ .Times(1)
2056+ .WillOnce(Return(true));
2057+
2058+ auto app = applicationManager.startApplication(appId, ApplicationManager::NoFlag);
2059+ applicationManager.onProcessStarting(appId);
2060+ std::shared_ptr<mir::scene::Session> session = std::make_shared<MockSession>("", procId);
2061+ bool authed = true;
2062+ applicationManager.authorizeSession(procId, authed);
2063+ onSessionStarting(session);
2064
2065 FakeMirSurface *surface = new FakeMirSurface;
2066 onSessionCreatedSurface(session.get(), surface);
2067@@ -2049,30 +2097,37 @@
2068 EXPECT_EQ(Application::InternalState::Running, app->internalState());
2069
2070 // Stop app
2071+
2072+ Mock::VerifyAndClearExpectations(taskController);
2073+
2074+ EXPECT_CALL(*taskController, start(appId, _))
2075+ .Times(1)
2076+ .WillOnce(Return(true));
2077+
2078+ QSignalSpy closeRequestedSpy(surface, SIGNAL(closeRequested()));
2079+
2080 applicationManager.stopApplication(appId);
2081
2082+ // Asking ApplicationManager to stop the application just makes it request its surfaces to be
2083+ // closed
2084 EXPECT_EQ(Application::InternalState::Closing, app->internalState());
2085-
2086- // // Set up Mocks & signal watcher
2087- auto mockDesktopFileReader = new NiceMock<MockDesktopFileReader>(appId, QFileInfo());
2088- ON_CALL(*mockDesktopFileReader, loaded()).WillByDefault(Return(true));
2089- ON_CALL(*mockDesktopFileReader, appId()).WillByDefault(Return(appId));
2090- ON_CALL(desktopFileReaderFactory, createInstance(appId, _)).WillByDefault(Return(mockDesktopFileReader));
2091-
2092+ EXPECT_EQ(1, closeRequestedSpy.count());
2093+
2094+ // Trying to start a new instance of this app while we are still waiting for its current
2095+ // instance to end yields no immediate result. This command gets queued instead.
2096 EXPECT_EQ(nullptr, applicationManager.startApplication(appId, ApplicationManager::NoFlag));
2097
2098- QSignalSpy spy(&applicationManager, SIGNAL(applicationAdded(const QString&)));
2099+ QSignalSpy appAddedSpy(&applicationManager, SIGNAL(applicationAdded(const QString&)));
2100+
2101+ // Simulates that the application complied to the close() request and stopped itself
2102+ onSessionStopping(session);
2103 applicationManager.onProcessStopped(appId);
2104
2105- QObject::connect(&applicationManager, &ApplicationManager::applicationAdded,
2106- &applicationManager, [&qtApp, appId](const QString& startedApp) {
2107- if (startedApp == appId) {
2108- qtApp.quit();
2109- }
2110- });
2111+ // DeferredDelete is special: likes to be called out specifically or it won't come out
2112+ qtApp.sendPostedEvents(app, QEvent::DeferredDelete);
2113+ qtApp.sendPostedEvents();
2114
2115- qtApp.exec();
2116- EXPECT_EQ(1, spy.count());
2117+ EXPECT_EQ(1, appAddedSpy.count());
2118 }
2119
2120 /*
2121@@ -2116,8 +2171,21 @@
2122
2123 const QString appId("testAppId");
2124 quint64 procId = 5551;
2125- Application* app = startApplication(procId, appId);
2126- std::shared_ptr<mir::scene::Session> session = app->session()->session();
2127+
2128+ ON_CALL(procInfo,command_line(procId)).WillByDefault(Return(QByteArray("/usr/bin/testAppId")));
2129+ ON_CALL(*taskController,appIdHasProcessId(appId, procId)).WillByDefault(Return(true));
2130+
2131+ ON_CALL(desktopFileReaderFactory, createInstance(appId, _))
2132+ .WillByDefault(Invoke(
2133+ [](const QString &appId, const QFileInfo&) { return new FakeDesktopFileReader(appId); }
2134+ ));
2135+
2136+ auto app = applicationManager.startApplication(appId, ApplicationManager::NoFlag);
2137+ applicationManager.onProcessStarting(appId);
2138+ std::shared_ptr<mir::scene::Session> session = std::make_shared<MockSession>("", procId);
2139+ bool authed = true;
2140+ applicationManager.authorizeSession(procId, authed);
2141+ onSessionStarting(session);
2142
2143 FakeMirSurface *surface = new FakeMirSurface;
2144 onSessionCreatedSurface(session.get(), surface);
2145@@ -2125,13 +2193,41 @@
2146
2147 EXPECT_EQ(Application::InternalState::Running, app->internalState());
2148
2149- QSignalSpy spy(app, SIGNAL(destroyed(QObject*)));
2150- QObject::connect(app, &QObject::destroyed, app, [&qtApp](){ qtApp.quit(); });
2151+ QSharedPointer<FakeTimeSource> fakeTimeSource(new FakeTimeSource);
2152+ FakeTimer *fakeCloseTimer = new FakeTimer(fakeTimeSource);
2153+ app->setCloseTimer(fakeCloseTimer);
2154+
2155+ EXPECT_CALL(*taskController, stop(appId))
2156+ .Times(1)
2157+ .WillOnce(Invoke(
2158+ [this, session](const QString &appIdParam) {
2159+ // No point in emitting it as applicationManager is not connected to the taskController
2160+ // FIXME: Connect applicationManager to taskController so that we have a better test environment!
2161+ // In the meantime call the ApplicationManager method directly, emulating the missing
2162+ // signal-slot connection
2163+ // Q_EMIT taskController->processStopped(appIdParam);
2164+ onSessionStopping(session);
2165+ applicationManager.onProcessStopped(appIdParam);
2166+ return true;
2167+ }
2168+ ));
2169+
2170+ QSignalSpy appDestroyedSpy(app, SIGNAL(destroyed(QObject*)));
2171
2172 // Stop app
2173 applicationManager.stopApplication(appId);
2174- qtApp.exec();
2175- EXPECT_EQ(1, spy.count());
2176+
2177+ if (fakeCloseTimer->isRunning()) {
2178+ // Simulate that closeTimer has timed out.
2179+ fakeTimeSource->m_msecsSinceReference = fakeCloseTimer->nextTimeoutTime() + 1;
2180+ fakeCloseTimer->update();
2181+ }
2182+
2183+ // DeferredDelete is special: likes to be called out specifically or it won't come out
2184+ qtApp.sendPostedEvents(app, QEvent::DeferredDelete);
2185+ qtApp.sendPostedEvents();
2186+
2187+ EXPECT_EQ(1, appDestroyedSpy.count());
2188 }
2189
2190 /*
2191@@ -2195,7 +2291,7 @@
2192
2193 // Process failed
2194 onSessionStopping(session->session());
2195- applicationManager.onProcessFailed(appId, true);
2196+ applicationManager.onProcessFailed(appId, TaskController::Error::APPLICATION_FAILED_TO_START);
2197 applicationManager.onProcessStopped(appId);
2198 EXPECT_EQ(Application::InternalState::StoppedResumable, application->internalState());
2199
2200
2201=== modified file 'tests/modules/CMakeLists.txt'
2202--- tests/modules/CMakeLists.txt 2015-10-20 09:57:17 +0000
2203+++ tests/modules/CMakeLists.txt 2016-02-11 11:52:55 +0000
2204@@ -5,4 +5,3 @@
2205 add_subdirectory(SharedWakelock)
2206 add_subdirectory(SessionManager)
2207 add_subdirectory(SurfaceManager)
2208-add_subdirectory(TaskController)
2209
2210=== removed directory 'tests/modules/TaskController'
2211=== removed file 'tests/modules/TaskController/CMakeLists.txt'
2212--- tests/modules/TaskController/CMakeLists.txt 2016-02-11 11:52:55 +0000
2213+++ tests/modules/TaskController/CMakeLists.txt 1970-01-01 00:00:00 +0000
2214@@ -1,30 +0,0 @@
2215-set(
2216- TASK_CONTROLLER_TEST_SOURCES
2217- taskcontroller_test.cpp
2218- ${CMAKE_SOURCE_DIR}/src/common/debughelpers.cpp
2219-)
2220-
2221-include_directories(
2222- ${APPLICATION_API_INCLUDE_DIRS}
2223- ${CMAKE_SOURCE_DIR}/src/modules
2224- ${CMAKE_SOURCE_DIR}/tests/framework
2225- ${MIRSERVER_INCLUDE_DIRS}
2226-)
2227-
2228-add_executable(taskcontroller_test ${TASK_CONTROLLER_TEST_SOURCES})
2229-
2230-add_dependencies(taskcontroller_test qtmir-test-framework-static)
2231-
2232-target_link_libraries(
2233- taskcontroller_test
2234-
2235- unityapplicationplugin
2236-
2237- -L${CMAKE_BINARY_DIR}/tests/framework
2238- qtmir-test-framework-static
2239-
2240- ${GTEST_BOTH_LIBRARIES}
2241- ${GMOCK_LIBRARIES}
2242-)
2243-
2244-add_test(TaskController, taskcontroller_test)
2245
2246=== removed file 'tests/modules/TaskController/taskcontroller_test.cpp'
2247--- tests/modules/TaskController/taskcontroller_test.cpp 2015-08-11 12:08:32 +0000
2248+++ tests/modules/TaskController/taskcontroller_test.cpp 1970-01-01 00:00:00 +0000
2249@@ -1,95 +0,0 @@
2250-/*
2251- * Copyright (C) 2013-2015 Canonical, Ltd.
2252- *
2253- * This program is free software: you can redistribute it and/or modify it under
2254- * the terms of the GNU Lesser General Public License version 3, as published by
2255- * the Free Software Foundation.
2256- *
2257- * This program is distributed in the hope that it will be useful, but WITHOUT
2258- * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
2259- * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2260- * Lesser General Public License for more details.
2261- *
2262- * You should have received a copy of the GNU Lesser General Public License
2263- * along with this program. If not, see <http://www.gnu.org/licenses/>.
2264- */
2265-
2266-#include <Unity/Application/taskcontroller.h>
2267-#include <Unity/Application/desktopfilereader.h>
2268-#include <Unity/Application/application.h>
2269-
2270-#include "mock_desktop_file_reader.h"
2271-
2272-#include <gmock/gmock.h>
2273-#include <gtest/gtest.h>
2274-
2275-namespace
2276-{
2277-using namespace qtmir;
2278-
2279-struct TriggerableApplicationController : public ApplicationController
2280-{
2281- void triggerApplicationStarted(const QString& appId)
2282- {
2283- Q_EMIT applicationStarted(appId);
2284- }
2285-
2286- void triggerApplicationStopped(const QString& appId)
2287- {
2288- Q_EMIT applicationStopped(appId);
2289- }
2290-
2291- void triggerApplicationFocusRequest(const QString& appId)
2292- {
2293- Q_EMIT applicationFocusRequest(appId);
2294- }
2295-
2296- MOCK_METHOD1(primaryPidForAppId, pid_t (const QString&));
2297- MOCK_METHOD2(appIdHasProcessId, bool(pid_t, const QString&));
2298- MOCK_CONST_METHOD1(findDesktopFileForAppId, QFileInfo(const QString &appId));
2299-
2300- MOCK_METHOD1(stopApplicationWithAppId, bool(const QString&));
2301- MOCK_METHOD2(startApplicationWithAppIdAndArgs, bool(const QString&, const QStringList&));
2302- MOCK_METHOD1(pauseApplicationWithAppId, bool(const QString&));
2303- MOCK_METHOD1(resumeApplicationWithAppId, bool(const QString&));
2304-};
2305-}
2306-
2307-TEST(TaskController, startingAnApplicationCallsCorrectlyIntoApplicationController)
2308-{
2309- using namespace ::testing;
2310-
2311- const QString appId{"com.canonical.does.not.exist"};
2312-
2313- testing::NiceMock<TriggerableApplicationController> appController;
2314- QSharedPointer<TriggerableApplicationController> appControllerPtr(
2315- &appController,
2316- [](ApplicationController*){});
2317-
2318- EXPECT_CALL(appController, startApplicationWithAppIdAndArgs(appId, QStringList())).Times(1).WillRepeatedly(Return(true));
2319-
2320- TaskController taskController(nullptr,
2321- appControllerPtr);
2322-
2323- taskController.start(appId, QStringList());
2324-}
2325-
2326-TEST(TaskController, stoppingAnApplicationCallsCorrectlyIntoApplicationController)
2327-{
2328- using namespace ::testing;
2329-
2330- const QString appId{"com.canonical.does.not.exist"};
2331-
2332- testing::NiceMock<TriggerableApplicationController> appController;
2333- QSharedPointer<TriggerableApplicationController> appControllerPtr(
2334- &appController,
2335- [](ApplicationController*){});
2336-
2337- EXPECT_CALL(appController, stopApplicationWithAppId(appId)).Times(1).WillRepeatedly(Return(true));
2338-
2339- TaskController taskController(nullptr,
2340- appControllerPtr);
2341-
2342- taskController.stop(appId);
2343-}
2344-

Subscribers

People subscribed via source and target branches