Merge lp:~nick-dedekind/unity-mir/trusted-sessions into lp:unity-mir

Proposed by Nick Dedekind
Status: Superseded
Proposed branch: lp:~nick-dedekind/unity-mir/trusted-sessions
Merge into: lp:unity-mir
Diff against target: 1943 lines (+922/-141)
30 files modified
debian/control (+4/-4)
src/modules/Unity/Application/CMakeLists.txt (+5/-2)
src/modules/Unity/Application/application.cpp (+84/-11)
src/modules/Unity/Application/application.h (+19/-3)
src/modules/Unity/Application/application_manager.cpp (+268/-79)
src/modules/Unity/Application/application_manager.h (+26/-7)
src/modules/Unity/Application/applicationscreenshotprovider.cpp (+2/-1)
src/modules/Unity/Application/dbuswindowstack.cpp (+1/-1)
src/modules/Unity/Application/mirsurface.cpp (+4/-4)
src/modules/Unity/Application/mirsurface.h (+4/-4)
src/modules/Unity/Application/mirsurfacemanager.cpp (+26/-13)
src/modules/Unity/Application/proc_info.cpp (+18/-0)
src/modules/Unity/Application/proc_info.h (+3/-0)
src/modules/Unity/Application/promptsession.cpp (+74/-0)
src/modules/Unity/Application/promptsession.h (+62/-0)
src/modules/Unity/Application/session.cpp (+54/-0)
src/modules/Unity/Application/session.h (+53/-0)
src/unity-mir/CMakeLists.txt (+2/-0)
src/unity-mir/focussetter.cpp (+3/-2)
src/unity-mir/promptsessionlistener.cpp (+60/-0)
src/unity-mir/promptsessionlistener.h (+45/-0)
src/unity-mir/qmirserver.cpp (+1/-0)
src/unity-mir/sessionauthorizer.cpp (+0/-1)
src/unity-mir/shellserverconfiguration.cpp (+20/-1)
src/unity-mir/shellserverconfiguration.h (+4/-0)
tests/CMakeLists.txt (+1/-0)
tests/application_manager_test.cpp (+12/-6)
tests/mock_proc_info.h (+6/-1)
tests/mock_prompt_session_manager.h (+57/-0)
tests/mock_session.h (+4/-1)
To merge this branch: bzr merge lp:~nick-dedekind/unity-mir/trusted-sessions
Reviewer Review Type Date Requested Status
Gerry Boland (community) Needs Information
PS Jenkins bot (community) continuous-integration Needs Fixing
Review via email: mp+210775@code.launchpad.net

This proposal has been superseded by a proposal from 2014-06-17.

Commit message

Shell implementation of Mir trust sessions.

Description of the change

Shell implementation of Mir trust sessions.
Requires lp:~nick-dedekind/mir/trusted_sessions to land

A mir trust session consists of any number of mir sessions arranged into a parent hierarchy. The last child of the hierarchy is the session which is considered to be the top focused session at all times if the unity-mir Application is in focus.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
179. By Nick Dedekind

Updated for changes to trust sessions

180. By Nick Dedekind

merged with trunk

181. By Nick Dedekind

Added trust session listener

182. By Nick Dedekind

Changes for trust sessions

183. By Nick Dedekind

merged with trunk

184. By Nick Dedekind

better trust session handling

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

changes reqired for trust session

186. By Nick Dedekind

merged with mir 0.2 changes

187. By Nick Dedekind

more changes for trust session api

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

mir 0.2 rebase

189. By Nick Dedekind

merged with devel

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

updated mock_shell for MirTrustSessionAddTrustResult removal

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

mir trust_session_manager changes

192. By Nick Dedekind

renaming of trust session manager interface functions

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

merge with devel

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

fixed tests

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

update trust helper auth

196. By Nick Dedekind

use trust manager for stopping session. Removed frontend::Shell references

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

session/surface changes cause screenshot update.

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

sessions added to list, not pid map

199. By Nick Dedekind

updated trust session listener function names

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

updated mir requirements

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

merged with trunk

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

rename trusted_participant_starting/stopping to participant_added/removed

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

Is this actually ready for review? If not, please mark as Work in Progress

review: Needs Information
203. By Nick Dedekind

s/trust/prompt

204. By Nick Dedekind

merged with compatibility branch

205. By Nick Dedekind

Fixed some focus issues

206. By Nick Dedekind

merged with trunk

207. By Nick Dedekind

fixed ApplicationManagerTests.onceAppAddedToApplicationLists_mirSurfaceCreatedEventHandled

208. By Nick Dedekind

simplify a bit

209. By Nick Dedekind

added prompt session unit tests

210. By Nick Dedekind

removed test comments

211. By Nick Dedekind

removed unitymir::Session

212. By Nick Dedekind

removed unitymir::PromptSession.

213. By Nick Dedekind

reverted unnecessary changes

214. By Nick Dedekind

use process-cpp for ppid

215. By Nick Dedekind

style changes.

216. By Nick Dedekind

reverted whitespace changes

217. By Nick Dedekind

revert some more unnecessary changes

218. By Nick Dedekind

check session pointers

219. By Nick Dedekind

remove clear session

220. By Nick Dedekind

TYPE const& -> const TYPE&

221. By Nick Dedekind

renamed effectiveSession -> foregroundSession / promptSession -> activePromptSession

222. By Nick Dedekind

pushPromptSession -> appendPromptSession

223. By Nick Dedekind

namespace mir::scene -> ms

224. By Nick Dedekind

style updates

225. By Nick Dedekind

more review comments

226. By Nick Dedekind

test review comments

227. By Nick Dedekind

fixed up some screenshot signal duplication

228. By Nick Dedekind

removed whitespace

229. By Nick Dedekind

merged with trunk

230. By Nick Dedekind

fixed build

231. By Nick Dedekind

fixed dlog

232. By Nick Dedekind

merged with lp:~nick-dedekind/unity-mir/thready-screenshotting

233. By Nick Dedekind

remerged with thready branch

234. By Nick Dedekind

remove authorise dodgeys for prompt sessions

235. By Nick Dedekind

reverted changes to debian/control & debian/changelog

236. By Nick Dedekind

