Merge lp:~gerboland/unity-mir/shortAppIds-0.1.9 into lp:unity-mir
- shortAppIds-0.1.9
- Merge into trunk
Status: | Merged | ||||
---|---|---|---|---|---|
Merged at revision: | 220 | ||||
Proposed branch: | lp:~gerboland/unity-mir/shortAppIds-0.1.9 | ||||
Merge into: | lp:unity-mir | ||||
Diff against target: |
903 lines (+312/-156) 14 files modified
src/modules/Unity/Application/application.cpp (+10/-2) src/modules/Unity/Application/application.h (+2/-0) src/modules/Unity/Application/application_manager.cpp (+55/-14) src/modules/Unity/Application/applicationcontroller.h (+3/-0) src/modules/Unity/Application/desktopfilereader.cpp (+6/-47) src/modules/Unity/Application/desktopfilereader.h (+2/-5) src/modules/Unity/Application/taskcontroller.cpp (+5/-0) src/modules/Unity/Application/taskcontroller.h (+1/-0) src/modules/Unity/Application/upstart/applicationcontroller.cpp (+92/-10) src/modules/Unity/Application/upstart/applicationcontroller.h (+7/-5) tests/application_manager_test.cpp (+85/-3) tests/mock_application_controller.h (+11/-0) tests/mock_desktop_file_reader.h (+31/-70) tests/taskcontroller_test.cpp (+2/-0) |
||||
To merge this branch: | bzr merge lp:~gerboland/unity-mir/shortAppIds-0.1.9 | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Michael Zanetti (community) | Approve | ||
PS Jenkins bot (community) | continuous-integration | Approve | |
Review via email: mp+219377@code.launchpad.net |
Commit message
Add support for short appIds
Shells should use only short AppIds (i.e. appId without the version string). In order to support this, needed to
- slightly decouple appId from the desktop file path, now need to ask the ApplicationCont
- DesktopFileReader now just a dumb file reader
- in the upstart ApplicationCont
- in ApplicationManager, to ease transition, have startApplication support both long & short appIds. But otherwise it uses short appIds only.
Description of the change
Add support for short appIds
Shells should use only short AppIds (i.e. appId without the version string). In order to support this, needed to
- slightly decouple appId from the desktop file path, now need to ask the ApplicationCont
- DesktopFileReader now just a dumb file reader
- in the upstart ApplicationCont
- in ApplicationManager, to ease transition, have startApplication support both long & short appIds. But otherwise it uses short appIds only.
- 228. By Gerry Boland
-
Remove unused header
PS Jenkins bot (ps-jenkins) wrote : | # |
Michael Zanetti (mzanetti) wrote : | # |
changelog please
Michael Zanetti (mzanetti) wrote : | # |
err... checklist... sorry
Gerry Boland (gerboland) wrote : | # |
Checklist:
* Are there any related MPs required for this MP to build/function as expected? Please list.
lp:~mzanetti/unity8/support-short-appid-in-gsettings
* 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
Michael Zanetti (mzanetti) wrote : | # |
74 + if (desktopFileNam
75 + appId = toShortAppIdIfP
76 + } else {
77 + appId = toShortAppIdIfP
78 + }
can there be .desktop files not ending with .desktop?
desktopFileName
Gerry Boland (gerboland) wrote : | # |
> can there be .desktop files not ending with .desktop?
Really old legacy support for --desktop_
> desktopFileName
Oh that's nicer, thanks!
Michael Zanetti (mzanetti) wrote : | # |
* Did you perform an exploratory manual test run of the code change and any related functionality?
Yes
* Did CI run pass? If not, please explain why.
Yes
- 229. By Gerry Boland
-
Correction to "appId guess from desktop file name" code (thanks for suggestion mzanetti)
- 230. By Gerry Boland
-
Test appId guess from desktop file name
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:230
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 231. By Gerry Boland
-
Extra test for long appId, fix bug
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:231
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Michael Zanetti (mzanetti) wrote : | # |
after installing this from silo 005, launching settings through the indicators seems broken.
Michael Zanetti (mzanetti) wrote : | # |
go to music scope, open a song's preview and click on "play in music app". doesn't seem to work any more either.
- 232. By Gerry Boland
-
Possible fix for bug where if app updated while running, need to refer to it by old long-appId, not short appId
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:232
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Michael Zanetti (mzanetti) wrote : | # |
Launching accounts from system settings app seems broken:
ApplicationManager REJECTED connection from app with pid 4025 as desktop_file_hint file not found
- 233. By Gerry Boland
-
Fix shortening of appId - no need to deref pointer
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:233
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 234. By Gerry Boland
-
Fix typo breaking apps launching via command line
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:234
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 235. By Gerry Boland
-
Have AppMan invokable methods gracefully handle long appIds. Do not re-create new Application for existing app
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:235
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Michael Zanetti (mzanetti) wrote : | # |
Ok. looking good. all test plans passing.
* Did you perform an exploratory manual test run of the code change and any related functionality?
Yes
* Did CI run pass? If not, please explain why.
it did!
Preview Diff
1 | === modified file 'src/modules/Unity/Application/application.cpp' |
2 | --- src/modules/Unity/Application/application.cpp 2014-04-15 14:31:02 +0000 |
3 | +++ src/modules/Unity/Application/application.cpp 2014-05-16 12:20:01 +0000 |
4 | @@ -52,6 +52,9 @@ |
5 | |
6 | m_suspendTimer->setSingleShot(true); |
7 | connect(m_suspendTimer, SIGNAL(timeout()), this, SLOT(suspend())); |
8 | + |
9 | + // FIXME(greyback) need to save long appId internally until upstart-app-launch can hide it from us |
10 | + m_longAppId = desktopFileReader->file().remove(QRegExp(".desktop$")).split('/').last(); |
11 | } |
12 | |
13 | Application::~Application() |
14 | @@ -276,13 +279,13 @@ |
15 | void Application::suspend() |
16 | { |
17 | DLOG("Application::suspend (this=%p)", this); |
18 | - m_taskController->suspend(appId()); |
19 | + m_taskController->suspend(longAppId()); |
20 | } |
21 | |
22 | void Application::resume() |
23 | { |
24 | DLOG("Application::resume (this=%p)", this); |
25 | - m_taskController->resume(appId()); |
26 | + m_taskController->resume(longAppId()); |
27 | } |
28 | |
29 | void Application::respawn() |
30 | @@ -291,4 +294,9 @@ |
31 | m_taskController->start(appId(), m_arguments); |
32 | } |
33 | |
34 | +QString Application::longAppId() const |
35 | +{ |
36 | + return m_longAppId; |
37 | +} |
38 | + |
39 | } // namespace unitymir |
40 | |
41 | === modified file 'src/modules/Unity/Application/application.h' |
42 | --- src/modules/Unity/Application/application.h 2014-04-15 14:31:02 +0000 |
43 | +++ src/modules/Unity/Application/application.h 2014-05-16 12:20:01 +0000 |
44 | @@ -89,6 +89,7 @@ |
45 | void visibleChanged(); |
46 | |
47 | private: |
48 | + QString longAppId() const; |
49 | void setPid(pid_t pid); |
50 | void setState(State state); |
51 | void setFocused(bool focus); |
52 | @@ -98,6 +99,7 @@ |
53 | |
54 | QSharedPointer<TaskController> m_taskController; |
55 | DesktopFileReader* m_desktopData; |
56 | + QString m_longAppId; |
57 | qint64 m_pid; |
58 | Stage m_stage; |
59 | State m_state; |
60 | |
61 | === modified file 'src/modules/Unity/Application/application_manager.cpp' |
62 | --- src/modules/Unity/Application/application_manager.cpp 2014-04-15 14:31:02 +0000 |
63 | +++ src/modules/Unity/Application/application_manager.cpp 2014-05-16 12:20:01 +0000 |
64 | @@ -76,6 +76,17 @@ |
65 | ); |
66 | } |
67 | |
68 | +// FIXME: To be removed once shell has fully adopted short appIds!! |
69 | +QString toShortAppIdIfPossible(const QString &appId) { |
70 | + QRegExp longAppIdMask("[a-z0-9][a-z0-9+.-]+_[a-zA-Z0-9+.-]+_[0-9][a-zA-Z0-9.+:~-]*"); |
71 | + if (longAppIdMask.exactMatch(appId)) { |
72 | + LOG("WARNING: long App ID encountered: %s", qPrintable(appId)); |
73 | + // input string a long AppId, chop the version string off the end |
74 | + QStringList parts = appId.split("_"); |
75 | + return QString("%1_%2").arg(parts.first()).arg(parts.at(1)); |
76 | + } |
77 | + return appId; |
78 | +} |
79 | |
80 | void connectToSessionListener(ApplicationManager * manager, SessionListener * listener) |
81 | { |
82 | @@ -262,8 +273,10 @@ |
83 | return m_applications.at(index); |
84 | } |
85 | |
86 | -Application* ApplicationManager::findApplication(const QString &appId) const |
87 | +Application* ApplicationManager::findApplication(const QString &inputAppId) const |
88 | { |
89 | + const QString appId = toShortAppIdIfPossible(inputAppId); |
90 | + |
91 | for (Application *app : m_applications) { |
92 | if (app->appId() == appId) { |
93 | return app; |
94 | @@ -272,8 +285,10 @@ |
95 | return nullptr; |
96 | } |
97 | |
98 | -bool ApplicationManager::requestFocusApplication(const QString &appId) |
99 | +bool ApplicationManager::requestFocusApplication(const QString &inputAppId) |
100 | { |
101 | + const QString appId = toShortAppIdIfPossible(inputAppId); |
102 | + |
103 | DLOG("ApplicationManager::requestFocusApplication (this=%p, appId=%s)", this, qPrintable(appId)); |
104 | Application *application = findApplication(appId); |
105 | |
106 | @@ -355,8 +370,10 @@ |
107 | application->setState(Application::Running); |
108 | } |
109 | |
110 | -bool ApplicationManager::focusApplication(const QString &appId) |
111 | +bool ApplicationManager::focusApplication(const QString &inputAppId) |
112 | { |
113 | + const QString appId = toShortAppIdIfPossible(inputAppId); |
114 | + |
115 | Application *application = findApplication(appId); |
116 | DLOG("ApplicationManager::focusApplication (this=%p, application=%p, appId=%s)", this, application, qPrintable(appId)); |
117 | |
118 | @@ -412,9 +429,26 @@ |
119 | return startApplication(appId, NoFlag, arguments); |
120 | } |
121 | |
122 | -Application *ApplicationManager::startApplication(const QString &appId, ExecFlags flags, |
123 | +/** |
124 | + * @brief ApplicationManager::startApplication launches an application identified by an "application id" or appId. |
125 | + * |
126 | + * Note: due to an implementation detail, appIds come in two forms: |
127 | + * * long appId: $(click_package)_$(application)_$(version) |
128 | + * * short appId: $(click_package)_$(application) |
129 | + * It is expected that the shell uses _only_ short appIds (but long appIds are accepted by this method for legacy |
130 | + * reasons - but be warned, this ability will be removed) |
131 | + * |
132 | + * Unless stated otherwise, we always use short appIds in this API. |
133 | + * |
134 | + * @param inputAppId AppId of application to launch (long appId supported) |
135 | + * @param flags Shell specific flags to modify the initial state of the application |
136 | + * @param arguments Command line arguments to pass to the application to be launched |
137 | + * @return Pointer to Application object representing the launched process |
138 | + */ |
139 | +Application *ApplicationManager::startApplication(const QString &inputAppId, ExecFlags flags, |
140 | const QStringList &arguments) |
141 | { |
142 | + QString appId = toShortAppIdIfPossible(inputAppId); |
143 | DLOG("ApplicationManager::startApplication (this=%p, appId=%s)", this, qPrintable(appId)); |
144 | |
145 | if (!m_taskController->start(appId, arguments)) { |
146 | @@ -425,15 +459,15 @@ |
147 | { |
148 | Application * application = findApplication(appId); |
149 | if (application) { |
150 | - DLOG("ApplicationManager::startApplication - application already " |
151 | - "exists: (this=%p, app=%p, appId=%s)", |
152 | + DLOG("ApplicationManager::startApplication - application already exists: (this=%p, app=%p, appId=%s)", |
153 | this, application, qPrintable(appId)); |
154 | + return application; |
155 | } |
156 | } |
157 | |
158 | Application* application = new Application( |
159 | m_taskController, |
160 | - m_desktopFileReaderFactory->createInstanceForAppId(appId), |
161 | + m_desktopFileReaderFactory->createInstance(appId, m_taskController->findDesktopFileForAppId(appId)), |
162 | Application::Starting, |
163 | arguments, |
164 | this); |
165 | @@ -467,7 +501,7 @@ |
166 | if (!application) { // if shell did not start this application, but upstart did |
167 | application = new Application( |
168 | m_taskController, |
169 | - m_desktopFileReaderFactory->createInstanceForAppId(appId), |
170 | + m_desktopFileReaderFactory->createInstance(appId, m_taskController->findDesktopFileForAppId(appId)), |
171 | Application::Starting, |
172 | QStringList(), this); |
173 | if (!application->isValid()) { |
174 | @@ -489,8 +523,10 @@ |
175 | } |
176 | } |
177 | |
178 | -bool ApplicationManager::stopApplication(const QString &appId) |
179 | +bool ApplicationManager::stopApplication(const QString &inputAppId) |
180 | { |
181 | + const QString appId = toShortAppIdIfPossible(inputAppId); |
182 | + |
183 | Application *application = findApplication(appId); |
184 | DLOG("ApplicationManager::stopApplication (this=%p, application=%p, appId=%s)", this, application, qPrintable(appId)); |
185 | |
186 | @@ -504,7 +540,7 @@ |
187 | remove(application); |
188 | m_dbusWindowStack->WindowDestroyed(0, application->appId()); |
189 | |
190 | - bool result = m_taskController->stop(application->appId()); |
191 | + bool result = m_taskController->stop(application->longAppId()); |
192 | |
193 | LOG_IF(result == false, "FAILED to ask Upstart to stop application '%s'", qPrintable(application->appId())); |
194 | |
195 | @@ -521,8 +557,10 @@ |
196 | return result; |
197 | } |
198 | |
199 | -bool ApplicationManager::updateScreenshot(const QString &appId) |
200 | +bool ApplicationManager::updateScreenshot(const QString &inputAppId) |
201 | { |
202 | + const QString appId = toShortAppIdIfPossible(inputAppId); |
203 | + |
204 | Application *application = findApplication(appId); |
205 | |
206 | if (!application) { |
207 | @@ -642,7 +680,7 @@ |
208 | |
209 | for (Application *app : m_applications) { |
210 | if (app->state() == Application::Starting |
211 | - && m_taskController->appIdHasProcessId(app->appId(), pid)) { |
212 | + && m_taskController->appIdHasProcessId(app->longAppId(), pid)) { |
213 | app->setPid(pid); |
214 | DLOG("ApplicationManager::authorizeSession - connecting: application=%p and pid=%lld", app, pid); |
215 | authorized = true; |
216 | @@ -678,13 +716,16 @@ |
217 | |
218 | DLOG("Process supplied desktop_file_hint, loading '%s'", desktopFileName.get().toLatin1().data()); |
219 | |
220 | + // Guess appId from the desktop file hint |
221 | + QString appId = toShortAppIdIfPossible(desktopFileName.get().remove(QRegExp(".desktop$")).split('/').last()); |
222 | + |
223 | // FIXME: right now we support --desktop_file_hint=appId for historical reasons. So let's try that in |
224 | // case we didn't get an existing .desktop file path |
225 | DesktopFileReader* desktopData; |
226 | if (QFileInfo(desktopFileName.get()).exists()) { |
227 | - desktopData = m_desktopFileReaderFactory->createInstanceForDesktopFile(QFileInfo(desktopFileName.get())); |
228 | + desktopData = m_desktopFileReaderFactory->createInstance(appId, QFileInfo(desktopFileName.get())); |
229 | } else { |
230 | - desktopData = m_desktopFileReaderFactory->createInstanceForAppId(desktopFileName.get()); |
231 | + desktopData = m_desktopFileReaderFactory->createInstance(appId, m_taskController->findDesktopFileForAppId(appId)); |
232 | } |
233 | |
234 | if (!desktopData->loaded()) { |
235 | |
236 | === modified file 'src/modules/Unity/Application/applicationcontroller.h' |
237 | --- src/modules/Unity/Application/applicationcontroller.h 2014-02-28 16:51:31 +0000 |
238 | +++ src/modules/Unity/Application/applicationcontroller.h 2014-05-16 12:20:01 +0000 |
239 | @@ -21,6 +21,7 @@ |
240 | #include <QObject> |
241 | #include <QString> |
242 | #include <QStringList> |
243 | +#include <QFileInfo> |
244 | |
245 | namespace unitymir |
246 | { |
247 | @@ -47,6 +48,8 @@ |
248 | virtual bool stopApplicationWithAppId(const QString& appId) = 0; |
249 | virtual bool startApplicationWithAppIdAndArgs(const QString& appId, const QStringList& arguments) = 0; |
250 | |
251 | + virtual QFileInfo findDesktopFileForAppId(const QString &appId) const = 0; |
252 | + |
253 | Q_SIGNALS: |
254 | void applicationAboutToBeStarted(QString id); |
255 | void applicationStarted(QString id); |
256 | |
257 | === modified file 'src/modules/Unity/Application/desktopfilereader.cpp' |
258 | --- src/modules/Unity/Application/desktopfilereader.cpp 2014-02-28 16:51:31 +0000 |
259 | +++ src/modules/Unity/Application/desktopfilereader.cpp 2014-05-16 12:20:01 +0000 |
260 | @@ -22,8 +22,6 @@ |
261 | |
262 | // Qt |
263 | #include <QFile> |
264 | -#include <QDir> |
265 | -#include <QStandardPaths> |
266 | |
267 | namespace unitymir |
268 | { |
269 | @@ -36,38 +34,23 @@ |
270 | { |
271 | } |
272 | |
273 | -DesktopFileReader* DesktopFileReader::Factory::createInstanceForAppId(const QString& appId) |
274 | -{ |
275 | - return new DesktopFileReader(appId); |
276 | -} |
277 | - |
278 | -DesktopFileReader* DesktopFileReader::Factory::createInstanceForDesktopFile(const QFileInfo& fi) |
279 | -{ |
280 | - return new DesktopFileReader(fi); |
281 | +DesktopFileReader* DesktopFileReader::Factory::createInstance(const QString &appId, const QFileInfo& fi) |
282 | +{ |
283 | + return new DesktopFileReader(appId, fi); |
284 | } |
285 | |
286 | // Retrieves the size of an array at compile time. |
287 | #define ARRAY_SIZE(a) \ |
288 | ((sizeof(a) / sizeof(*(a))) / static_cast<size_t>(!(sizeof(a) % sizeof(*(a))))) |
289 | |
290 | -DesktopFileReader::DesktopFileReader(const QString &appId) |
291 | +DesktopFileReader::DesktopFileReader(const QString &appId, const QFileInfo &desktopFile) |
292 | : appId_(appId) |
293 | , entries_(DesktopFileReader::kNumberOfEntries, "") |
294 | { |
295 | - DLOG("DesktopFileReader::DesktopFileReader (this=%p, appId='%s')", this, appId.toLatin1().data()); |
296 | - DASSERT(appId != NULL); |
297 | - |
298 | - file_ = findDesktopFile(appId); |
299 | - loaded_ = loadDesktopFile(file_); |
300 | -} |
301 | - |
302 | -DesktopFileReader::DesktopFileReader(const QFileInfo &desktopFile) |
303 | - : entries_(DesktopFileReader::kNumberOfEntries, "") |
304 | -{ |
305 | - DLOG("DesktopFileReader::DesktopFileReader (this=%p, desktopFile='%s')", this, desktopFile.absoluteFilePath().toLatin1().data()); |
306 | + DLOG("DesktopFileReader::DesktopFileReader (this=%p, appId='%s', desktopFile='%s')", this, |
307 | + qPrintable(appId), qPrintable(desktopFile.absoluteFilePath())); |
308 | DASSERT(desktopFile.exists()); |
309 | |
310 | - appId_ = desktopFile.completeBaseName(); |
311 | file_ = desktopFile.absoluteFilePath(); |
312 | loaded_ = loadDesktopFile(file_); |
313 | } |
314 | @@ -78,30 +61,6 @@ |
315 | entries_.clear(); |
316 | } |
317 | |
318 | - |
319 | -QString DesktopFileReader::findDesktopFile(const QString &appId) const |
320 | -{ |
321 | - DLOG("DesktopFileReader::findDesktopFile (appId='%s')", appId.toLatin1().data()); |
322 | - |
323 | - int dashPos = -1; |
324 | - QString helper = appId; |
325 | - QString desktopFile; |
326 | - |
327 | - do { |
328 | - if (dashPos != -1) { |
329 | - helper = helper.replace(dashPos, 1, '/'); |
330 | - } |
331 | - |
332 | - desktopFile = QStandardPaths::locate(QStandardPaths::ApplicationsLocation, QString("%1.desktop").arg(helper)); |
333 | - if (!desktopFile.isEmpty()) return desktopFile; |
334 | - |
335 | - dashPos = helper.indexOf("-"); |
336 | - } while (dashPos != -1); |
337 | - |
338 | - return QString(); |
339 | -} |
340 | - |
341 | - |
342 | bool DesktopFileReader::loadDesktopFile(QString desktopFile) |
343 | { |
344 | DLOG("DesktopFileReader::loadDesktopFile (this=%p, desktopFile='%s')", |
345 | |
346 | === modified file 'src/modules/Unity/Application/desktopfilereader.h' |
347 | --- src/modules/Unity/Application/desktopfilereader.h 2014-02-28 16:51:31 +0000 |
348 | +++ src/modules/Unity/Application/desktopfilereader.h 2014-05-16 12:20:01 +0000 |
349 | @@ -35,8 +35,7 @@ |
350 | |
351 | Factory& operator=(const Factory&) = delete; |
352 | |
353 | - virtual DesktopFileReader* createInstanceForAppId(const QString& appId); |
354 | - virtual DesktopFileReader* createInstanceForDesktopFile(const QFileInfo& fi); |
355 | + virtual DesktopFileReader* createInstance(const QString &appId, const QFileInfo& fi); |
356 | }; |
357 | |
358 | virtual ~DesktopFileReader(); |
359 | @@ -50,13 +49,11 @@ |
360 | virtual QString path() const { return entries_[kPathIndex]; } |
361 | virtual QString stageHint() const { return entries_[kStageHintIndex]; } |
362 | virtual bool loaded() const { return loaded_; } |
363 | - virtual QString findDesktopFile(const QString &appId) const; |
364 | |
365 | protected: |
366 | friend class DesktopFileReaderFactory; |
367 | |
368 | - DesktopFileReader(const QString &appId); |
369 | - DesktopFileReader(const QFileInfo &desktopFile); |
370 | + DesktopFileReader(const QString &appId, const QFileInfo &desktopFile); |
371 | |
372 | private: |
373 | static const int kNameIndex = 0, |
374 | |
375 | === modified file 'src/modules/Unity/Application/taskcontroller.cpp' |
376 | --- src/modules/Unity/Application/taskcontroller.cpp 2014-02-28 16:51:31 +0000 |
377 | +++ src/modules/Unity/Application/taskcontroller.cpp 2014-05-16 12:20:01 +0000 |
378 | @@ -107,6 +107,11 @@ |
379 | return m_appController->appIdHasProcessId(pid, appId); |
380 | } |
381 | |
382 | +QFileInfo TaskController::findDesktopFileForAppId(const QString &appId) const |
383 | +{ |
384 | + return m_appController->findDesktopFileForAppId(appId); |
385 | +} |
386 | + |
387 | bool TaskController::suspend(const QString& appId) |
388 | { |
389 | DLOG("TaskController::suspend (this=%p, application=%p)", this, qPrintable(appId)); |
390 | |
391 | === modified file 'src/modules/Unity/Application/taskcontroller.h' |
392 | --- src/modules/Unity/Application/taskcontroller.h 2014-02-28 16:51:31 +0000 |
393 | +++ src/modules/Unity/Application/taskcontroller.h 2014-05-16 12:20:01 +0000 |
394 | @@ -45,6 +45,7 @@ |
395 | bool resume(const QString& appId); |
396 | |
397 | bool appIdHasProcessId(const QString& appId, const quint64 pid); |
398 | + QFileInfo findDesktopFileForAppId(const QString &appId) const; |
399 | |
400 | Q_SIGNALS: |
401 | void processStartReport(const QString& appId, const bool failure); |
402 | |
403 | === modified file 'src/modules/Unity/Application/upstart/applicationcontroller.cpp' |
404 | --- src/modules/Unity/Application/upstart/applicationcontroller.cpp 2014-04-16 17:45:59 +0000 |
405 | +++ src/modules/Unity/Application/upstart/applicationcontroller.cpp 2014-05-16 12:20:01 +0000 |
406 | @@ -20,6 +20,9 @@ |
407 | // unity-mir |
408 | #include <logging.h> |
409 | |
410 | +// Qt |
411 | +#include <QStandardPaths> |
412 | + |
413 | // upstart |
414 | extern "C" { |
415 | #include "upstart-app-launch.h" |
416 | @@ -40,33 +43,89 @@ |
417 | upstart_app_launch_app_failed_observer_t failureCallback = nullptr; |
418 | }; |
419 | |
420 | +namespace { |
421 | +/** |
422 | + * @brief toShortAppIdIfPossible |
423 | + * @param appId - any string that you think is an appId |
424 | + * @return if a valid appId was input, a shortened appId is returned, else returns the input string unaltered |
425 | + */ |
426 | +QString toShortAppIdIfPossible(const QString &appId) { |
427 | + gchar *package, *application; |
428 | + if (upstart_app_launch_app_id_parse(appId.toLatin1().constData(), &package, &application, nullptr)) { |
429 | + // is long appId, so assemble its short appId |
430 | + QString shortAppId = QString("%1_%2").arg(package).arg(application); |
431 | + g_free(package); |
432 | + g_free(application); |
433 | + return shortAppId; |
434 | + } else { |
435 | + return appId; |
436 | + } |
437 | +} |
438 | + |
439 | +/** |
440 | + * @brief toLongAppIdIfPossible |
441 | + * @param shortAppId - any string that you think is a short appId |
442 | + * @return if valid short appId was input, the corresponding long appId is returned. If a long appId was |
443 | + * entered, it is returned unchanged. Anything else is also returned unchanged. |
444 | + */ |
445 | +QString toLongAppIdIfPossible(const QString &shortAppId) { |
446 | + if (upstart_app_launch_app_id_parse(shortAppId.toLatin1().constData(), nullptr, nullptr, nullptr)) { |
447 | + // then we got a long appId after all, just return it |
448 | + return shortAppId; |
449 | + } else { |
450 | + // try to parse the string in the form "$package_$application" |
451 | + QRegExp shortAppIdMask("[a-z0-9][a-z0-9+.-]+_[a-zA-Z0-9+.-]+"); |
452 | + if (!shortAppIdMask.exactMatch(shortAppId)) { |
453 | + // input string not a short appId, so just return it unchanged |
454 | + return shortAppId; |
455 | + } |
456 | + |
457 | + // ask upstart for the long appId corresponding to this short appId |
458 | + QStringList parts = shortAppId.split("_"); |
459 | + gchar *longAppId; |
460 | + longAppId = upstart_app_launch_triplet_to_app_id(parts.first().toLatin1().constData(), |
461 | + parts.last().toLatin1().constData(), |
462 | + nullptr); |
463 | + if (longAppId == nullptr) { |
464 | + // was unable to construct a long appId from the short appId, return input unchanged |
465 | + return shortAppId; |
466 | + } else { |
467 | + QString appId(longAppId); |
468 | + g_free(longAppId); |
469 | + return appId; |
470 | + } |
471 | + } |
472 | +} |
473 | + |
474 | +} // namespace |
475 | + |
476 | ApplicationController::ApplicationController() |
477 | : unitymir::ApplicationController(), |
478 | impl(new Private()) |
479 | { |
480 | impl->preStartCallback = [](const gchar * appId, gpointer userData) { |
481 | auto thiz = static_cast<ApplicationController*>(userData); |
482 | - Q_EMIT(thiz->applicationAboutToBeStarted(appId)); |
483 | + Q_EMIT(thiz->applicationAboutToBeStarted(toShortAppIdIfPossible(appId))); |
484 | }; |
485 | |
486 | impl->startedCallback = [](const gchar * appId, gpointer userData) { |
487 | auto thiz = static_cast<ApplicationController*>(userData); |
488 | - Q_EMIT(thiz->applicationStarted(appId)); |
489 | + Q_EMIT(thiz->applicationStarted(toShortAppIdIfPossible(appId))); |
490 | }; |
491 | |
492 | impl->stopCallback = [](const gchar * appId, gpointer userData) { |
493 | auto thiz = static_cast<ApplicationController*>(userData); |
494 | - Q_EMIT(thiz->applicationStopped(appId)); |
495 | + Q_EMIT(thiz->applicationStopped(toShortAppIdIfPossible(appId))); |
496 | }; |
497 | |
498 | impl->focusCallback = [](const gchar * appId, gpointer userData) { |
499 | auto thiz = static_cast<ApplicationController*>(userData); |
500 | - Q_EMIT(thiz->applicationFocusRequest(appId)); |
501 | + Q_EMIT(thiz->applicationFocusRequest(toShortAppIdIfPossible(appId))); |
502 | }; |
503 | |
504 | impl->resumeCallback = [](const gchar * appId, gpointer userData) { |
505 | auto thiz = static_cast<ApplicationController*>(userData); |
506 | - Q_EMIT(thiz->applicationResumeRequest(appId)); |
507 | + Q_EMIT(thiz->applicationResumeRequest(toShortAppIdIfPossible(appId))); |
508 | }; |
509 | |
510 | impl->failureCallback = [](const gchar * appId, upstart_app_launch_app_failed_t failureType, gpointer userData) { |
511 | @@ -78,7 +137,7 @@ |
512 | } |
513 | |
514 | auto thiz = static_cast<ApplicationController*>(userData); |
515 | - Q_EMIT(thiz->applicationError(appId, error)); |
516 | + Q_EMIT(thiz->applicationError(toShortAppIdIfPossible(appId), error)); |
517 | }; |
518 | |
519 | upstart_app_launch_observer_add_app_starting(impl->preStartCallback, this); |
520 | @@ -101,7 +160,7 @@ |
521 | |
522 | pid_t ApplicationController::primaryPidForAppId(const QString& appId) |
523 | { |
524 | - GPid pid = upstart_app_launch_get_primary_pid(appId.toLatin1().constData()); |
525 | + GPid pid = upstart_app_launch_get_primary_pid(toLongAppIdIfPossible(appId).toLatin1().constData()); |
526 | DLOG_IF(!pid, "ApplicationController::stopApplication appId='%s' FAILED", qPrintable(appId)); |
527 | |
528 | return pid; |
529 | @@ -109,12 +168,12 @@ |
530 | |
531 | bool ApplicationController::appIdHasProcessId(pid_t pid, const QString& appId) |
532 | { |
533 | - return upstart_app_launch_pid_in_app_id(pid, appId.toLatin1().constData()); |
534 | + return upstart_app_launch_pid_in_app_id(pid, toLongAppIdIfPossible(appId).toLatin1().constData()); |
535 | } |
536 | |
537 | bool ApplicationController::stopApplicationWithAppId(const QString& appId) |
538 | { |
539 | - auto result = upstart_app_launch_stop_application(appId.toLatin1().constData()); |
540 | + auto result = upstart_app_launch_stop_application(toLongAppIdIfPossible(appId).toLatin1().constData()); |
541 | DLOG_IF(!result, "ApplicationController::stopApplicationWithAppId appId='%s' FAILED", qPrintable(appId)); |
542 | return result; |
543 | } |
544 | @@ -130,7 +189,7 @@ |
545 | } |
546 | |
547 | auto result = upstart_app_launch_start_application( |
548 | - appId.toLatin1().constData(), |
549 | + toLongAppIdIfPossible(appId).toLatin1().constData(), |
550 | static_cast<const gchar * const *>(upstartArgs)); |
551 | |
552 | g_strfreev(upstartArgs); |
553 | @@ -139,5 +198,28 @@ |
554 | return result; |
555 | } |
556 | |
557 | +QFileInfo ApplicationController::findDesktopFileForAppId(const QString &appId) const |
558 | +{ |
559 | + DLOG("ApplicationController::desktopFilePathForAppId (appId='%s')", qPrintable(appId)); |
560 | + |
561 | + // Search for the correct desktop file using a simple heuristic |
562 | + int dashPos = -1; |
563 | + QString helper = toLongAppIdIfPossible(appId); |
564 | + QString desktopFile; |
565 | + |
566 | + do { |
567 | + if (dashPos != -1) { |
568 | + helper = helper.replace(dashPos, 1, '/'); |
569 | + } |
570 | + |
571 | + desktopFile = QStandardPaths::locate(QStandardPaths::ApplicationsLocation, QString("%1.desktop").arg(helper)); |
572 | + if (!desktopFile.isEmpty()) return desktopFile; |
573 | + |
574 | + dashPos = helper.indexOf("-"); |
575 | + } while (dashPos != -1); |
576 | + |
577 | + return QFileInfo(); |
578 | +} |
579 | + |
580 | } // namespace upstart |
581 | } // namespace unitymir |
582 | |
583 | === modified file 'src/modules/Unity/Application/upstart/applicationcontroller.h' |
584 | --- src/modules/Unity/Application/upstart/applicationcontroller.h 2014-02-28 16:51:31 +0000 |
585 | +++ src/modules/Unity/Application/upstart/applicationcontroller.h 2014-05-16 12:20:01 +0000 |
586 | @@ -31,11 +31,13 @@ |
587 | ApplicationController(); |
588 | ~ApplicationController(); |
589 | |
590 | - pid_t primaryPidForAppId(const QString& appId); |
591 | - bool appIdHasProcessId(pid_t pid, const QString& appId); |
592 | - |
593 | - bool stopApplicationWithAppId(const QString& appId); |
594 | - bool startApplicationWithAppIdAndArgs(const QString& appId, const QStringList& arguments); |
595 | + pid_t primaryPidForAppId(const QString& appId) override; |
596 | + bool appIdHasProcessId(pid_t pid, const QString& appId) override; |
597 | + |
598 | + bool stopApplicationWithAppId(const QString& appId) override; |
599 | + bool startApplicationWithAppIdAndArgs(const QString& appId, const QStringList& arguments) override; |
600 | + |
601 | + QFileInfo findDesktopFileForAppId(const QString &appId) const override; |
602 | |
603 | private: |
604 | struct Private; |
605 | |
606 | === modified file 'tests/application_manager_test.cpp' |
607 | --- tests/application_manager_test.cpp 2014-04-15 14:31:02 +0000 |
608 | +++ tests/application_manager_test.cpp 2014-05-16 12:20:01 +0000 |
609 | @@ -82,8 +82,9 @@ |
610 | const QString appId("com.canonical.does.not.exist"); |
611 | |
612 | EXPECT_CALL(appController, startApplicationWithAppIdAndArgs(_, _)).Times(1); |
613 | + EXPECT_CALL(appController, findDesktopFileForAppId(appId)).Times(1); |
614 | |
615 | - EXPECT_CALL(desktopFileReaderFactory, createInstanceForAppId(appId)).Times(1); |
616 | + EXPECT_CALL(desktopFileReaderFactory, createInstance(_, _)).Times(1); |
617 | |
618 | EXPECT_CALL(processController, sigStopProcessGroupForPid(_)).Times(1); |
619 | EXPECT_CALL(processController, sigContinueProcessGroupForPid(_)).Times(1); |
620 | @@ -225,6 +226,85 @@ |
621 | EXPECT_EQ(beforeFailure, afterFailure); |
622 | } |
623 | |
624 | +TEST_F(ApplicationManagerTests,startApplicationSupportsShortAppId) |
625 | +{ |
626 | + using namespace ::testing; |
627 | + |
628 | + const QString shortAppId("com.canonical.test_test"); |
629 | + |
630 | + EXPECT_CALL(appController, startApplicationWithAppIdAndArgs(_, _)).Times(1); |
631 | + EXPECT_CALL(appController, findDesktopFileForAppId(shortAppId)).Times(1); |
632 | + |
633 | + EXPECT_CALL(desktopFileReaderFactory, createInstance(_, _)).Times(1); |
634 | + |
635 | + auto application = applicationManager.startApplication( |
636 | + shortAppId, |
637 | + ApplicationManager::NoFlag, |
638 | + QStringList()); |
639 | + |
640 | + EXPECT_EQ(shortAppId, application->appId()); |
641 | +} |
642 | + |
643 | +TEST_F(ApplicationManagerTests,startApplicationSupportsLongAppId) |
644 | +{ |
645 | + using namespace ::testing; |
646 | + |
647 | + const QString longAppId("com.canonical.test_test_0.1.235"); |
648 | + const QString shortAppId("com.canonical.test_test"); |
649 | + |
650 | + EXPECT_CALL(appController, startApplicationWithAppIdAndArgs(_, _)).Times(1); |
651 | + EXPECT_CALL(appController, findDesktopFileForAppId(shortAppId)).Times(1); |
652 | + |
653 | + EXPECT_CALL(desktopFileReaderFactory, createInstance(_, _)).Times(1); |
654 | + |
655 | + auto application = applicationManager.startApplication( |
656 | + longAppId, |
657 | + ApplicationManager::NoFlag, |
658 | + QStringList()); |
659 | + |
660 | + EXPECT_EQ(shortAppId, application->appId()); |
661 | +} |
662 | + |
663 | +TEST_F(ApplicationManagerTests,testAppIdGuessFromDesktopFileName) |
664 | +{ |
665 | + using namespace ::testing; |
666 | + quint64 procId = 5921; |
667 | + QString appId("sudoku-app"); |
668 | + QString cmdLine = QString("/usr/bin/my-app --desktop_file_hint=/usr/share/click/preinstalled/com.ubuntu.sudoku/1.0.180/%1.desktop").arg(appId); |
669 | + |
670 | + EXPECT_CALL(procInfo,command_line(procId)) |
671 | + .Times(1) |
672 | + .WillOnce(Return(qPrintable(cmdLine))); |
673 | + |
674 | + bool authed = true; |
675 | + applicationManager.authorizeSession(procId, authed); |
676 | + Application *app = applicationManager.findApplication(appId); |
677 | + |
678 | + EXPECT_EQ(true, authed); |
679 | + EXPECT_NE(app, nullptr); |
680 | + EXPECT_EQ(appId, app->appId()); |
681 | +} |
682 | + |
683 | +TEST_F(ApplicationManagerTests,testAppIdGuessFromDesktopFileNameWithLongAppId) |
684 | +{ |
685 | + using namespace ::testing; |
686 | + quint64 procId = 5921; |
687 | + QString shortAppId("com.ubuntu.desktop_desktop"); |
688 | + QString cmdLine = QString("/usr/bin/my-app --desktop_file_hint=/usr/share/applications/%1_1.0.180.desktop").arg(shortAppId); |
689 | + |
690 | + EXPECT_CALL(procInfo,command_line(procId)) |
691 | + .Times(1) |
692 | + .WillOnce(Return(qPrintable(cmdLine))); |
693 | + |
694 | + bool authed = true; |
695 | + applicationManager.authorizeSession(procId, authed); |
696 | + Application *app = applicationManager.findApplication(shortAppId); |
697 | + |
698 | + EXPECT_EQ(true, authed); |
699 | + EXPECT_NE(app, nullptr); |
700 | + EXPECT_EQ(shortAppId, app->appId()); |
701 | +} |
702 | + |
703 | TEST_F(ApplicationManagerTests,bug_case_1281075_session_ptrs_always_distributed_to_last_started_app) |
704 | { |
705 | using namespace ::testing; |
706 | @@ -305,11 +385,13 @@ |
707 | using namespace ::testing; |
708 | QString appId("sideStage"); |
709 | |
710 | - auto mockDesktopFileReader = new NiceMock<MockDesktopFileReader>(appId); |
711 | + EXPECT_CALL(appController, findDesktopFileForAppId(appId)).Times(1); |
712 | + |
713 | + auto mockDesktopFileReader = new NiceMock<MockDesktopFileReader>(appId, QFileInfo()); |
714 | ON_CALL(*mockDesktopFileReader, loaded()).WillByDefault(Return(true)); |
715 | ON_CALL(*mockDesktopFileReader, stageHint()).WillByDefault(Return("SideStage")); |
716 | |
717 | - ON_CALL(desktopFileReaderFactory, createInstanceForAppId(appId)).WillByDefault(Return(mockDesktopFileReader)); |
718 | + ON_CALL(desktopFileReaderFactory, createInstance(appId, _)).WillByDefault(Return(mockDesktopFileReader)); |
719 | |
720 | // mock upstart launching an app which reports itself as sidestage, but we're on phone |
721 | applicationManager.onProcessStartReportReceived(appId, false); |
722 | |
723 | === modified file 'tests/mock_application_controller.h' |
724 | --- tests/mock_application_controller.h 2014-02-28 16:51:31 +0000 |
725 | +++ tests/mock_application_controller.h 2014-05-16 12:20:01 +0000 |
726 | @@ -30,6 +30,7 @@ |
727 | { |
728 | MOCK_METHOD1(primaryPidForAppId, pid_t(const QString& appId)); |
729 | MOCK_METHOD2(appIdHasProcessId, bool(pid_t, const QString&)); |
730 | + MOCK_CONST_METHOD1(findDesktopFileForAppId, QFileInfo(const QString &appId)); |
731 | |
732 | MOCK_METHOD1(stopApplicationWithAppId, bool(const QString&)); |
733 | MOCK_METHOD2(startApplicationWithAppIdAndArgs, bool(const QString&, const QStringList&)); |
734 | @@ -45,6 +46,10 @@ |
735 | .WillByDefault( |
736 | Invoke(this, &MockApplicationController::doAppIdHasProcessId)); |
737 | |
738 | + ON_CALL(*this, findDesktopFileForAppId(_)) |
739 | + .WillByDefault( |
740 | + Invoke(this, &MockApplicationController::doFindDesktopFileForAppId)); |
741 | + |
742 | ON_CALL(*this, stopApplicationWithAppId(_)) |
743 | .WillByDefault( |
744 | Invoke(this, &MockApplicationController::doStopApplicationWithAppId)); |
745 | @@ -72,6 +77,12 @@ |
746 | return it->pid() == pid; |
747 | } |
748 | |
749 | + QFileInfo doFindDesktopFileForAppId(const QString& appId) const |
750 | + { |
751 | + QString path = QString("/usr/share/applications/%1.desktop").arg(appId); |
752 | + return QFileInfo(path); |
753 | + } |
754 | + |
755 | bool doStopApplicationWithAppId(const QString& appId) |
756 | { |
757 | (void) appId; |
758 | |
759 | === modified file 'tests/mock_desktop_file_reader.h' |
760 | --- tests/mock_desktop_file_reader.h 2014-02-28 16:51:31 +0000 |
761 | +++ tests/mock_desktop_file_reader.h 2014-05-16 12:20:01 +0000 |
762 | @@ -26,38 +26,20 @@ |
763 | { |
764 | struct MockDesktopFileReader : public unitymir::DesktopFileReader |
765 | { |
766 | - MockDesktopFileReader(const QString& appId) |
767 | - : unitymir::DesktopFileReader(appId) |
768 | - { |
769 | - using namespace ::testing; |
770 | - |
771 | - ON_CALL(*this, file()).WillByDefault(Invoke(this, &MockDesktopFileReader::doFile)); |
772 | - ON_CALL(*this, appId()).WillByDefault(Invoke(this, &MockDesktopFileReader::doAppId)); |
773 | - ON_CALL(*this, name()).WillByDefault(Invoke(this, &MockDesktopFileReader::doName)); |
774 | - ON_CALL(*this, comment()).WillByDefault(Invoke(this, &MockDesktopFileReader::doComment)); |
775 | - ON_CALL(*this, icon()).WillByDefault(Invoke(this, &MockDesktopFileReader::doIcon)); |
776 | - ON_CALL(*this, exec()).WillByDefault(Invoke(this, &MockDesktopFileReader::doExec)); |
777 | - ON_CALL(*this, path()).WillByDefault(Invoke(this, &MockDesktopFileReader::doPath)); |
778 | - ON_CALL(*this, stageHint()).WillByDefault(Invoke(this, &MockDesktopFileReader::doStageHint)); |
779 | - ON_CALL(*this, loaded()).WillByDefault(Invoke(this, &MockDesktopFileReader::doLoaded)); |
780 | - ON_CALL(*this, findDesktopFile(_)).WillByDefault(Invoke(this, &MockDesktopFileReader::doFindDesktopFile)); |
781 | - } |
782 | - |
783 | - MockDesktopFileReader(const QFileInfo& fileInfo) |
784 | - : DesktopFileReader(fileInfo) |
785 | - { |
786 | - using namespace ::testing; |
787 | - |
788 | - ON_CALL(*this, file()).WillByDefault(Invoke(this, &MockDesktopFileReader::doFile)); |
789 | - ON_CALL(*this, appId()).WillByDefault(Invoke(this, &MockDesktopFileReader::doAppId)); |
790 | - ON_CALL(*this, name()).WillByDefault(Invoke(this, &MockDesktopFileReader::doName)); |
791 | - ON_CALL(*this, comment()).WillByDefault(Invoke(this, &MockDesktopFileReader::doComment)); |
792 | - ON_CALL(*this, icon()).WillByDefault(Invoke(this, &MockDesktopFileReader::doIcon)); |
793 | - ON_CALL(*this, exec()).WillByDefault(Invoke(this, &MockDesktopFileReader::doExec)); |
794 | - ON_CALL(*this, path()).WillByDefault(Invoke(this, &MockDesktopFileReader::doPath)); |
795 | - ON_CALL(*this, stageHint()).WillByDefault(Invoke(this, &MockDesktopFileReader::doStageHint)); |
796 | - ON_CALL(*this, loaded()).WillByDefault(Invoke(this, &MockDesktopFileReader::doLoaded)); |
797 | - ON_CALL(*this, findDesktopFile(_)).WillByDefault(Invoke(this, &MockDesktopFileReader::doFindDesktopFile)); |
798 | + MockDesktopFileReader(const QString &appId, const QFileInfo& fileInfo) |
799 | + : DesktopFileReader(appId, fileInfo) |
800 | + { |
801 | + using namespace ::testing; |
802 | + |
803 | + ON_CALL(*this, file()).WillByDefault(Invoke(this, &MockDesktopFileReader::doFile)); |
804 | + ON_CALL(*this, appId()).WillByDefault(Invoke(this, &MockDesktopFileReader::doAppId)); |
805 | + ON_CALL(*this, name()).WillByDefault(Invoke(this, &MockDesktopFileReader::doName)); |
806 | + ON_CALL(*this, comment()).WillByDefault(Invoke(this, &MockDesktopFileReader::doComment)); |
807 | + ON_CALL(*this, icon()).WillByDefault(Invoke(this, &MockDesktopFileReader::doIcon)); |
808 | + ON_CALL(*this, exec()).WillByDefault(Invoke(this, &MockDesktopFileReader::doExec)); |
809 | + ON_CALL(*this, path()).WillByDefault(Invoke(this, &MockDesktopFileReader::doPath)); |
810 | + ON_CALL(*this, stageHint()).WillByDefault(Invoke(this, &MockDesktopFileReader::doStageHint)); |
811 | + ON_CALL(*this, loaded()).WillByDefault(Invoke(this, &MockDesktopFileReader::doLoaded)); |
812 | } |
813 | |
814 | MOCK_CONST_METHOD0(file, QString()); |
815 | @@ -69,7 +51,6 @@ |
816 | MOCK_CONST_METHOD0(path, QString()); |
817 | MOCK_CONST_METHOD0(stageHint, QString()); |
818 | MOCK_CONST_METHOD0(loaded, bool()); |
819 | - MOCK_CONST_METHOD1(findDesktopFile, QString(const QString&)); |
820 | |
821 | QString doFile() const |
822 | { |
823 | @@ -115,11 +96,6 @@ |
824 | { |
825 | return DesktopFileReader::loaded(); |
826 | } |
827 | - |
828 | - QString doFindDesktopFile(const QString& appId) const |
829 | - { |
830 | - return DesktopFileReader::findDesktopFile(appId); |
831 | - } |
832 | }; |
833 | |
834 | struct MockDesktopFileReaderFactory : public unitymir::DesktopFileReader::Factory |
835 | @@ -127,38 +103,23 @@ |
836 | MockDesktopFileReaderFactory() |
837 | { |
838 | using namespace ::testing; |
839 | - ON_CALL(*this, createInstanceForAppId(_)) |
840 | - .WillByDefault( |
841 | - Invoke( |
842 | - this, |
843 | - &MockDesktopFileReaderFactory::doCreateInstanceForAppId)); |
844 | - ON_CALL(*this, createInstanceForDesktopFile(_)) |
845 | - .WillByDefault( |
846 | - Invoke( |
847 | - this, |
848 | - &MockDesktopFileReaderFactory::doCreateInstanceForDesktopFile)); |
849 | - } |
850 | - |
851 | - virtual unitymir::DesktopFileReader* doCreateInstanceForAppId(const QString& appId) |
852 | - { |
853 | - using namespace ::testing; |
854 | - auto instance = new NiceMock<MockDesktopFileReader>(appId); |
855 | - ON_CALL(*instance, loaded()).WillByDefault(Return(true)); |
856 | - |
857 | - return instance; |
858 | - } |
859 | - |
860 | - virtual unitymir::DesktopFileReader* doCreateInstanceForDesktopFile(const QFileInfo& fi) |
861 | - { |
862 | - using namespace ::testing; |
863 | - auto instance = new NiceMock<MockDesktopFileReader>(fi); |
864 | - ON_CALL(*instance, loaded()).WillByDefault(Return(true)); |
865 | - |
866 | - return instance; |
867 | - } |
868 | - |
869 | - MOCK_METHOD1(createInstanceForAppId, unitymir::DesktopFileReader*(const QString&)); |
870 | - MOCK_METHOD1(createInstanceForDesktopFile, unitymir::DesktopFileReader*(const QFileInfo&)); |
871 | + ON_CALL(*this, createInstance(_, _)) |
872 | + .WillByDefault( |
873 | + Invoke( |
874 | + this, |
875 | + &MockDesktopFileReaderFactory::doCreateInstance)); |
876 | + } |
877 | + |
878 | + virtual unitymir::DesktopFileReader* doCreateInstance(const QString &appId, const QFileInfo &fi) |
879 | + { |
880 | + using namespace ::testing; |
881 | + auto instance = new NiceMock<MockDesktopFileReader>(appId, fi); |
882 | + ON_CALL(*instance, loaded()).WillByDefault(Return(true)); |
883 | + |
884 | + return instance; |
885 | + } |
886 | + |
887 | + MOCK_METHOD2(createInstance, unitymir::DesktopFileReader*(const QString &appId, const QFileInfo &fi)); |
888 | }; |
889 | } |
890 | |
891 | |
892 | === modified file 'tests/taskcontroller_test.cpp' |
893 | --- tests/taskcontroller_test.cpp 2014-02-28 16:51:31 +0000 |
894 | +++ tests/taskcontroller_test.cpp 2014-05-16 12:20:01 +0000 |
895 | @@ -49,6 +49,8 @@ |
896 | |
897 | MOCK_METHOD1(primaryPidForAppId, pid_t (const QString&)); |
898 | MOCK_METHOD2(appIdHasProcessId, bool(pid_t, const QString&)); |
899 | + MOCK_CONST_METHOD1(findDesktopFileForAppId, QFileInfo(const QString &appId)); |
900 | + |
901 | MOCK_METHOD1(stopApplicationWithAppId, bool(const QString&)); |
902 | MOCK_METHOD2(startApplicationWithAppIdAndArgs, bool(const QString&, const QStringList&)); |
903 | }; |
PASSED: Continuous integration, rev:228 jenkins. qa.ubuntu. com/job/ unity-mir- ci/337/ jenkins. qa.ubuntu. com/job/ unity-mir- utopic- amd64-ci/ 1 jenkins. qa.ubuntu. com/job/ unity-mir- utopic- armhf-ci/ 1 jenkins. qa.ubuntu. com/job/ unity-mir- utopic- armhf-ci/ 1/artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ unity-mir- utopic- i386-ci/ 1
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/unity- mir-ci/ 337/rebuild
http://