bumped to 0.5

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/control'
2--- debian/control 2014-06-09 11:35:09 +0000
3+++ debian/control 2014-06-17 15:53:01 +0000
4@@ -9,8 +9,8 @@
5 libboost-dev,
6 libboost-system-dev,
7 libubuntu-application-api-dev (>= 2.0.0),
8- libmirserver-dev (>= 0.2.0),
9- libmirclient-dev (>= 0.1.8),
10+ libmirserver-dev (>= 0.3.0),
11+ libmirclient-dev (>= 0.1.9),
12 libprocess-cpp-dev,
13 libunity-api-dev (>= 7.80.6),
14 libubuntu-app-launch2-dev,
15@@ -38,7 +38,7 @@
16 unity-application-impl,
17 unity-application-impl-2,
18 Description: Qt plugins for Unity specific Mir APIs
19- Unity-Mir provides Qt bindings for Mir features that are not exposed
20+ Unity-Mir provides Qt bindings for Mir features that are not exposed
21 through the QtUbuntu QPA plugins but needed for shell functionality.
22
23 Package: libunity-mir-dev
24@@ -55,7 +55,7 @@
25 libplatform-api1-dev,
26 qtbase5-dev,
27 Description: Qt plugins for Unity specific Mir APIs - development files
28- Unity-Mir provides Qt bindings for Mir features that are not exposed
29+ Unity-Mir provides Qt bindings for Mir features that are not exposed
30 through the QtUbuntu QPA plugins but needed for shell functionality.
31 .
32 This package provides the development files for libunity-mir.
33
34=== modified file 'src/modules/Unity/Application/CMakeLists.txt'
35--- src/modules/Unity/Application/CMakeLists.txt 2014-06-09 11:35:09 +0000
36+++ src/modules/Unity/Application/CMakeLists.txt 2014-06-17 15:53:01 +0000
37@@ -33,6 +33,8 @@
38 processcontroller.cpp
39 proc_info.cpp
40 shellinputarea.cpp
41+ session.cpp
42+ promptsession.cpp
43 ubuntukeyboardinfo.cpp
44
45 upstart/applicationcontroller.h
46@@ -48,10 +50,11 @@
47 mirsurface.h
48 mirsurfacemanager.h
49 shellinputarea.h
50+ session.h
51 inputarea.h
52 inputfilterarea.h
53 ubuntukeyboardinfo.h
54-
55+
56 # We need to pull in some external header files
57 /usr/include/unity/shell/application/ApplicationManagerInterface.h
58 /usr/include/unity/shell/application/ApplicationInfoInterface.h
59@@ -63,7 +66,7 @@
60
61 target_link_libraries(
62 unityapplicationplugin
63-
64+
65 unity-mir
66
67 ubuntu_application_api
68
69=== modified file 'src/modules/Unity/Application/application.cpp'
70--- src/modules/Unity/Application/application.cpp 2014-05-26 15:54:44 +0000
71+++ src/modules/Unity/Application/application.cpp 2014-06-17 15:53:01 +0000
72@@ -22,6 +22,8 @@
73
74 // unity-mir
75 #include "logging.h"
76+#include "session.h"
77+#include "promptsession.h"
78
79 // mir
80 #include <mir/scene/session.h>
81@@ -133,11 +135,51 @@
82 return m_fullscreen;
83 }
84
85-std::shared_ptr<mir::scene::Session> Application::session() const
86+std::shared_ptr<mir::scene::Session> Application::topMirSession() const
87+{
88+ QListIterator<QSharedPointer<PromptSession>> iter(m_promptSessions);
89+ iter.toBack();
90+ while (iter.hasPrevious()) {
91+ auto top_prompt_provider = iter.previous()->topProvider();
92+ if (top_prompt_provider) {
93+ return top_prompt_provider;
94+ }
95+ }
96+
97+ QSharedPointer<Session> appSession = session();
98+ if (appSession) {
99+ return appSession->mirSession();
100+ }
101+ return std::shared_ptr<mir::scene::Session>();
102+}
103+
104+QSharedPointer<Session> Application::session() const
105 {
106 return m_session;
107 }
108
109+QSharedPointer<PromptSession> Application::promptSession() const
110+{
111+ if (m_promptSessions.count() > 0)
112+ return m_promptSessions.back();
113+ return QSharedPointer<PromptSession>();
114+}
115+
116+bool Application::hasChildProcess(pid_t pid) const
117+{
118+ if (m_pid == pid) {
119+ return true;
120+ }
121+
122+ QListIterator<QSharedPointer<PromptSession>> iter(m_promptSessions);
123+ while(iter.hasNext()) {
124+ if (iter.next()->hasChildProcess(pid)) {
125+ return true;
126+ }
127+ }
128+ return false;
129+}
130+
131 bool Application::visible() const
132 {
133 return m_visible;
134@@ -163,13 +205,36 @@
135 m_pid = pid;
136 }
137
138-void Application::setSession(const std::shared_ptr<mir::scene::Session>& session)
139+void Application::setSession(const QSharedPointer<Session>& new_session)
140 {
141- DLOG("Application::setSession (this=%p, session=%p)", this, session.get());
142+ DLOG("Application::setSession (this=%p, session=%p)", this, new_session ? new_session->mirSession().get() : nullptr);
143
144 // TODO(greyback) what if called with new surface?
145- m_session = session;
146+ m_session = new_session;
147 m_visible = true; // bit of an assumption that, but no other way to deduce an actual Surface has been created
148+ checkSessionChanges();
149+}
150+
151+void Application::pushPromptSession(const QSharedPointer<PromptSession>& prompt_session)
152+{
153+ DLOG("Application::setPromptSession (this=%p, prompt_session=%p)", this, prompt_session ? prompt_session.data() : nullptr);
154+
155+ m_promptSessions.append(prompt_session);
156+ checkSessionChanges();
157+}
158+
159+void Application::removePromptSession(const QSharedPointer<PromptSession>& prompt_session)
160+{
161+ DLOG("Application::setPromptSession (this=%p, prompt_session=%p)", this, prompt_session ? prompt_session.data() : nullptr);
162+
163+ QMutableListIterator<QSharedPointer<PromptSession>> iter(m_promptSessions);
164+ while(iter.hasNext()) {
165+ if (iter.next() == prompt_session) {
166+ iter.remove();
167+ }
168+ }
169+
170+ checkSessionChanges();
171 }
172
173 void Application::setSessionName(const QString& name)
174@@ -198,7 +263,7 @@
175
176 void Application::updateScreenshot()
177 {
178- session()->take_snapshot(
179+ topMirSession()->take_snapshot(
180 [&](mir::scene::Snapshot const& snapshot)
181 {
182 DLOG("ApplicationScreenshotProvider - Mir snapshot ready with size %d x %d",
183@@ -222,7 +287,7 @@
184 {
185 case Application::Suspended:
186 if (m_state == Application::Running) {
187- session()->set_lifecycle_state(mir_lifecycle_state_will_suspend);
188+ session()->setLifecycleState(mir_lifecycle_state_will_suspend);
189 m_suspendTimer->start(3000);
190 }
191 break;
192@@ -232,7 +297,7 @@
193
194 if (m_state == Application::Suspended) {
195 resume();
196- session()->set_lifecycle_state(mir_lifecycle_state_resumed);
197+ session()->setLifecycleState(mir_lifecycle_state_resumed);
198 } else if (m_state == Application::Stopped) {
199 respawn();
200 state = Application::Starting;
201@@ -273,10 +338,8 @@
202 DLOG("Application::setVisible (this=%p, visible=%s)", this, visible ? "yes" : "no");
203 // FIXME: this is bad, as should a MirSurface of this app exist, it won't be notified of the visiblity change.
204 if (visible != m_visible) {
205- if (visible) {
206- m_session->show();
207- } else {
208- m_session->hide();
209+ if (m_session) {
210+ visible ? m_session->show() : m_session->hide();
211 }
212 m_visible = visible;
213 Q_EMIT visibleChanged();
214@@ -306,4 +369,14 @@
215 return m_longAppId;
216 }
217
218+void Application::checkSessionChanges()
219+{
220+ mir::scene::Session* lastTopSession = m_lastTopSession;
221+ auto currentTopSession = topMirSession().get();
222+ m_lastTopSession = currentTopSession;
223+ if (currentTopSession && currentTopSession != lastTopSession) {
224+ Q_EMIT sessionChanged();
225+ }
226+}
227+
228 } // namespace unitymir
229
230=== modified file 'src/modules/Unity/Application/application.h'
231--- src/modules/Unity/Application/application.h 2014-05-16 15:40:00 +0000
232+++ src/modules/Unity/Application/application.h 2014-06-17 15:53:01 +0000
233@@ -36,6 +36,8 @@
234
235 class DesktopFileReader;
236 class TaskController;
237+class Session;
238+class PromptSession;
239
240 class Application : public unity::shell::application::ApplicationInfoInterface {
241 Q_OBJECT
242@@ -78,9 +80,17 @@
243 QString desktopFile() const;
244 QString exec() const;
245 bool fullscreen() const;
246- std::shared_ptr<::mir::scene::Session> session() const;
247 pid_t pid() const;
248
249+ std::shared_ptr<mir::scene::Session> topMirSession() const;
250+
251+ QSharedPointer<Session> session() const;
252+ QSharedPointer<PromptSession> promptSession() const;
253+
254+ bool hasChildProcess(pid_t pid) const;
255+
256+ void checkSessionChanges();
257+
258 public Q_SLOTS:
259 void suspend();
260 void resume();
261@@ -89,6 +99,7 @@
262 Q_SIGNALS:
263 void fullscreenChanged();
264 void stageChanged(Stage stage);
265+ void sessionChanged();
266 void visibleChanged();
267
268 private:
269@@ -97,9 +108,12 @@
270 void setState(State state);
271 void setFocused(bool focus);
272 void setFullscreen(bool fullscreen);
273- void setSession(const std::shared_ptr<::mir::scene::Session>& session);
274 void setSessionName(const QString& name);
275
276+ void setSession(const QSharedPointer<Session>& session);
277+ void pushPromptSession(const QSharedPointer<PromptSession>& session);
278+ void removePromptSession(const QSharedPointer<PromptSession>& session);
279+
280 QSharedPointer<TaskController> m_taskController;
281 DesktopFileReader* m_desktopData;
282 QString m_longAppId;
283@@ -111,11 +125,13 @@
284 QImage m_screenshotImage;
285 bool m_canBeResumed;
286 bool m_fullscreen;
287+ QSharedPointer<Session> m_session;
288+ QList<QSharedPointer<PromptSession>> m_promptSessions;
289 bool m_visible; // duplicating internal Mir data :(
290- std::shared_ptr<::mir::scene::Session> m_session;
291 QString m_sessionName;
292 QStringList m_arguments;
293 QTimer* m_suspendTimer;
294+ mutable mir::scene::Session* m_lastTopSession;
295
296 friend class ApplicationManager;
297 friend class MirSurfaceManager;
298
299=== modified file 'src/modules/Unity/Application/application_manager.cpp'
300--- src/modules/Unity/Application/application_manager.cpp 2014-05-26 15:54:50 +0000
301+++ src/modules/Unity/Application/application_manager.cpp 2014-06-17 15:53:01 +0000
302@@ -31,18 +31,25 @@
303 #include "initialsurfaceplacementstrategy.h"
304 #include "taskcontroller.h"
305 #include "logging.h"
306+#include "session.h"
307+#include "promptsession.h"
308+#include "promptsessionlistener.h"
309
310 // mir
311 #include <mir/scene/depth_id.h>
312 #include <mir/scene/session.h>
313 #include <mir/shell/focus_controller.h>
314 #include <mir/scene/surface.h>
315+#include <mir/scene/prompt_session.h>
316 #include <mir/graphics/display.h>
317 #include <mir/graphics/display_buffer.h>
318 #include <mircommon/mir/geometry/rectangles.h>
319+#include <mir/frontend/shell.h>
320+#include <mir/scene/prompt_session_manager.h>
321
322 // Qt
323 #include <QCoreApplication>
324+#include <QThread>
325
326 // std
327 #include <csignal>
328@@ -102,6 +109,20 @@
329 manager, &ApplicationManager::onSessionCreatedSurface);
330 }
331
332+void connectToPromptSessionListener(ApplicationManager * manager, PromptSessionListener * listener)
333+{
334+ QObject::connect(listener, &PromptSessionListener::promptSessionStarting,
335+ manager, &ApplicationManager::onPromptSessionStarting);
336+ QObject::connect(listener, &PromptSessionListener::promptSessionStopping,
337+ manager, &ApplicationManager::onPromptSessionStopping);
338+
339+ QObject::connect(listener, &PromptSessionListener::promptProviderAdded,
340+ manager, &ApplicationManager::onPromptProviderAdded);
341+ QObject::connect(listener, &PromptSessionListener::promptProviderRemoved,
342+ manager, &ApplicationManager::onPromptProviderRemoved);
343+
344+}
345+
346 void connectToSessionAuthorizer(ApplicationManager * manager, SessionAuthorizer * authorizer)
347 {
348 QObject::connect(authorizer, &SessionAuthorizer::requestAuthorizationForSession,
349@@ -151,17 +172,19 @@
350 // FIXME: We should use a QSharedPointer to wrap this ApplicationManager object, which requires us
351 // to use the data() method to pass the raw pointer to the QML engine. However the QML engine appears
352 // to take ownership of the object, and deletes it when it wants to. This conflicts with the purpose
353- // of the QSharedPointer, and a double-delete results. Trying QQmlEngine::setObjectOwnership on the
354+ // of the QSharedPointer, and a double-delete results. Trying QQmlEngine::setObjectOwnership on the
355 // object no effect, which it should. Need to investigate why.
356 ApplicationManager* appManager = new ApplicationManager(
357 taskController,
358 fileReaderFactory,
359 procInfo,
360 mirServer->the_focus_controller(),
361+ mirServer->the_prompt_session_manager(),
362 displaySize
363 );
364
365 connectToSessionListener(appManager, mirServer->sessionListener());
366+ connectToPromptSessionListener(appManager, mirServer->promptSessionListener());
367 connectToSessionAuthorizer(appManager, mirServer->sessionAuthorizer());
368 connectToPlacementStrategy(appManager, mirServer->placementStrategy());
369 connectToTaskController(appManager, taskController.data());
370@@ -183,7 +206,8 @@
371 const QSharedPointer<TaskController>& taskController,
372 const QSharedPointer<DesktopFileReader::Factory>& desktopFileReaderFactory,
373 const QSharedPointer<ProcInfo>& procInfo,
374- const std::shared_ptr<mir::shell::FocusController>& controller,
375+ const std::shared_ptr<mir::shell::FocusController>& focusController,
376+ const std::shared_ptr<mir::scene::PromptSessionManager>& promptSessionManager,
377 const QSize& displaySize,
378 QObject *parent)
379 : ApplicationManagerInterface(parent)
380@@ -193,13 +217,13 @@
381 , m_msApplicationToBeFocused(nullptr)
382 , m_ssApplicationToBeFocused(nullptr)
383 , m_lifecycleExceptions(QStringList() << "com.ubuntu.music")
384- , m_focusController(controller)
385+ , m_focusController(focusController)
386+ , m_promptSessionManager(promptSessionManager)
387 , m_dbusWindowStack(new DBusWindowStack(this))
388 , m_taskController(taskController)
389 , m_desktopFileReaderFactory(desktopFileReaderFactory)
390 , m_procInfo(procInfo)
391 , m_gridUnitPx(8)
392- , m_fenceNext(false)
393 , m_displaySize(displaySize)
394 , m_panelHeight(54)
395 {
396@@ -385,15 +409,15 @@
397 DLOG("No such running application '%s'", qPrintable(appId));
398 return false;
399 }
400-
401+
402 if (application->stage() == Application::MainStage && m_sideStageApplication)
403 suspendApplication(m_sideStageApplication);
404-
405+
406 if (application->stage() == Application::MainStage)
407 m_msApplicationToBeFocused = application;
408 else
409 m_ssApplicationToBeFocused = application;
410-
411+
412 if (application->state() == Application::Stopped) {
413 // Respawning this app, move to end of application list so onSessionStarting works ok
414 // FIXME: this happens pretty late, shell could request respawn earlier
415@@ -401,8 +425,9 @@
416 int from = m_applications.indexOf(application);
417 move(from, m_applications.length()-1);
418 } else {
419- if (application->session()) {
420- m_focusController->set_focus_to(application->session());
421+ auto mirSession = application->topMirSession();
422+ if (mirSession) {
423+ m_focusController->set_focus_to(mirSession);
424 int from = m_applications.indexOf(application);
425 move(from, 0);
426 }
427@@ -479,6 +504,7 @@
428 DLOG("Unable to instantiate application with appId '%s'", qPrintable(appId));
429 return nullptr;
430 }
431+ connect(application, &Application::sessionChanged, this, &ApplicationManager::onApplicationTopSessionChanged);
432
433 // override stage if necessary
434 if (application->stage() == Application::SideStage && flags.testFlag(ApplicationManager::ForceMainStage)) {
435@@ -703,15 +729,27 @@
436
437 if (info->startsWith("maliit-server") || info->contains("qt5/libexec/QtWebProcess")
438 || info->startsWith("/usr/bin/signon-ui")) {
439- authorized = true;
440- m_fenceNext = true;
441+ DLOG("ApplicationManager ACCEPTED connection from white-list app with pid %lld", pid);
442+ authorized = true;
443+ m_fencePIDs << pid;
444+ return;
445+ }
446+
447+ const quint64 ppid = m_procInfo->ppid(pid);
448+ if (info->contains("trust-session-demo-trusted-helper") ||
449+ info->contains("unity8") ||
450+ (ppid != 0 && m_procInfo->commandLine(ppid)->contains("trust-session-demo-trusted-helper"))) {
451+ DLOG("ApplicationManager ACCEPTED trust app %lld", pid);
452+ authorized = true;
453+ m_fencePIDs << pid;
454 return;
455 }
456
457 boost::optional<QString> desktopFileName{ info->getParameter("--desktop_file_hint=") };
458
459 if (!desktopFileName) {
460- LOG("ApplicationManager REJECTED connection from app with pid %lld as no desktop_file_hint specified", pid);
461+ LOG("ApplicationManager REJECTED connection from app with pid %lld as no desktop_file_hint specified (%s)", pid,
462+ info->asStringList()[0].toLatin1().data());
463 return;
464 }
465
466@@ -769,11 +807,11 @@
467
468 void ApplicationManager::placeSession(ms::Session const* session, uint32_t &x, uint32_t &y)
469 {
470- Application* application = findApplicationWithSession(session);
471+ Application* application = findApplicationWithSession(session, true);
472 DLOG("ApplicationManager::placeSession (this=%p, application=%p, session=%p, name=%s)", this, application, session,
473 session?(session->name().c_str()):"null");
474
475- // Application defaults
476+ // Application defaults
477 x = 0;
478 y = m_panelHeight;
479
480@@ -790,72 +828,79 @@
481 // SideStage override
482 if (application && application->stage() == Application::SideStage)
483 x = m_displaySize.width() - (SIDE_STAGE_WIDTH_GU * m_gridUnitPx);
484-
485+
486 DLOG("ApplicationManager::placeSession (x=%d, y=%d)", x, y);
487 }
488
489-void ApplicationManager::onSessionStarting(const std::shared_ptr<ms::Session>& session)
490+void ApplicationManager::onSessionStarting(const std::shared_ptr<ms::Session>& mirSession)
491 {
492- DLOG("ApplicationManager::onSessionStarting (this=%p, application=%s)", this, session?session->name().c_str():"null");
493-
494- if (m_fenceNext) {
495- m_fenceNext = false;
496- return;
497- }
498-
499- Application* application = findApplicationWithPid(session->process_id());
500+ DLOG("ApplicationManager::onSessionStarting (this=%p, application=%s)", this, mirSession?mirSession->name().c_str():"null");
501+
502+ pid_t pid = mirSession->process_id();
503+
504+ QSharedPointer<Session> new_session(new Session(mirSession));
505+ m_sessions.append(new_session);
506+
507+ Application* application = findApplicationWithPid(mirSession->process_id(), false);
508 if (application && application->state() != Application::Running) {
509- application->setSession(session);
510+ application->setSession(new_session);
511 if (application->stage() == Application::MainStage)
512 m_msApplicationToBeFocused = application;
513 else
514 m_ssApplicationToBeFocused = application;
515 } else {
516+ if (m_fencePIDs.contains(pid)) {
517+ return;
518+ }
519 DLOG("ApplicationManager::onSessionStarting - unauthorized application!!");
520 }
521 }
522
523-void ApplicationManager::onSessionStopping(const std::shared_ptr<ms::Session>& session)
524+void ApplicationManager::onSessionStopping(const std::shared_ptr<ms::Session>& mirSession)
525 {
526- // in case application closed not by hand of shell, check again here:
527- Application* application = findApplicationWithSession(session);
528-
529- DLOG("ApplicationManager::onSessionStopping (this=%p, application=%p, appId=%s, session name=%s)", this, application,
530- application?qPrintable(application->appId()):"null", session?session->name().c_str():"null");
531-
532- if (application) {
533- /* Can remove the application from the running apps list immediately in these curcumstances:
534- * 1. application is not managed by upstart (this message from Mir is only notice the app has stopped, must do
535- * it here)
536- * 2. application is managed by upstart, but has stopped before it managed to create a surface, we can assume
537- * it crashed on startup, and thus cannot be resumed - so remove it.
538- * 3. application is managed by upstart and is in foreground (i.e. has Running state), if Mir reports the
539- * application disconnects, it either crashed or stopped itself. Either case, remove it.
540- */
541- if (!application->canBeResumed()
542- || application->state() == Application::Starting
543- || application->state() == Application::Running) {
544- checkFocusOnRemovedApplication(application);
545- m_dbusWindowStack->WindowDestroyed(0, application->appId());
546- remove(application);
547- delete application;
548- } else {
549- // otherwise, we do not have enough information to make any changes to the model, so await events from
550- // upstart to go further, but set the app state
551- application->setState(Application::Stopped);
552+ DLOG("ApplicationManager::onSessionStopping (this=%p, session name=%s)", this, mirSession?mirSession->name().c_str():"null");
553+
554+ QSharedPointer<Session> const& session = findSession(mirSession);
555+ if (session) {
556+ Application* application = findApplicationWithSession(mirSession, false); // only check app sessions
557+ if (application) {
558+ /* Can remove the application from the running apps list immediately in these curcumstances:
559+ * 1. application is not managed by upstart (this message from Mir is only notice the app has stopped, must do
560+ * it here)
561+ * 2. application is managed by upstart, but has stopped before it managed to create a surface, we can assume
562+ * it crashed on startup, and thus cannot be resumed - so remove it.
563+ * 3. application is managed by upstart and is in foreground (i.e. has Running state), if Mir reports the
564+ * application disconnects, it either crashed or stopped itself. Either case, remove it.
565+ */
566+ if (!application->canBeResumed()
567+ || application->state() == Application::Starting
568+ || application->state() == Application::Running) {
569+ checkFocusOnRemovedApplication(application);
570+ m_dbusWindowStack->WindowDestroyed(0, application->appId());
571+ remove(application);
572+ delete application;
573+ } else {
574+ // otherwise, we do not have enough information to make any changes to the model, so await events from
575+ // upstart to go further, but set the app state
576+ application->setState(Application::Stopped);
577+ application->setSession(QSharedPointer<Session>());
578+ }
579 }
580+
581+ m_sessions.removeAll(session);
582+ m_fencePIDs.removeOne(mirSession->process_id());
583 }
584 }
585
586-void ApplicationManager::onSessionFocused(const std::shared_ptr<ms::Session>& session)
587+void ApplicationManager::onSessionFocused(const std::shared_ptr<ms::Session>& mirSession)
588 {
589- Application* application = findApplicationWithSession(session);
590+ Application* application = findApplicationWithSession(mirSession, true);
591 DLOG("ApplicationManager::onSessionFocused (this=%p, application=%p, appId=%s, session name=%s)", this, application,
592- application?qPrintable(application->appId()):"null", session?session->name().c_str():"null");
593+ application?qPrintable(application->appId()):"null", mirSession?mirSession->name().c_str():"null");
594
595 // Don't give application focus until it has created it's surface, when it is set as state "Running"
596 // and only notify shell of focus changes that it actually expects
597- if (application && application->state() != Application::Starting &&
598+ if (application && application->state() != Application::Starting &&
599 (application == m_msApplicationToBeFocused ||
600 application == m_ssApplicationToBeFocused)
601 && application != m_focusedApplication) {
602@@ -865,10 +910,14 @@
603 } else {
604 if (application == nullptr) {
605 DLOG("Invalid application focused, discarding the event");
606- if (nullptr != m_focusedApplication)
607+ if (nullptr != m_focusedApplication) {
608 focusApplication(m_focusedApplication->appId());
609- else
610+ } else {
611 m_focusController->set_focus_to(nullptr);
612+ }
613+ } else if (application == m_focusedApplication && mirSession != application->topMirSession()) {
614+ DLOG("Focused session is not on top. Resetting focus");
615+ focusApplication(application->appId());
616 }
617 }
618 }
619@@ -879,7 +928,8 @@
620 if (nullptr != m_focusedApplication) {
621 Q_ASSERT(m_focusedApplication->focused());
622 m_focusedApplication->setFocused(false);
623-
624+
625+ auto lastFocusedApp = m_focusedApplication;
626 suspendApplication(m_focusedApplication);
627
628 m_focusedApplication = nullptr;
629@@ -888,16 +938,20 @@
630
631 QModelIndex appIndex = findIndex(m_focusedApplication);
632 Q_EMIT dataChanged(appIndex, appIndex, QVector<int>() << RoleFocused << RoleState);
633+
634+ if (lastFocusedApp && lastFocusedApp->promptSession()) {
635+ m_promptSessionManager->stop_prompt_session(lastFocusedApp->promptSession()->mirPromptSession());
636+ }
637 }
638 }
639
640 void ApplicationManager::onSessionCreatedSurface(const ms::Session * session,
641 const std::shared_ptr<ms::Surface> & surface)
642 {
643- DLOG("ApplicationManager::onSessionCreatedSurface (this=%p)", this);
644+ DLOG("ApplicationManager::onSessionCreatedSurface (this=%p, appId=%s)", this, session->name().c_str());
645 Q_UNUSED(surface);
646
647- Application* application = findApplicationWithSession(session);
648+ Application* application = findApplicationWithSession(session, true);
649 if (application && application->state() == Application::Starting) {
650 m_dbusWindowStack->WindowCreated(0, application->appId());
651 // only when Session creates a Surface will we actually mark it focused
652@@ -907,6 +961,88 @@
653 }
654 }
655
656+void ApplicationManager::onPromptSessionStarting(std::shared_ptr<ms::PromptSession> const& mirPromptSession)
657+{
658+ DLOG("ApplicationManager::onPromptSessionStarting (this=%p, prompt_session=%p)", this, mirPromptSession.get());
659+
660+ if (auto promptSession = findPromptSession(mirPromptSession.get())) {
661+ DLOG("ApplicationManager::onPromptSessionStarting - prompt session already exists!");
662+ return;
663+ }
664+
665+ QSharedPointer<PromptSession> promptSession(new PromptSession(mirPromptSession, m_promptSessionManager));
666+ m_promptSessions.append(promptSession);
667+
668+ Application* app = findApplicationWithSession(m_promptSessionManager->application_for(mirPromptSession), false);
669+ if (app) {
670+ app->pushPromptSession(promptSession);
671+ } else {
672+ DLOG("ApplicationManager::onPromptSessionStarting - no app found (prompt_session=%p)", mirPromptSession.get());
673+ }
674+}
675+
676+void ApplicationManager::onPromptSessionStopping(std::shared_ptr<ms::PromptSession> const& mirPromptSession)
677+{
678+ DLOG("ApplicationManager::onPromptSessionStopping (this=%p, prompt_session=%p)", this, mirPromptSession.get());
679+
680+ QMutableListIterator<QSharedPointer<PromptSession>> iter(m_promptSessions);
681+ while(iter.hasNext()) {
682+ auto prompt_session = iter.next();
683+ if (prompt_session->mirPromptSession() == mirPromptSession) {
684+
685+ for (Application *app : m_applications) {
686+ // shouldn't happen; but remove all traces of the prompt session.
687+ if (app->promptSession() == prompt_session) {
688+ app->removePromptSession(prompt_session);
689+ }
690+ }
691+ iter.remove();
692+ return;
693+ }
694+ }
695+
696+ DLOG("ApplicationManager::onPromptSessionStopping - prompt session does not exist!");
697+}
698+
699+void ApplicationManager::onPromptProviderAdded(ms::PromptSession const* mirPromptSession,
700+ std::shared_ptr<ms::Session> const& session)
701+{
702+ Q_UNUSED(mirPromptSession);
703+ DLOG("ApplicationManager::onPromptProviderAdded (this=%p, prompt_session=%p, session=%s)", this, mirPromptSession, session?session->name().c_str():"null");
704+
705+ Application* app = findApplicationWithSession(session, true);
706+ if (app) {
707+ app->checkSessionChanges();
708+
709+ if (app == m_focusedApplication) {
710+ focusApplication(app->appId());
711+ }
712+ } else {
713+ DLOG("ApplicationManager::onPromptProviderAdded - no app found (prompt_session=%p)", mirPromptSession);
714+ }
715+}
716+
717+void ApplicationManager::onPromptProviderRemoved(ms::PromptSession const* mirPromptSession,
718+ std::shared_ptr<ms::Session> const& session)
719+{
720+ Q_UNUSED(mirPromptSession);
721+ DLOG("ApplicationManager::onPromptProviderAdded (this=%p, prompt_session=%p, session=%s)", this, (void*)mirPromptSession, session?session->name().c_str():"null");
722+
723+ // we need to update the focus if the app is in focus.
724+ for (Application *app : m_applications) {
725+ QSharedPointer<PromptSession> promptSession = app->promptSession();
726+ if (promptSession && promptSession->mirPromptSession().get() == mirPromptSession) {
727+ if (app->hasChildProcess(session->process_id())) {
728+ app->checkSessionChanges();
729+
730+ if (app == m_focusedApplication) {
731+ focusApplication(app->appId());
732+ }
733+ }
734+ }
735+ }
736+}
737+
738 void ApplicationManager::setFocused(Application *application)
739 {
740 DLOG("ApplicationManager::setFocused (application=%p, appId=%s)", application, qPrintable(application->appId()));
741@@ -926,6 +1062,7 @@
742 else
743 m_sideStageApplication = application;
744
745+ auto lastFocusedApp = m_focusedApplication;
746 m_focusedApplication = application;
747 m_focusedApplication->setFocused(true);
748 m_focusedApplication->setVisible(true);
749@@ -933,24 +1070,25 @@
750 move(m_applications.indexOf(application), 0);
751 Q_EMIT focusedApplicationIdChanged();
752 m_dbusWindowStack->FocusedWindowChanged(0, application->appId(), application->stage());
753-}
754-
755-Application* ApplicationManager::findApplicationWithSession(const std::shared_ptr<ms::Session> &session)
756-{
757- return findApplicationWithSession(session.get());
758-}
759-
760-Application* ApplicationManager::findApplicationWithSession(const ms::Session *session)
761-{
762- for (Application *app : m_applications) {
763- if (app->session().get() == session) {
764- return app;
765- }
766+
767+ // stop prompt session when focus changes.
768+ if (lastFocusedApp && lastFocusedApp->promptSession()) {
769+ m_promptSessionManager->stop_prompt_session(lastFocusedApp->promptSession()->mirPromptSession());
770 }
771- return nullptr;
772-}
773-
774-Application* ApplicationManager::findApplicationWithPid(const qint64 pid)
775+}
776+
777+Application* ApplicationManager::findApplicationWithSession(const std::shared_ptr<ms::Session> &session, bool checkSessions)
778+{
779+ return findApplicationWithSession(session.get(), checkSessions);
780+}
781+
782+Application* ApplicationManager::findApplicationWithSession(const ms::Session *session, bool checkSessions)
783+{
784+ if (!session) { return NULL; }
785+ return findApplicationWithPid(session->process_id(), checkSessions);
786+}
787+
788+Application* ApplicationManager::findApplicationWithPid(const qint64 pid, bool checkSessions)
789 {
790 if (pid <= 0)
791 return nullptr;
792@@ -959,10 +1097,43 @@
793 if (app->m_pid == pid) {
794 return app;
795 }
796+
797+ if (checkSessions && app->hasChildProcess(pid)) {
798+ return app;
799+ }
800 }
801 return nullptr;
802 }
803
804+QSharedPointer<PromptSession> ApplicationManager::findPromptSession(ms::PromptSession const* mirPromptSession)
805+{
806+ QListIterator<QSharedPointer<PromptSession>> iter(m_promptSessions);
807+ while(iter.hasNext()) {
808+ auto promptSession = iter.next();
809+ if (promptSession->mirPromptSession().get() == mirPromptSession) {
810+ return promptSession;
811+ }
812+ }
813+ return QSharedPointer<PromptSession>();
814+}
815+
816+QSharedPointer<Session> ApplicationManager::findSession(const std::shared_ptr<mir::scene::Session> &mirSession)
817+{
818+ return findSession(mirSession.get());
819+}
820+
821+QSharedPointer<Session> ApplicationManager::findSession(const mir::scene::Session *mirSession)
822+{
823+ QListIterator<QSharedPointer<Session>> iter(m_sessions);
824+ while(iter.hasNext()) {
825+ auto localSession = iter.next();
826+ if (localSession->mirSession().get() == mirSession) {
827+ return localSession;
828+ }
829+ }
830+ return QSharedPointer<Session>();
831+}
832+
833 Application* ApplicationManager::applicationForStage(Application::Stage stage)
834 {
835 DLOG("ApplicationManager::focusedApplicationForStage(this=%p)", this);
836@@ -1007,7 +1178,8 @@
837 }
838 }
839
840-void ApplicationManager::move(int from, int to) {
841+void ApplicationManager::move(int from, int to)
842+{
843 DLOG("ApplicationManager::move (this=%p, from=%d, to=%d)", this, from, to);
844 if (from == to) return;
845
846@@ -1037,11 +1209,28 @@
847 {
848 if (application == m_focusedApplication) {
849 // TODO(greyback) What to do?? Focus next app, or unfocus everything??
850+ auto lastFocusedApp = m_focusedApplication;
851 m_focusedApplication = nullptr;
852 Q_EMIT focusedApplicationIdChanged();
853+
854+ // stop prompt session when focus changes.
855+ if (lastFocusedApp && lastFocusedApp->promptSession()) {
856+ m_promptSessionManager->stop_prompt_session(lastFocusedApp->promptSession()->mirPromptSession());
857+ }
858+
859 return true;
860 }
861 return false;
862 }
863
864+void ApplicationManager::onApplicationTopSessionChanged()
865+{
866+ Application* application = qobject_cast<Application*>(sender());
867+ if (application) {
868+ application->updateScreenshot();
869+ QModelIndex appIndex = findIndex(application);
870+ Q_EMIT dataChanged(appIndex, appIndex, QVector<int>() << RoleScreenshot);
871+ }
872+}
873+
874 } // namespace unitymir
875
876=== modified file 'src/modules/Unity/Application/application_manager.h'
877--- src/modules/Unity/Application/application_manager.h 2014-05-26 15:54:44 +0000
878+++ src/modules/Unity/Application/application_manager.h 2014-06-17 15:53:01 +0000
879@@ -41,6 +41,9 @@
880 namespace scene {
881 class Session;
882 class Surface;
883+ class PromptSession;
884+ class PromptSessionManager;
885+
886 }
887 namespace shell {
888 class FocusController;
889@@ -55,6 +58,7 @@
890 class MirSurfaceManager;
891 class TaskController;
892 class ProcInfo;
893+class PromptSession;
894
895 class ApplicationManager : public unity::shell::application::ApplicationManagerInterface
896 {
897@@ -79,7 +83,8 @@
898 explicit ApplicationManager(const QSharedPointer<TaskController>& taskController,
899 const QSharedPointer<DesktopFileReader::Factory>& desktopFileReaderFactory,
900 const QSharedPointer<ProcInfo>& processInfo,
901- std::shared_ptr<mir::shell::FocusController> const& controller,
902+ std::shared_ptr<mir::shell::FocusController> const& focusController,
903+ const std::shared_ptr<mir::scene::PromptSessionManager>& promptSessionManager,
904 QSize const& displaySize,
905 QObject *parent = 0);
906 virtual ~ApplicationManager();
907@@ -106,7 +111,7 @@
908 Q_INVOKABLE void move(int from, int to);
909
910 const QList<Application*> &list() const { return m_applications; }
911- unitymir::Application* findApplicationWithPid(const qint64 pid);
912+ Application* findApplicationWithPid(const qint64 pid, bool checkSessions);
913
914 // Internal helpers
915 bool suspendApplication(Application *application);
916@@ -117,12 +122,17 @@
917 public Q_SLOTS:
918 void authorizeSession(const quint64 pid, bool &authorized);
919 void placeSession(::mir::scene::Session const*, uint32_t &x, uint32_t &y);
920-
921+
922 void onSessionStarting(std::shared_ptr<::mir::scene::Session> const& session);
923 void onSessionStopping(std::shared_ptr<::mir::scene::Session> const& session);
924 void onSessionFocused(std::shared_ptr<::mir::scene::Session> const& session);
925 void onSessionUnfocused();
926
927+ void onPromptSessionStarting(std::shared_ptr<mir::scene::PromptSession> const& promptSession);
928+ void onPromptSessionStopping(std::shared_ptr<mir::scene::PromptSession> const& promptSession);
929+ void onPromptProviderAdded(mir::scene::PromptSession const* promptSession, std::shared_ptr<mir::scene::Session> const& session);
930+ void onPromptProviderRemoved(mir::scene::PromptSession const* promptSession, std::shared_ptr<mir::scene::Session> const& session);
931+
932 void onSessionCreatedSurface(::mir::scene::Session const*, std::shared_ptr<::mir::scene::Surface> const&);
933
934 void onProcessFailed(const QString& appId, const bool duringStartup);
935@@ -131,6 +141,8 @@
936 void onFocusRequested(const QString& appId);
937 void onResumeRequested(const QString& appId);
938
939+ void onApplicationTopSessionChanged();
940+
941 Q_SIGNALS:
942 void focusRequested(const QString &appId);
943
944@@ -141,27 +153,34 @@
945 void setFocused(Application *application);
946 void add(Application *application);
947 void remove(Application* application);
948- Application* findApplicationWithSession(const std::shared_ptr<::mir::scene::Session> &session);
949- Application* findApplicationWithSession(const ::mir::scene::Session *session);
950+ Application* findApplicationWithSession(const std::shared_ptr<mir::scene::Session> &session, bool checkSessions);
951+ Application* findApplicationWithSession(const mir::scene::Session *session, bool checkSessions);
952 Application* applicationForStage(Application::Stage stage);
953 QModelIndex findIndex(Application* application);
954+ QSharedPointer<PromptSession> findPromptSession(mir::scene::PromptSession const* prompt_session);
955 bool isFocused(Application* application);
956 bool checkFocusOnRemovedApplication(Application *application);
957
958+ QSharedPointer<Session> findSession(const std::shared_ptr<mir::scene::Session> &session);
959+ QSharedPointer<Session> findSession(const mir::scene::Session *session);
960+
961 QList<Application*> m_applications;
962+ QList<QSharedPointer<Session>> m_sessions;
963+ QList<QSharedPointer<PromptSession>> m_promptSessions;
964 Application* m_focusedApplication; // remove as Mir has API for this
965 Application* m_mainStageApplication;
966 Application* m_sideStageApplication;
967 Application* m_msApplicationToBeFocused; // placeholder store for async focusing
968 Application* m_ssApplicationToBeFocused; // placeholder store for async focusing
969 QStringList m_lifecycleExceptions;
970- std::shared_ptr<mir::shell::FocusController> m_focusController;
971+ std::shared_ptr<mir::shell::FocusController> const m_focusController;
972+ std::shared_ptr<mir::scene::PromptSessionManager> const m_promptSessionManager;
973 DBusWindowStack* m_dbusWindowStack;
974 QSharedPointer<TaskController> m_taskController;
975 QSharedPointer<DesktopFileReader::Factory> m_desktopFileReaderFactory;
976 QSharedPointer<ProcInfo> m_procInfo;
977 int m_gridUnitPx;
978- bool m_fenceNext;
979+ QList<pid_t> m_fencePIDs;
980 QString m_nextFocusedAppId;
981 QSize m_displaySize;
982 int m_panelHeight;
983
984=== modified file 'src/modules/Unity/Application/applicationscreenshotprovider.cpp'
985--- src/modules/Unity/Application/applicationscreenshotprovider.cpp 2014-04-15 14:31:02 +0000
986+++ src/modules/Unity/Application/applicationscreenshotprovider.cpp 2014-06-17 15:53:01 +0000
987@@ -52,7 +52,8 @@
988
989 // TODO: if app not ready, return an app-provided splash image. If app has been stopped with saved state
990 // return the screenshot that was saved to disk.
991- if (!app->session() || !app->session()->default_surface()) {
992+ auto mirSession = app->topMirSession();
993+ if (!mirSession || !mirSession->default_surface()) {
994 LOG("ApplicationScreenshotProvider - app session not found - asking for screenshot too early");
995 return QImage();
996 }
997
998=== modified file 'src/modules/Unity/Application/dbuswindowstack.cpp'
999--- src/modules/Unity/Application/dbuswindowstack.cpp 2014-03-11 03:40:49 +0000
1000+++ src/modules/Unity/Application/dbuswindowstack.cpp 2014-06-17 15:53:01 +0000
1001@@ -47,7 +47,7 @@
1002 {
1003 AppIdDesktopFile res;
1004 ApplicationManager *appMgr = static_cast<ApplicationManager*>(parent());
1005- const Application* app = static_cast<Application*>(appMgr->findApplicationWithPid(pid));
1006+ const Application* app = static_cast<Application*>(appMgr->findApplicationWithPid(pid, false));
1007 if (app) {
1008 res.app_id = app->appId();
1009 res.desktop_file = app->desktopFile();
1010
1011=== modified file 'src/modules/Unity/Application/mirsurface.cpp'
1012--- src/modules/Unity/Application/mirsurface.cpp 2014-04-15 14:31:02 +0000
1013+++ src/modules/Unity/Application/mirsurface.cpp 2014-06-17 15:53:01 +0000
1014@@ -30,10 +30,10 @@
1015 namespace unitymir
1016 {
1017
1018-MirSurface::MirSurface(std::shared_ptr<mir::scene::Surface> surface, Application* application, QQuickItem *parent)
1019+MirSurface::MirSurface(std::shared_ptr<mir::scene::Surface> surface, QSharedPointer<Session> const& session, QQuickItem *parent)
1020 : QQuickItem(parent)
1021 , m_surface(surface)
1022- , m_application(application)
1023+ , m_session(session)
1024 {
1025 DLOG("MirSurface::MirSurface");
1026 setFlag(QQuickItem::ItemHasContents, false); //so scene graph will not render this item
1027@@ -44,9 +44,9 @@
1028 m_inputAreas.clear();
1029 }
1030
1031-Application* MirSurface::application() const
1032+QSharedPointer<Session> MirSurface::session() const
1033 {
1034- return m_application;
1035+ return m_session;
1036 }
1037
1038 qreal MirSurface::x() const
1039
1040=== modified file 'src/modules/Unity/Application/mirsurface.h'
1041--- src/modules/Unity/Application/mirsurface.h 2014-04-15 14:31:02 +0000
1042+++ src/modules/Unity/Application/mirsurface.h 2014-06-17 15:53:01 +0000
1043@@ -31,7 +31,7 @@
1044 {
1045 class MirSurfaceManager;
1046 class InputArea;
1047-class Application;
1048+class Session;
1049
1050 class MirSurface : public QQuickItem
1051 {
1052@@ -50,7 +50,7 @@
1053 Q_PROPERTY(QString name READ name NOTIFY nameChanged)
1054
1055 public:
1056- explicit MirSurface(std::shared_ptr<mir::scene::Surface> surface, Application* application, QQuickItem *parent = 0);
1057+ explicit MirSurface(std::shared_ptr<mir::scene::Surface> surface, QSharedPointer<Session> const& session, QQuickItem *parent = 0);
1058 ~MirSurface();
1059
1060 enum Type {
1061@@ -73,7 +73,7 @@
1062 };
1063
1064 //getters
1065- Application* application() const;
1066+ QSharedPointer<Session> session() const;
1067 Type type() const;
1068 State state() const;
1069 QString name() const;
1070@@ -124,7 +124,7 @@
1071
1072 bool m_visible = true; //FIXME(greyback) state should be in Mir::scene::Surface, not here
1073
1074- Application* m_application;
1075+ QSharedPointer<Session> m_session;
1076
1077 friend class MirSurfaceManager;
1078 friend class InputArea;
1079
1080=== modified file 'src/modules/Unity/Application/mirsurfacemanager.cpp'
1081--- src/modules/Unity/Application/mirsurfacemanager.cpp 2014-04-15 14:31:02 +0000
1082+++ src/modules/Unity/Application/mirsurfacemanager.cpp 2014-06-17 15:53:01 +0000
1083@@ -29,6 +29,7 @@
1084 #include "surfaceconfigurator.h"
1085 #include "focussetter.h"
1086 #include "logging.h"
1087+#include "session.h"
1088
1089 // mir
1090 #include <mir/scene/session.h>
1091@@ -106,11 +107,15 @@
1092 {
1093 DLOG("MirSurfaceManager::sessionCreatedSurface (this=%p) with surface name '%s'", this, surface->name().c_str());
1094 ApplicationManager* appMgr = static_cast<ApplicationManager*>(ApplicationManager::singleton());
1095- Application* application = appMgr->findApplicationWithSession(session);
1096-
1097- auto qmlSurface = new MirSurface(surface, application);
1098+
1099+ auto qmlSurface = new MirSurface(surface, appMgr->findSession(session));
1100 m_surfaces.insert(surface.get(), qmlSurface);
1101 Q_EMIT surfaceCreated(qmlSurface);
1102+
1103+ Application* application = appMgr->findApplicationWithSession(session, true);
1104+ if (application) {
1105+ application->checkSessionChanges();
1106+ }
1107 }
1108
1109 void MirSurfaceManager::sessionDestroyingSurface(mir::scene::Session const*, std::shared_ptr<mir::scene::Surface> const& surface)
1110@@ -131,13 +136,13 @@
1111 void MirSurfaceManager::shellSurfaceCreated(const std::shared_ptr<ms::Surface> &surface)
1112 {
1113 DLOG("MirSurfaceManager::shellSurfaceCreated (this=%p)", this);
1114- m_shellSurface = new MirSurface(surface, nullptr);
1115+ m_shellSurface = new MirSurface(surface, QSharedPointer<Session>());
1116
1117 FocusSetter *fs = m_mirServer->focusSetter();
1118 if (fs) {
1119 fs->set_default_keyboard_target(surface);
1120 }
1121-
1122+
1123 Q_EMIT shellSurfaceChanged(m_shellSurface);
1124 }
1125
1126@@ -148,18 +153,26 @@
1127
1128 auto it = m_surfaces.find(surface);
1129 if (it != m_surfaces.end()) {
1130- it.value()->setAttribute(attribute, value);
1131+ auto const& surface = it.value();
1132+
1133+ surface->setAttribute(attribute, value);
1134 if (attribute == mir_surface_attrib_state &&
1135 value == mir_surface_state_fullscreen) {
1136+
1137 // Only screen-wide applications are allowed to go fullscreen
1138- if (it.value()->application()->stage() == Application::MainStage) {
1139- it.value()->application()->setFullscreen(static_cast<bool>(value));
1140+ if (surface->session()) {
1141 ApplicationManager* appMgr = static_cast<ApplicationManager*>(ApplicationManager::singleton());
1142- QSize displaySize = appMgr->displaySize();
1143- it.value()->setWidth(displaySize.width());
1144- it.value()->setHeight(displaySize.height());
1145- it.value()->setX(0);
1146- it.value()->setY(0);
1147+ Application* application = appMgr->findApplicationWithSession(surface->session()->mirSession(), true);
1148+
1149+ if (application && application->stage() == Application::MainStage) {
1150+ application->setFullscreen(static_cast<bool>(value));
1151+ ApplicationManager* appMgr = static_cast<ApplicationManager*>(ApplicationManager::singleton());
1152+ QSize displaySize = appMgr->displaySize();
1153+ surface->setWidth(displaySize.width());
1154+ surface->setHeight(displaySize.height());
1155+ surface->setX(0);
1156+ surface->setY(0);
1157+ }
1158 }
1159 }
1160 }
1161
1162=== modified file 'src/modules/Unity/Application/proc_info.cpp'
1163--- src/modules/Unity/Application/proc_info.cpp 2014-03-11 19:11:00 +0000
1164+++ src/modules/Unity/Application/proc_info.cpp 2014-06-17 15:53:01 +0000
1165@@ -33,6 +33,24 @@
1166
1167 return std::unique_ptr<CommandLine>(new CommandLine{ cmdline.readLine().replace('\0', ' ') });
1168 }
1169+
1170+quint64 ProcInfo::ppid(quint64 pid)
1171+{
1172+ QFile stats(QString("/proc/%1/stat").arg(pid));
1173+ if (!stats.open(QIODevice::ReadOnly | QIODevice::Text)) {
1174+ return 0;
1175+ }
1176+
1177+ int pidThis;
1178+ char comm[128] = {0};
1179+ char state;
1180+ int ppid;
1181+
1182+ sscanf(stats.readLine().data(), "%d %s %c %d", &pidThis, &comm[0], &state, &ppid);
1183+
1184+ return ppid;
1185+}
1186+
1187 QStringList ProcInfo::CommandLine::asStringList() const {
1188 return QString(m_command.data()).split(' ');
1189 }
1190
1191=== modified file 'src/modules/Unity/Application/proc_info.h'
1192--- src/modules/Unity/Application/proc_info.h 2014-03-11 19:11:00 +0000
1193+++ src/modules/Unity/Application/proc_info.h 2014-06-17 15:53:01 +0000
1194@@ -45,6 +45,9 @@
1195 QStringList asStringList() const;
1196 };
1197 virtual std::unique_ptr<CommandLine> commandLine(quint64 pid);
1198+
1199+ virtual quint64 ppid(quint64 pid);
1200+
1201 virtual ~ProcInfo();
1202 };
1203
1204
1205=== added file 'src/modules/Unity/Application/promptsession.cpp'
1206--- src/modules/Unity/Application/promptsession.cpp 1970-01-01 00:00:00 +0000
1207+++ src/modules/Unity/Application/promptsession.cpp 2014-06-17 15:53:01 +0000
1208@@ -0,0 +1,74 @@
1209+/*
1210+ * Copyright (C) 2014 Canonical, Ltd.
1211+ *
1212+ * This program is free software: you can redistribute it and/or modify it under
1213+ * the terms of the GNU Lesser General Public License version 3, as published by
1214+ * the Free Software Foundation.
1215+ *
1216+ * This program is distributed in the hope that it will be useful, but WITHOUT
1217+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
1218+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1219+ * Lesser General Public License for more details.
1220+ *
1221+ * You should have received a copy of the GNU Lesser General Public License
1222+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1223+ */
1224+
1225+#include "promptsession.h"
1226+
1227+// mir
1228+#include <mir/scene/prompt_session.h>
1229+#include <mir/scene/prompt_session_manager.h>
1230+#include <mir/scene/session.h>
1231+#include <QDebug>
1232+
1233+namespace unitymir
1234+{
1235+
1236+PromptSession::PromptSession(const std::shared_ptr<mir::scene::PromptSession>& promptSession, const std::shared_ptr<mir::scene::PromptSessionManager>& promptSessionManager)
1237+: m_promptSession(promptSession)
1238+, m_promptSessionManager(promptSessionManager)
1239+{
1240+}
1241+
1242+PromptSession::~PromptSession()
1243+{
1244+}
1245+
1246+std::shared_ptr<mir::scene::PromptSession> PromptSession::mirPromptSession() const
1247+{
1248+ return m_promptSession;
1249+}
1250+
1251+std::shared_ptr<mir::scene::Session> PromptSession::topProvider() const
1252+{
1253+ std::shared_ptr<mir::scene::Session> child;
1254+ if (m_promptSession) {
1255+ m_promptSessionManager->for_each_provider_in(m_promptSession,
1256+ [&child](std::shared_ptr<mir::scene::Session> const& provider) {
1257+ child = provider;
1258+ });
1259+ }
1260+ return child;
1261+}
1262+
1263+bool PromptSession::hasChildProcess(pid_t pid) const
1264+{
1265+ if (!m_promptSession) {
1266+ return false;
1267+ }
1268+
1269+ auto helper = m_promptSessionManager->helper_for(m_promptSession);
1270+ if (helper && helper->process_id() == pid)
1271+ return true;
1272+
1273+ bool found = false;
1274+ m_promptSessionManager->for_each_provider_in(m_promptSession,
1275+ [&](std::shared_ptr<mir::scene::Session> const& provider) {
1276+ if (provider->process_id() == pid)
1277+ found = true;
1278+ });
1279+ return found;
1280+}
1281+
1282+}
1283
1284=== added file 'src/modules/Unity/Application/promptsession.h'
1285--- src/modules/Unity/Application/promptsession.h 1970-01-01 00:00:00 +0000
1286+++ src/modules/Unity/Application/promptsession.h 2014-06-17 15:53:01 +0000
1287@@ -0,0 +1,62 @@
1288+/*
1289+ * Copyright (C) 2014 Canonical, Ltd.
1290+ *
1291+ * This program is free software: you can redistribute it and/or modify it under
1292+ * the terms of the GNU Lesser General Public License version 3, as published by
1293+ * the Free Software Foundation.
1294+ *
1295+ * This program is distributed in the hope that it will be useful, but WITHOUT
1296+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
1297+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1298+ * Lesser General Public License for more details.
1299+ *
1300+ * You should have received a copy of the GNU Lesser General Public License
1301+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1302+ */
1303+
1304+#ifndef PROMPT_SESSION_H
1305+#define PROMPT_SESSION_H
1306+
1307+// std
1308+#include <memory>
1309+
1310+// Mir
1311+#include <mir_toolkit/common.h>
1312+
1313+ // Qt
1314+#include <QSharedPointer>
1315+
1316+namespace mir
1317+{
1318+namespace scene
1319+{
1320+class Session;
1321+class PromptSession;
1322+class PromptSessionManager;
1323+}
1324+}
1325+
1326+namespace unitymir
1327+{
1328+
1329+class PromptSession {
1330+public:
1331+ PromptSession(const std::shared_ptr<mir::scene::PromptSession>& promptSession,
1332+ const std::shared_ptr<mir::scene::PromptSessionManager>& promptSessionManager);
1333+ virtual ~PromptSession();
1334+
1335+ std::shared_ptr<mir::scene::PromptSession> mirPromptSession() const;
1336+ std::shared_ptr<mir::scene::Session> topProvider() const;
1337+
1338+ bool hasChildProcess(pid_t pid) const;
1339+
1340+private:
1341+ std::shared_ptr<mir::scene::PromptSession> const m_promptSession;
1342+ std::shared_ptr<mir::scene::PromptSessionManager> const m_promptSessionManager;
1343+};
1344+
1345+} // namespace unity-mir
1346+
1347+Q_DECLARE_METATYPE(unitymir::PromptSession*)
1348+
1349+#endif // PROMPT_SESSION_H
1350
1351=== added file 'src/modules/Unity/Application/session.cpp'
1352--- src/modules/Unity/Application/session.cpp 1970-01-01 00:00:00 +0000
1353+++ src/modules/Unity/Application/session.cpp 2014-06-17 15:53:01 +0000
1354@@ -0,0 +1,54 @@
1355+/*
1356+ * Copyright (C) 2014 Canonical, Ltd.
1357+ *
1358+ * This program is free software: you can redistribute it and/or modify it under
1359+ * the terms of the GNU Lesser General Public License version 3, as published by
1360+ * the Free Software Foundation.
1361+ *
1362+ * This program is distributed in the hope that it will be useful, but WITHOUT
1363+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
1364+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1365+ * Lesser General Public License for more details.
1366+ *
1367+ * You should have received a copy of the GNU Lesser General Public License
1368+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1369+ */
1370+
1371+#include "session.h"
1372+
1373+// mir
1374+#include <mir/scene/session.h>
1375+
1376+namespace unitymir
1377+{
1378+
1379+Session::Session(const std::shared_ptr<mir::scene::Session>& session)
1380+: m_session(session)
1381+{
1382+}
1383+
1384+Session::~Session()
1385+{
1386+}
1387+
1388+std::shared_ptr<mir::scene::Session> Session::mirSession() const
1389+{
1390+ return m_session;
1391+}
1392+
1393+void Session::setLifecycleState(MirLifecycleState state)
1394+{
1395+ m_session->set_lifecycle_state(state);
1396+}
1397+
1398+void Session::hide()
1399+{
1400+ m_session->hide();
1401+}
1402+
1403+void Session::show()
1404+{
1405+ m_session->show();
1406+}
1407+
1408+}
1409
1410=== added file 'src/modules/Unity/Application/session.h'
1411--- src/modules/Unity/Application/session.h 1970-01-01 00:00:00 +0000
1412+++ src/modules/Unity/Application/session.h 2014-06-17 15:53:01 +0000
1413@@ -0,0 +1,53 @@
1414+/*
1415+ * Copyright (C) 2014 Canonical, Ltd.
1416+ *
1417+ * This program is free software: you can redistribute it and/or modify it under
1418+ * the terms of the GNU Lesser General Public License version 3, as published by
1419+ * the Free Software Foundation.
1420+ *
1421+ * This program is distributed in the hope that it will be useful, but WITHOUT
1422+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
1423+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1424+ * Lesser General Public License for more details.
1425+ *
1426+ * You should have received a copy of the GNU Lesser General Public License
1427+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1428+ */
1429+
1430+#ifndef SESSION_H
1431+#define SESSION_H
1432+
1433+// std
1434+#include <memory>
1435+
1436+// Mir
1437+#include <mir_toolkit/common.h>
1438+
1439+ // Qt
1440+#include <QSharedPointer>
1441+
1442+namespace mir { namespace scene { class Session; }}
1443+
1444+namespace unitymir
1445+{
1446+
1447+class Session {
1448+public:
1449+ Session(const std::shared_ptr<mir::scene::Session>& session);
1450+ virtual ~Session();
1451+
1452+ std::shared_ptr<mir::scene::Session> mirSession() const;
1453+
1454+ void setLifecycleState(MirLifecycleState state);
1455+ void hide();
1456+ void show();
1457+
1458+private:
1459+ std::shared_ptr<mir::scene::Session> m_session;
1460+};
1461+
1462+} // namespace unity-mir
1463+
1464+Q_DECLARE_METATYPE(unitymir::Session*)
1465+
1466+#endif // SESSION_H
1467
1468=== modified file 'src/unity-mir/CMakeLists.txt'
1469--- src/unity-mir/CMakeLists.txt 2014-05-22 21:37:02 +0000
1470+++ src/unity-mir/CMakeLists.txt 2014-06-17 15:53:01 +0000
1471@@ -28,6 +28,7 @@
1472 logging.h
1473 focussetter.h
1474 serverstatuslistener.h
1475+ promptsessionlistener.h
1476 ${GENERATED_PROTOBUF_HDRS}
1477 )
1478
1479@@ -47,6 +48,7 @@
1480 unityprotobufservice.cpp
1481 focussetter.cpp
1482 serverstatuslistener.cpp
1483+ promptsessionlistener.cpp
1484
1485 ${UNITY_MIR_HEADERS}
1486 ${GENERATED_PROTOBUF_SRCS}
1487
1488=== modified file 'src/unity-mir/focussetter.cpp'
1489--- src/unity-mir/focussetter.cpp 2014-04-15 14:31:02 +0000
1490+++ src/unity-mir/focussetter.cpp 2014-06-17 15:53:01 +0000
1491@@ -15,6 +15,7 @@
1492 */
1493
1494 #include <mir/scene/surface.h>
1495+#include <mir/scene/session.h>
1496
1497 #include "focussetter.h"
1498 #include "logging.h"
1499@@ -35,7 +36,7 @@
1500
1501 void FocusSetter::set_focus_to(std::shared_ptr<ms::Session> const& session)
1502 {
1503- DLOG("FocusSetter::set_focus_to(session=%p):%d", session.get(), __LINE__);
1504+ DLOG("FocusSetter::set_focus_to(session=%p, session name=%s):%d", session.get(), session?session->name().c_str():"null", __LINE__);
1505 // Ensure we always call the underlying setter to dispatch focus/unfocus notifications.
1506 underlying_setter->set_focus_to(session);
1507 if (session == nullptr)
1508@@ -53,6 +54,6 @@
1509 assert(t);
1510
1511 default_keyboard_target = default_target;
1512-
1513+
1514 t->take_input_focus(keyboard_input_targeter);
1515 }
1516
1517=== added file 'src/unity-mir/promptsessionlistener.cpp'
1518--- src/unity-mir/promptsessionlistener.cpp 1970-01-01 00:00:00 +0000
1519+++ src/unity-mir/promptsessionlistener.cpp 2014-06-17 15:53:01 +0000
1520@@ -0,0 +1,60 @@
1521+/*
1522+ * Copyright (C) 2013 Canonical, Ltd.
1523+ *
1524+ * This program is free software: you can redistribute it and/or modify it under
1525+ * the terms of the GNU Lesser General Public License version 3, as published by
1526+ * the Free Software Foundation.
1527+ *
1528+ * This program is distributed in the hope that it will be useful, but WITHOUT
1529+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
1530+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1531+ * Lesser General Public License for more details.
1532+ *
1533+ * You should have received a copy of the GNU Lesser General Public License
1534+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1535+ */
1536+
1537+#include "promptsessionlistener.h"
1538+#include "logging.h"
1539+
1540+#include <QThread>
1541+
1542+namespace ms = mir::scene;
1543+
1544+Q_DECLARE_METATYPE(std::shared_ptr<ms::PromptSession>)
1545+
1546+PromptSessionListener::PromptSessionListener(QObject *parent) :
1547+ QObject(parent)
1548+{
1549+ DLOG("PromptSessionListener::PromptSessionListener (this=%p)", this);
1550+ qRegisterMetaType<std::shared_ptr<ms::PromptSession>>("std::shared_ptr<mir::scene::PromptSession>");
1551+}
1552+
1553+PromptSessionListener::~PromptSessionListener()
1554+{
1555+ DLOG("PromptSessionListener::~PromptSessionListener (this=%p)", this);
1556+}
1557+
1558+void PromptSessionListener::starting(std::shared_ptr<ms::PromptSession> const& prompt_session)
1559+{
1560+ DLOG("PromptSessionListener::starting (this=%p, prompt_session=%p)", this, (void*)prompt_session.get());
1561+ Q_EMIT promptSessionStarting(prompt_session);
1562+}
1563+
1564+void PromptSessionListener::stopping(std::shared_ptr<ms::PromptSession> const& prompt_session)
1565+{
1566+ DLOG("PromptSessionListener::stopping (this=%p, prompt_session=%p)", this, (void*)prompt_session.get());
1567+ Q_EMIT promptSessionStopping(prompt_session);
1568+}
1569+
1570+void PromptSessionListener::prompt_provider_added(ms::PromptSession const& prompt_session, std::shared_ptr<ms::Session> const& prompt_provider)
1571+{
1572+ DLOG("PromptSessionListener::prompt_provider_added (this=%p, prompt_session=%p, prompt_provider=%p)", this, &prompt_session, (void*)prompt_provider.get());
1573+ Q_EMIT promptProviderAdded(&prompt_session, prompt_provider);
1574+}
1575+
1576+void PromptSessionListener::prompt_provider_removed(ms::PromptSession const& prompt_session, std::shared_ptr<ms::Session> const& prompt_provider)
1577+{
1578+ DLOG("PromptSessionListener::prompt_provider_removed (this=%p, prompt_session=%p, prompt_provider=%p)", this, &prompt_session, (void*)prompt_provider.get());
1579+ Q_EMIT promptProviderRemoved(&prompt_session, prompt_provider);
1580+}
1581
1582=== added file 'src/unity-mir/promptsessionlistener.h'
1583--- src/unity-mir/promptsessionlistener.h 1970-01-01 00:00:00 +0000
1584+++ src/unity-mir/promptsessionlistener.h 2014-06-17 15:53:01 +0000
1585@@ -0,0 +1,45 @@
1586+/*
1587+ * Copyright (C) 2014 Canonical, Ltd.
1588+ *
1589+ * This program is free software: you can redistribute it and/or modify it under
1590+ * the terms of the GNU Lesser General Public License version 3, as published by
1591+ * the Free Software Foundation.
1592+ *
1593+ * This program is distributed in the hope that it will be useful, but WITHOUT
1594+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
1595+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1596+ * Lesser General Public License for more details.
1597+ *
1598+ * You should have received a copy of the GNU Lesser General Public License
1599+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1600+ */
1601+
1602+#ifndef PROMPTSESSIONLISTENER_H
1603+#define PROMPTSESSIONLISTENER_H
1604+
1605+#include <QObject>
1606+
1607+#include "mir/scene/prompt_session_listener.h"
1608+
1609+class PromptSessionListener : public QObject, public mir::scene::PromptSessionListener
1610+{
1611+ Q_OBJECT
1612+public:
1613+ explicit PromptSessionListener(QObject *parent = 0);
1614+ ~PromptSessionListener();
1615+
1616+ void starting(std::shared_ptr<mir::scene::PromptSession> const& prompt_session) override;
1617+ void stopping(std::shared_ptr<mir::scene::PromptSession> const& prompt_session) override;
1618+
1619+ void prompt_provider_added(mir::scene::PromptSession const& prompt_session, std::shared_ptr<mir::scene::Session> const& prompt_provider) override;
1620+ void prompt_provider_removed(mir::scene::PromptSession const& prompt_session, std::shared_ptr<mir::scene::Session> const& prompt_provider) override;
1621+
1622+Q_SIGNALS:
1623+ void promptSessionStarting(std::shared_ptr<mir::scene::PromptSession> const& session);
1624+ void promptSessionStopping(std::shared_ptr<mir::scene::PromptSession> const& session);
1625+
1626+ void promptProviderAdded(mir::scene::PromptSession const*, std::shared_ptr<mir::scene::Session> const&);
1627+ void promptProviderRemoved(mir::scene::PromptSession const*, std::shared_ptr<mir::scene::Session> const&);
1628+};
1629+
1630+#endif // SESSIONLISTENER_H
1631
1632=== modified file 'src/unity-mir/qmirserver.cpp'
1633--- src/unity-mir/qmirserver.cpp 2014-06-10 19:51:56 +0000
1634+++ src/unity-mir/qmirserver.cpp 2014-06-17 15:53:01 +0000
1635@@ -34,6 +34,7 @@
1636 #include <chrono>
1637 #include <csignal>
1638 #include <thread>
1639+#include <unistd.h>
1640
1641 // local
1642 #include "logging.h"
1643
1644=== modified file 'src/unity-mir/sessionauthorizer.cpp'
1645--- src/unity-mir/sessionauthorizer.cpp 2014-05-08 03:50:31 +0000
1646+++ src/unity-mir/sessionauthorizer.cpp 2014-06-17 15:53:01 +0000
1647@@ -54,4 +54,3 @@
1648 Q_UNUSED(creds)
1649 return true;
1650 }
1651-
1652
1653=== modified file 'src/unity-mir/shellserverconfiguration.cpp'
1654--- src/unity-mir/shellserverconfiguration.cpp 2014-05-08 03:50:31 +0000
1655+++ src/unity-mir/shellserverconfiguration.cpp 2014-06-17 15:53:01 +0000
1656@@ -24,6 +24,7 @@
1657 #include "sessionlistener.h"
1658 #include "surfaceconfigurator.h"
1659 #include "sessionauthorizer.h"
1660+#include "promptsessionlistener.h"
1661 #include "focussetter.h"
1662 #include "logging.h"
1663
1664@@ -117,6 +118,16 @@
1665 });
1666 }
1667
1668+std::shared_ptr<ms::PromptSessionListener>
1669+ShellServerConfiguration::the_prompt_session_listener()
1670+{
1671+ return prompt_session_listener(
1672+ [this]
1673+ {
1674+ return std::make_shared<PromptSessionListener>();
1675+ });
1676+}
1677+
1678 std::shared_ptr<mir::ServerStatusListener>
1679 ShellServerConfiguration::the_server_status_listener()
1680 {
1681@@ -136,7 +147,7 @@
1682 // The rationale is that if when you do
1683 // the_session_authorizer()
1684 // get a pointer that is unique means that Mir is not
1685-// holding the pointer and thus when we return from the
1686+// holding the pointer and thus when we return from the
1687 // sessionAuthorizer()
1688 // scope the unique pointer will be destroyed so we return 0
1689 //
1690@@ -165,6 +176,14 @@
1691 return static_cast<SessionListener*>(sharedPtr.get());
1692 }
1693
1694+PromptSessionListener *ShellServerConfiguration::promptSessionListener()
1695+{
1696+ auto sharedPtr = the_prompt_session_listener();
1697+ if (sharedPtr.unique()) return 0;
1698+
1699+ return static_cast<PromptSessionListener*>(sharedPtr.get());
1700+}
1701+
1702 SurfaceConfigurator *ShellServerConfiguration::surfaceConfigurator()
1703 {
1704 auto sharedPtr = the_surface_configurator();
1705
1706=== modified file 'src/unity-mir/shellserverconfiguration.h'
1707--- src/unity-mir/shellserverconfiguration.h 2014-05-08 03:50:31 +0000
1708+++ src/unity-mir/shellserverconfiguration.h 2014-06-17 15:53:01 +0000
1709@@ -28,6 +28,7 @@
1710
1711 class FocusSetter;
1712 class SessionListener;
1713+class PromptSessionListener;
1714 class SessionAuthorizer;
1715 class SurfaceConfigurator;
1716 class InitialSurfacePlacementStrategy;
1717@@ -38,6 +39,7 @@
1718
1719 Q_PROPERTY(SessionAuthorizer* sessionAuthorizer READ sessionAuthorizer CONSTANT)
1720 Q_PROPERTY(SessionListener* sessionListener READ sessionListener CONSTANT)
1721+ Q_PROPERTY(PromptSessionListener* promptSessionListener READ promptSessionListener CONSTANT)
1722 Q_PROPERTY(SurfaceConfigurator* surfaceConfigurator READ surfaceConfigurator CONSTANT)
1723
1724 public:
1725@@ -50,6 +52,7 @@
1726 std::shared_ptr<mir::scene::SessionListener> the_session_listener() override;
1727 std::shared_ptr<mir::scene::SurfaceConfigurator> the_surface_configurator() override;
1728 std::shared_ptr<mir::shell::FocusSetter> the_shell_focus_setter() override;
1729+ std::shared_ptr<mir::scene::PromptSessionListener> the_prompt_session_listener() override;
1730 std::shared_ptr<mir::ServerStatusListener> the_server_status_listener() override;
1731 std::shared_ptr<mir::frontend::SessionAuthorizer> the_session_authorizer() override;
1732 std::shared_ptr<mir::frontend::ConnectionCreator> the_connection_creator() override;
1733@@ -59,6 +62,7 @@
1734 InitialSurfacePlacementStrategy *placementStrategy();
1735 SessionAuthorizer *sessionAuthorizer();
1736 SessionListener *sessionListener();
1737+ PromptSessionListener *promptSessionListener();
1738 SurfaceConfigurator *surfaceConfigurator();
1739 FocusSetter *focusSetter();
1740
1741
1742=== modified file 'tests/CMakeLists.txt'
1743--- tests/CMakeLists.txt 2014-05-19 12:13:58 +0000
1744+++ tests/CMakeLists.txt 2014-06-17 15:53:01 +0000
1745@@ -33,6 +33,7 @@
1746 mock_process_controller.h
1747 mock_proc_info.h
1748 mock_session.h
1749+ mock_prompt_session_manager.h
1750 )
1751
1752 add_executable(
1753
1754=== modified file 'tests/application_manager_test.cpp'
1755--- tests/application_manager_test.cpp 2014-05-26 15:54:50 +0000
1756+++ tests/application_manager_test.cpp 2014-06-17 15:53:01 +0000
1757@@ -20,6 +20,7 @@
1758 #include <Unity/Application/applicationcontroller.h>
1759 #include <Unity/Application/taskcontroller.h>
1760 #include <Unity/Application/proc_info.h>
1761+#include <Unity/Application/session.h>
1762
1763 #include <core/posix/linux/proc/process/oom_score_adj.h>
1764
1765@@ -34,6 +35,8 @@
1766 #include "mock_proc_info.h"
1767 #include "mock_session.h"
1768 #include "mock_focus_controller.h"
1769+#include "mock_prompt_session_manager.h"
1770+
1771
1772 using namespace unitymir;
1773
1774@@ -66,6 +69,7 @@
1775 [](DesktopFileReader::Factory*){}),
1776 QSharedPointer<ProcInfo>(&procInfo,[](ProcInfo *){}),
1777 std::shared_ptr<mir::shell::FocusController>(&focusController, [](void*){}),
1778+ std::shared_ptr<mir::scene::PromptSessionManager>(&promptSessionManager, [](void*){}),
1779 QSize(400,400)
1780 }
1781 {
1782@@ -76,6 +80,7 @@
1783 testing::NiceMock<testing::MockProcInfo> procInfo;
1784 testing::NiceMock<testing::MockDesktopFileReaderFactory> desktopFileReaderFactory;
1785 testing::NiceMock<testing::MockFocusController> focusController;
1786+ testing::NiceMock<testing::MockPromptSessionManager> promptSessionManager;
1787 QSharedPointer<TaskController> taskController;
1788 ApplicationManager applicationManager;
1789 };
1790@@ -386,9 +391,9 @@
1791 Application * secondApp = applicationManager.findApplication(second_app_id);
1792 Application * thirdApp = applicationManager.findApplication(third_app_id);
1793
1794- EXPECT_EQ(first_session, firstApp->session());
1795- EXPECT_EQ(second_session, secondApp->session());
1796- EXPECT_EQ(third_session, thirdApp->session());
1797+ EXPECT_EQ(first_session, firstApp->session()->mirSession());
1798+ EXPECT_EQ(second_session, secondApp->session()->mirSession());
1799+ EXPECT_EQ(third_session, thirdApp->session()->mirSession());
1800 }
1801
1802 TEST_F(ApplicationManagerTests,two_session_on_one_application)
1803@@ -414,7 +419,7 @@
1804 Application * the_app = applicationManager.findApplication(an_app_id);
1805
1806 EXPECT_EQ(true, authed);
1807- EXPECT_EQ(second_session, the_app->session());
1808+ EXPECT_EQ(second_session, the_app->session()->mirSession());
1809 }
1810
1811 TEST_F(ApplicationManagerTests,upstart_launching_sidestage_app_on_phone_forced_into_mainstage)
1812@@ -465,7 +470,7 @@
1813
1814 EXPECT_EQ(true, authed);
1815 EXPECT_EQ(Application::Running, the_app->state());
1816- EXPECT_EQ(first_session, the_app->session());
1817+ EXPECT_EQ(first_session, the_app->session()->mirSession());
1818 }
1819
1820 TEST_F(ApplicationManagerTests,suspended_suspends_focused_app)
1821@@ -958,7 +963,7 @@
1822
1823 // Check application state and session are correctly set
1824 Application *theApp = applicationManager.findApplication(appId);
1825- EXPECT_EQ(theApp->session(), session);
1826+ EXPECT_EQ(theApp->session()->mirSession(), session);
1827 EXPECT_EQ(theApp->focused(), false);
1828 }
1829
1830@@ -1092,6 +1097,7 @@
1831 EXPECT_EQ(removedSpy.takeFirst().at(0).toString(), appId);
1832 }
1833
1834+
1835 /*
1836 * Test that the background application is stopped correctly
1837 */
1838
1839=== modified file 'tests/mock_proc_info.h'
1840--- tests/mock_proc_info.h 2014-02-28 17:42:43 +0000
1841+++ tests/mock_proc_info.h 2014-06-17 15:53:01 +0000
1842@@ -27,10 +27,15 @@
1843 struct MockProcInfo : public unitymir::ProcInfo
1844 {
1845 MOCK_METHOD1(command_line, QByteArray(quint64));
1846- std::unique_ptr<CommandLine> commandLine(quint64 pid)
1847+ std::unique_ptr<CommandLine> commandLine(quint64 pid) override
1848 {
1849 return std::unique_ptr<CommandLine>(new CommandLine{command_line(pid)});
1850 }
1851+
1852+ quint64 ppid(quint64 /* pid */) override
1853+ {
1854+ return 0;
1855+ }
1856 };
1857 }
1858
1859
1860=== added file 'tests/mock_prompt_session_manager.h'
1861--- tests/mock_prompt_session_manager.h 1970-01-01 00:00:00 +0000
1862+++ tests/mock_prompt_session_manager.h 2014-06-17 15:53:01 +0000
1863@@ -0,0 +1,57 @@
1864+/*
1865+ * Copyright (C) 2014 Canonical, Ltd.
1866+ *
1867+ * This program is free software: you can redistribute it and/or modify it under
1868+ * the terms of the GNU Lesser General Public License version 3, as published by
1869+ * the Free Software Foundation.
1870+ *
1871+ * This program is distributed in the hope that it will be useful, but WITHOUT
1872+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
1873+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1874+ * Lesser General Public License for more details.
1875+ *
1876+ * You should have received a copy of the GNU Lesser General Public License
1877+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1878+ *
1879+ */
1880+
1881+#ifndef MOCK_MIR_SCENE_PROMPT_SESSION_MANAGER_H_
1882+#define MOCK_MIR_SCENE_PROMPT_SESSION_MANAGER_H_
1883+
1884+#include "mir/scene/prompt_session_manager.h"
1885+#include "mir/scene/prompt_session_creation_parameters.h"
1886+
1887+#include <gmock/gmock.h>
1888+
1889+namespace testing
1890+{
1891+
1892+class MockPromptSessionManager: public mir::scene::PromptSessionManager
1893+{
1894+public:
1895+ MOCK_CONST_METHOD2(start_prompt_session_for, std::shared_ptr<mir::scene::PromptSession>(std::shared_ptr<mir::scene::Session> const&,
1896+ mir::scene::PromptSessionCreationParameters const&));
1897+
1898+ MOCK_CONST_METHOD1(stop_prompt_session, void(std::shared_ptr<mir::scene::PromptSession> const&));
1899+
1900+ MOCK_CONST_METHOD2(add_prompt_provider, void(std::shared_ptr<mir::scene::PromptSession> const&,
1901+ std::shared_ptr<mir::scene::Session> const&));
1902+
1903+ MOCK_CONST_METHOD2(add_prompt_provider_by_pid, void(std::shared_ptr<mir::scene::PromptSession> const&,
1904+ pid_t));
1905+
1906+ MOCK_CONST_METHOD1(add_expected_session, void(std::shared_ptr<mir::scene::Session> const&));
1907+
1908+ MOCK_CONST_METHOD1(remove_session, void(std::shared_ptr<mir::scene::Session> const&));
1909+
1910+ MOCK_CONST_METHOD1(application_for, std::shared_ptr<mir::scene::Session>(std::shared_ptr<mir::scene::PromptSession> const&));
1911+
1912+ MOCK_CONST_METHOD1(helper_for, std::shared_ptr<mir::scene::Session>(std::shared_ptr<mir::scene::PromptSession> const&));
1913+
1914+ MOCK_CONST_METHOD2(for_each_provider_in, void(std::shared_ptr<mir::scene::PromptSession> const&,
1915+ std::function<void(std::shared_ptr<mir::scene::Session> const&)> const&));
1916+};
1917+
1918+} // namespace testing
1919+
1920+#endif // MOCK_MIR_SCENE_PROMPT_SESSION_MANAGER_H_
1921
1922=== modified file 'tests/mock_session.h'
1923--- tests/mock_session.h 2014-05-06 20:11:48 +0000
1924+++ tests/mock_session.h 2014-06-17 15:53:01 +0000
1925@@ -30,7 +30,7 @@
1926 struct MockSession : public mir::scene::Session
1927 {
1928 MockSession() {}
1929- MockSession(std::string const& sessionName, pid_t processId)
1930+ MockSession(std::string const& sessionName, pid_t processId)
1931 : m_sessionName(sessionName), m_sessionId(processId)
1932 {}
1933
1934@@ -60,6 +60,9 @@
1935 MOCK_METHOD0(show, void());
1936 MOCK_METHOD1(send_display_config, void(mir::graphics::DisplayConfiguration const&));
1937 MOCK_METHOD3(configure_surface, int(SurfaceId, MirSurfaceAttrib, int));
1938+
1939+ MOCK_METHOD0(start_prompt_session, void());
1940+ MOCK_METHOD0(stop_prompt_session, void());
1941 private:
1942 std::string m_sessionName;
1943 pid_t m_sessionId;

Subscribers

People subscribed via source and target branches