Merge lp:~nick-dedekind/unity-mir/unity-mir.trusted_sessions into lp:unity-mir

Proposed by Nick Dedekind
Status: Merged
Merged at revision: 241
Proposed branch: lp:~nick-dedekind/unity-mir/unity-mir.trusted_sessions
Merge into: lp:unity-mir
Diff against target: 1073 lines (+438/-123)
14 files modified
src/modules/Unity/Application/ApplicationImage.qml (+8/-0)
src/modules/Unity/Application/CMakeLists.txt (+4/-2)
src/modules/Unity/Application/application.cpp (+33/-11)
src/modules/Unity/Application/application.h (+18/-4)
src/modules/Unity/Application/application_manager.cpp (+196/-86)
src/modules/Unity/Application/application_manager.h (+11/-6)
src/modules/Unity/Application/applicationscreenshotprovider.cpp (+4/-2)
src/modules/Unity/Application/dbuswindowstack.cpp (+1/-1)
src/modules/Unity/Application/mirsurfacemanager.cpp (+13/-10)
src/modules/Unity/Application/session.cpp (+70/-0)
src/modules/Unity/Application/session.h (+60/-0)
src/unity-mir/sessionlistener.cpp (+13/-0)
src/unity-mir/sessionlistener.h (+6/-0)
src/unity-mir/shellserverconfiguration.cpp (+1/-1)
To merge this branch: bzr merge lp:~nick-dedekind/unity-mir/unity-mir.trusted_sessions
Reviewer Review Type Date Requested Status
Mir development team Pending
Review via email: mp+208324@code.launchpad.net
To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/modules/Unity/Application/ApplicationImage.qml'
2--- src/modules/Unity/Application/ApplicationImage.qml 2013-10-01 17:45:26 +0000
3+++ src/modules/Unity/Application/ApplicationImage.qml 2014-02-26 10:27:46 +0000
4@@ -40,4 +40,12 @@
5 source: (root.source) ? "image://screenshot/" + root.source.appId : ""
6 cache: false
7 }
8+
9+ Connections {
10+ target: source
11+ onSessionChanged: {
12+ console.log("SESSION CHANGED");
13+ scheduleUpdate();
14+ }
15+ }
16 }
17
18=== modified file 'src/modules/Unity/Application/CMakeLists.txt'
19--- src/modules/Unity/Application/CMakeLists.txt 2014-01-27 11:29:44 +0000
20+++ src/modules/Unity/Application/CMakeLists.txt 2014-02-26 10:27:46 +0000
21@@ -32,6 +32,7 @@
22 processcontroller.h
23 processcontroller.cpp
24 shellinputarea.cpp
25+ session.cpp
26 ubuntukeyboardinfo.cpp
27
28 upstart/applicationcontroller.h
29@@ -47,10 +48,11 @@
30 mirsurface.h
31 mirsurfacemanager.h
32 shellinputarea.h
33+ session.h
34 inputarea.h
35 inputfilterarea.h
36 ubuntukeyboardinfo.h
37-
38+
39 # We need to pull in some external header files
40 /usr/include/unity/shell/application/ApplicationManagerInterface.h
41 /usr/include/unity/shell/application/ApplicationInfoInterface.h
42@@ -62,7 +64,7 @@
43
44 target_link_libraries(
45 unityapplicationplugin
46-
47+
48 unity-mir
49
50 ubuntu_application_api_mirserver
51
52=== modified file 'src/modules/Unity/Application/application.cpp'
53--- src/modules/Unity/Application/application.cpp 2014-01-27 11:29:44 +0000
54+++ src/modules/Unity/Application/application.cpp 2014-02-26 10:27:46 +0000
55@@ -22,11 +22,13 @@
56
57 // unity-mir
58 #include "logging.h"
59+#include "session.h"
60
61 // mir
62-#include <mir/shell/session.h>
63 #include <mir/shell/snapshot.h>
64
65+#include <QDebug>
66+
67 Application::Application(const QSharedPointer<TaskController>& taskController,
68 DesktopFileReader *desktopFileReader,
69 State state,
70@@ -120,9 +122,16 @@
71 return m_fullscreen;
72 }
73
74-std::shared_ptr<mir::shell::Session> Application::session() const
75-{
76- return m_session;
77+QSharedPointer<Session> Application::session() const
78+{
79+ if (!m_overrideSession.isNull())
80+ return m_overrideSession;
81+ return m_session.toStrongRef();
82+}
83+
84+QSharedPointer<Session> Application::overrideSession() const
85+{
86+ return m_overrideSession;
87 }
88
89 pid_t Application::pid() const
90@@ -135,12 +144,25 @@
91 m_pid = pid;
92 }
93
94-void Application::setSession(const std::shared_ptr<mir::shell::Session>& session)
95+void Application::setSession(const QSharedPointer<Session>& new_session)
96 {
97- DLOG("Application::setSession (this=%p, session=%p)", this, session.get());
98+ DLOG("Application::setSession (this=%p, session=%p)", this, new_session ? new_session->mirSession().get() : nullptr);
99
100 // TODO(greyback) what if called with new surface?
101- m_session = session;
102+ m_session = new_session.toWeakRef();
103+ if (session()) {
104+ Q_EMIT sessionChanged();
105+ }
106+}
107+
108+void Application::setOverrideSession(const QSharedPointer<Session>& override_session)
109+{
110+ DLOG("Application::setOverrideSession (this=%p, session=%p)", this, override_session ? override_session->mirSession().get() : nullptr);
111+
112+ m_overrideSession = override_session;
113+ if (session()) {
114+ Q_EMIT sessionChanged();
115+ }
116 }
117
118 void Application::setSessionName(const QString& name)
119@@ -169,8 +191,8 @@
120 switch (state)
121 {
122 case Application::Suspended:
123- if (m_state == Application::Running) {
124- session()->set_lifecycle_state(mir_lifecycle_state_will_suspend);
125+ if (session() && m_state == Application::Running) {
126+ session()->setLifecycleState(mir_lifecycle_state_will_suspend);
127 m_suspendTimer->start(3000);
128 }
129 break;
130@@ -178,9 +200,9 @@
131 if (m_suspendTimer->isActive())
132 m_suspendTimer->stop();
133
134- if (m_state == Application::Suspended) {
135+ if (session() && m_state == Application::Suspended) {
136 resume();
137- session()->set_lifecycle_state(mir_lifecycle_state_resumed);
138+ session()->setLifecycleState(mir_lifecycle_state_resumed);
139 } else if (m_state == Application::Stopped) {
140 respawn();
141 state = Application::Starting;
142
143=== modified file 'src/modules/Unity/Application/application.h'
144--- src/modules/Unity/Application/application.h 2014-01-27 11:29:44 +0000
145+++ src/modules/Unity/Application/application.h 2014-02-26 10:27:46 +0000
146@@ -31,7 +31,14 @@
147 class QImage;
148 class DesktopFileReader;
149 class TaskController;
150-namespace mir { namespace shell { class Session; }}
151+class Session;
152+namespace mir
153+{
154+namespace shell
155+{
156+class TrustedSession;
157+}
158+}
159
160 class Application : public unity::shell::application::ApplicationInfoInterface {
161 Q_OBJECT
162@@ -63,9 +70,11 @@
163 QString desktopFile() const;
164 QString exec() const;
165 bool fullscreen() const;
166- std::shared_ptr<mir::shell::Session> session() const;
167 pid_t pid() const;
168
169+ QSharedPointer<Session> session() const;
170+ QSharedPointer<Session> overrideSession() const;
171+
172 public Q_SLOTS:
173 void suspend();
174 void resume();
175@@ -74,15 +83,18 @@
176 Q_SIGNALS:
177 void fullscreenChanged();
178 void stageChanged(Stage stage);
179+ void sessionChanged();
180
181 private:
182 void setPid(pid_t pid);
183 void setState(State state);
184 void setFocused(bool focus);
185 void setFullscreen(bool fullscreen);
186- void setSession(const std::shared_ptr<mir::shell::Session>& session);
187 void setSessionName(const QString& name);
188
189+ void setSession(const QSharedPointer<Session>& session);
190+ void setOverrideSession(const QSharedPointer<Session>& session);
191+
192 QSharedPointer<TaskController> m_taskController;
193 DesktopFileReader* m_desktopData;
194 qint64 m_pid;
195@@ -90,7 +102,9 @@
196 State m_state;
197 bool m_focused;
198 bool m_fullscreen;
199- std::shared_ptr<mir::shell::Session> m_session;
200+ QWeakPointer<Session> m_session;
201+ QSharedPointer<Session> m_overrideSession;
202+
203 QString m_sessionName;
204 QStringList m_arguments;
205 QTimer* m_suspendTimer;
206
207=== modified file 'src/modules/Unity/Application/application_manager.cpp'
208--- src/modules/Unity/Application/application_manager.cpp 2014-02-11 09:47:56 +0000
209+++ src/modules/Unity/Application/application_manager.cpp 2014-02-26 10:27:46 +0000
210@@ -31,15 +31,18 @@
211 #include "surfacefactory.h"
212 #include "taskcontroller.h"
213 #include "logging.h"
214+#include "session.h"
215
216 // mir
217 #include <mir/scene/depth_id.h>
218 #include <mir/shell/session.h>
219 #include <mir/shell/focus_controller.h>
220 #include <mir/shell/surface.h>
221+#include <mir/shell/trusted_session.h>
222 #include <mir/graphics/display.h>
223 #include <mir/graphics/display_buffer.h>
224 #include <mircommon/mir/geometry/rectangles.h>
225+#include <mir/frontend/shell.h>
226
227 // Qt
228 #include <QCoreApplication>
229@@ -53,6 +56,11 @@
230
231 ApplicationManager *ApplicationManager::the_application_manager = nullptr;
232
233+QList<QByteArray> ApplicationManager::whiteListApps({ "maliit-server",
234+ "/usr/lib/arm-linux-gnueabihf/qt5/libexec/QtWebProcess",
235+ "/usr/bin/signon-ui",
236+ "/usr/bin/mir_demo_client_trusted_session_trusted" });
237+
238 ApplicationManager* ApplicationManager::singleton()
239 {
240 if (!the_application_manager) {
241@@ -82,7 +90,6 @@
242 , m_taskController(taskController)
243 , m_desktopFileReaderFactory(desktopFileReaderFactory)
244 , m_gridUnitPx(8)
245- , m_fenceNext(false)
246 , m_panelHeight(54)
247 {
248 DLOG("ApplicationManager::ApplicationManager (this=%p)", this);
249@@ -105,6 +112,10 @@
250 this, &ApplicationManager::onSessionUnfocused);
251 QObject::connect(m_mirServer->sessionListener(), &SessionListener::sessionCreatedSurface,
252 this, &ApplicationManager::onSessionCreatedSurface);
253+ QObject::connect(m_mirServer->sessionListener(), &SessionListener::trustedSessionStarted,
254+ this, &ApplicationManager::onTrustedSessionStarted);
255+ QObject::connect(m_mirServer->sessionListener(), &SessionListener::trustedSessionStopped,
256+ this, &ApplicationManager::onTrustedSessionStopped);
257 QObject::connect(m_mirServer->sessionAuthorizer(), &SessionAuthorizer::requestAuthorizationForSession,
258 this, &ApplicationManager::authorizeSession, Qt::BlockingQueuedConnection);
259 QObject::connect(m_mirServer->placementStrategy(), &InitialSurfacePlacementStrategy::requestPlacementForSession,
260@@ -130,7 +141,7 @@
261 {
262 view_area.add(db.view_area());
263 });
264-
265+
266 m_displaySize = QSize(
267 view_area.bounding_rectangle().size.width.as_uint32_t(),
268 view_area.bounding_rectangle().size.height.as_uint32_t()
269@@ -239,15 +250,15 @@
270 DLOG("No such running application '%s'", qPrintable(appId));
271 return false;
272 }
273-
274+
275 if (application->stage() == Application::MainStage && m_sideStageApplication)
276 suspendApplication(m_sideStageApplication);
277-
278+
279 if (application->stage() == Application::MainStage)
280 m_msApplicationToBeFocused = application;
281 else
282 m_ssApplicationToBeFocused = application;
283-
284+
285 if (application->state() == Application::Stopped) {
286 // Respawning this app, move to end of application list so onSessionStarting works ok
287 // FIXME: this happens pretty late, shell could request respawn earlier
288@@ -255,8 +266,9 @@
289 int from = m_applications.indexOf(application);
290 move(from, m_applications.length()-1);
291 } else {
292- if (application->session())
293- m_mirServer->the_focus_controller()->set_focus_to(application->session());
294+ if (application->session()) {
295+ m_mirServer->the_focus_controller()->set_focus_to(application->session()->mirSession());
296+ }
297 }
298
299 // FIXME(dandrader): lying here. The operation is async. So we will only know whether
300@@ -353,15 +365,24 @@
301
302 if (application == m_focusedApplication) {
303 // TODO(greyback) What to do?? Focus next app, or unfocus everything??
304+ auto lastFocusedApp = m_focusedApplication;
305 m_focusedApplication = NULL;
306 Q_EMIT focusedApplicationIdChanged();
307+
308+ // stop trusted session when focus changes.
309+ if (lastFocusedApp && lastFocusedApp->overrideSession()) {
310+ auto overrideMirSession = lastFocusedApp->overrideSession()->mirSession();
311+ if (overrideMirSession->get_trusted_session()) {
312+ m_mirServer->the_frontend_shell()->stop_trusted_session(overrideMirSession->get_trusted_session()->id());
313+ }
314+ }
315 }
316
317 if (application == m_mainStageApplication)
318 m_mainStageApplication = nullptr;
319 if (application == m_sideStageApplication)
320 m_sideStageApplication = nullptr;
321-
322+
323 remove(application);
324 m_dbusWindowStack->WindowDestroyed(0, application->appId());
325
326@@ -388,9 +409,18 @@
327
328 if (application == m_focusedApplication) {
329 // Very bad case where focused application dies. Remove from list. Should give error message
330+ auto lastFocusedApp = m_focusedApplication;
331 m_focusedApplication = nullptr;
332 Q_EMIT focusedApplicationIdChanged();
333 removeApplication = true;
334+
335+ // stop trusted session when focus changes.
336+ if (lastFocusedApp && lastFocusedApp->overrideSession()) {
337+ auto overrideMirSession = lastFocusedApp->overrideSession()->mirSession();
338+ if (overrideMirSession->get_trusted_session()) {
339+ m_mirServer->the_frontend_shell()->stop_trusted_session(overrideMirSession->get_trusted_session()->id());
340+ }
341+ }
342 }
343
344 if (application->state() == Application::Running || application->state() == Application::Starting) {
345@@ -399,7 +429,7 @@
346 removeApplication = true;
347 } else if (application->state() == Application::Suspended) {
348 application->setState(Application::Stopped);
349- application->setSession(nullptr);
350+ application->setSession(QSharedPointer<Session>());
351 }
352
353 if (removeApplication) {
354@@ -471,12 +501,14 @@
355
356 QByteArray command = cmdline.readLine().replace('\0', ' ');
357
358- // FIXME: special exception for the OSK - maliit-server - not very secure
359- if (command.startsWith("maliit-server") || command.startsWith("/usr/lib/arm-linux-gnueabihf/qt5/libexec/QtWebProcess")
360- || command.startsWith("/usr/bin/signon-ui")) {
361- authorized = true;
362- m_fenceNext = true;
363- return;
364+ // FIXME: special exceptions - not very secure
365+ for( auto const& whiteListApp : whiteListApps) {
366+ if (command.startsWith(whiteListApp)) {
367+ DLOG("ApplicationManager ACCEPTED connection from white-list app with pid %lld", pid);
368+ authorized = true;
369+ m_fencePIDs << pid;
370+ return;
371+ }
372 }
373
374 QString pattern = QRegularExpression::escape("--desktop_file_hint=") + "(\\S+)";
375@@ -484,7 +516,7 @@
376 QRegularExpressionMatch regExpMatch = regExp.match(command);
377
378 if (!regExpMatch.hasMatch()) {
379- LOG("ApplicationManager REJECTED connection from app with pid %lld as no desktop_file_hint specified", pid);
380+ LOG("ApplicationManager REJECTED connection from app with pid %lld (%s) as no desktop_file_hint specified", pid, command.data());
381 return;
382 }
383
384@@ -543,10 +575,10 @@
385 void ApplicationManager::placeSession(msh::Session const* session, uint32_t &x, uint32_t &y)
386 {
387 DLOG("ApplicationManager::placeSession (this=%p, session=%p)", this, session);
388-
389- Application* application = findApplicationWithSession(session);
390-
391- // Application defaults
392+
393+ Application* application = findApplicationWithSession(session, true);
394+
395+ // Application defaults
396 x = 0;
397 y = m_panelHeight;
398
399@@ -563,7 +595,7 @@
400 // SideStage override
401 if (application && application->stage() == Application::SideStage)
402 x = m_displaySize.width() - (SIDE_STAGE_WIDTH_GU * m_gridUnitPx);
403-
404+
405 DLOG("ApplicationManager::placeSession (x=%d, y=%d)", x, y);
406 }
407
408@@ -571,21 +603,22 @@
409 {
410 DLOG("ApplicationManager::onSessionStarting (this=%p, application=%s)", this, session->name().c_str());
411
412- if (m_fenceNext) {
413- m_fenceNext = false;
414- return;
415- }
416-
417- //FIXME(greyback) Mir not supplying any identifier that we can use to link the PID to the session
418- // so am assuming that the *most recently* launched application session is the one that connects
419- Application* application = findLastExecutedApplication();
420+ pid_t pid = session->process_id();
421+
422+ QSharedPointer<Session> new_session(new Session(session));
423+ m_sessions[pid] = new_session;
424+
425+ Application* application = findApplicationWithPid(session->process_id(), false);
426 if (application && application->state() != Application::Running) {
427- application->setSession(session);
428+ application->setSession(new_session);
429 if (application->stage() == Application::MainStage)
430 m_msApplicationToBeFocused = application;
431 else
432 m_ssApplicationToBeFocused = application;
433 } else {
434+ if (m_fencePIDs.contains(pid)) {
435+ return;
436+ }
437 DLOG("ApplicationManager::onSessionStarting - unauthorized application!!");
438 }
439 }
440@@ -594,44 +627,56 @@
441 {
442 DLOG("ApplicationManager::onSessionStopping (this=%p, application=%s)", this, session->name().c_str());
443
444- // in case application closed not by hand of shell, check again here:
445- Application* application = findApplicationWithSession(session);
446- if (application) {
447- bool removeApplication = true;
448-
449- if (application->state() != Application::Starting) {
450- application->setState(Application::Stopped);
451- application->setSession(nullptr);
452- m_dbusWindowStack->WindowDestroyed(0, application->appId());
453- if (application != m_focusedApplication) {
454- removeApplication = false;
455- }
456- }
457-
458- if (m_mainStageApplication == application)
459- m_mainStageApplication = nullptr;
460-
461- if (m_sideStageApplication == application)
462- m_sideStageApplication = nullptr;
463-
464- if (removeApplication) {
465- // TODO(greyback) What to do?? Focus next app, or unfocus everything??
466- m_focusedApplication = NULL;
467- remove(application);
468- delete application;
469- Q_EMIT focusedApplicationIdChanged();
470- }
471+ auto sit = m_sessions.find(session->process_id());
472+ if (sit != m_sessions.end()) {
473+ QSharedPointer<Session> localSession = sit.value();
474+
475+ // in case application closed not by hand of shell, check again here:
476+ Application* application = findApplicationWithSession(session, false); // only check app sessions
477+ if (application) {
478+
479+ if (session->get_trusted_session()) {
480+ m_mirServer->the_frontend_shell()->stop_trusted_session(session->get_trusted_session()->id());
481+ }
482+
483+ bool removeApplication = true;
484+ if (application->state() != Application::Starting) {
485+ application->setState(Application::Stopped);
486+ application->setSession(QSharedPointer<Session>());
487+ m_dbusWindowStack->WindowDestroyed(0, application->appId());
488+ if (application != m_focusedApplication) {
489+ removeApplication = false;
490+ }
491+ }
492+
493+ if (m_mainStageApplication == application)
494+ m_mainStageApplication = nullptr;
495+
496+ if (m_sideStageApplication == application)
497+ m_sideStageApplication = nullptr;
498+
499+ if (removeApplication) {
500+ // TODO(greyback) What to do?? Focus next app, or unfocus everything??
501+ m_focusedApplication = NULL;
502+ remove(application);
503+ delete application;
504+ Q_EMIT focusedApplicationIdChanged();
505+ }
506+ }
507+
508+ m_sessions.erase(sit);
509+ m_fencePIDs.removeAll(session->process_id());
510 }
511 }
512
513 void ApplicationManager::onSessionFocused(std::shared_ptr<msh::Session> const& session)
514 {
515- DLOG("ApplicationManager::onSessionFocused (this=%p, session=%p)", this, session.get());
516- Application* application = findApplicationWithSession(session);
517+ DLOG("ApplicationManager::onSessionFocused (this=%p, application=%s)", this, session->name().c_str());
518+ Application* application = findApplicationWithSession(session, true);
519
520 // Don't give application focus until it has created it's surface, when it is set as state "Running"
521 // and only notify shell of focus changes that it actually expects
522- if (application && application->state() != Application::Starting &&
523+ if (application && application->state() != Application::Starting &&
524 (application == m_msApplicationToBeFocused ||
525 application == m_ssApplicationToBeFocused)
526 && application != m_focusedApplication) {
527@@ -640,9 +685,10 @@
528 Q_EMIT dataChanged(appIndex, appIndex, QVector<int>() << RoleFocused);
529 } else {
530 if (application == nullptr) {
531- DLOG("Invalid application focused, discarding the event");
532- if (NULL != m_focusedApplication)
533+ DLOG("Invalid application focused, discarding the event (m_focusedApplication=%p)", m_focusedApplication);
534+ if (NULL != m_focusedApplication) {
535 focusApplication(m_focusedApplication->appId());
536+ }
537 }
538 }
539 }
540@@ -653,7 +699,8 @@
541 if (NULL != m_focusedApplication) {
542 Q_ASSERT(m_focusedApplication->focused());
543 m_focusedApplication->setFocused(false);
544-
545+
546+ auto lastFocusedApp = m_focusedApplication;
547 suspendApplication(m_focusedApplication);
548
549 m_focusedApplication = NULL;
550@@ -662,16 +709,23 @@
551
552 QModelIndex appIndex = findIndex(m_focusedApplication);
553 Q_EMIT dataChanged(appIndex, appIndex, QVector<int>() << RoleFocused << RoleState);
554+
555+ if (lastFocusedApp->overrideSession()) {
556+ auto overrideMirSession = lastFocusedApp->overrideSession()->mirSession();
557+ if (overrideMirSession->get_trusted_session()) {
558+ m_mirServer->the_frontend_shell()->stop_trusted_session(overrideMirSession->get_trusted_session()->id());
559+ }
560+ }
561 }
562 }
563
564 void ApplicationManager::onSessionCreatedSurface(msh::Session const* session,
565 std::shared_ptr<msh::Surface> const& surface)
566 {
567- DLOG("ApplicationManager::onSessionCreatedSurface (this=%p)", this);
568+ DLOG("ApplicationManager::onSessionCreatedSurface (this=%p, application=%p)", this, session->name().c_str());
569 Q_UNUSED(surface);
570
571- Application* application = findApplicationWithSession(session);
572+ Application* application = findApplicationWithSession(session, true);
573 if (application && application->state() == Application::Starting) {
574 m_dbusWindowStack->WindowCreated(0, application->appId());
575 // only when Session creates a Surface will we actually mark it focused
576@@ -681,6 +735,51 @@
577 }
578 }
579
580+void ApplicationManager::onTrustedSessionStarted(std::shared_ptr<mir::shell::TrustedSession> const& mir_trusted_session)
581+{
582+ DLOG("ApplicationManager::onTrustedSessionStarted (this=%p, application=%p)", this, mir_trusted_session->name().c_str());
583+
584+ QSharedPointer<Session> trusted_session(new Session(mir_trusted_session));
585+
586+ bool overrideSet = false;
587+ std::vector<pid_t> trusted_apps = mir_trusted_session->get_applications();
588+ for (pid_t pid : trusted_apps) {
589+ Application* app = findApplicationWithPid(pid, false);
590+ if (!app) {
591+ continue;
592+ }
593+
594+ overrideSet = true;
595+ app->setOverrideSession(trusted_session);
596+
597+ if (m_focusedApplication == app) {
598+ focusApplication(app->appId());
599+ }
600+ }
601+
602+ if (!overrideSet) {
603+ DLOG("ApplicationManager::onTrustedSessionStarted - no trusted helper to start");
604+ }
605+}
606+
607+void ApplicationManager::onTrustedSessionStopped(std::shared_ptr<mir::shell::TrustedSession> const& trusted_session)
608+{
609+ auto trusted_helper = trusted_session->get_trusted_helper();
610+ DLOG("ApplicationManager::onTrustedSessionStopped (this=%p, application=%s)", this, trusted_helper->name().c_str());
611+
612+ for (Application *app : m_applications) {
613+
614+ if (app->overrideSession() && app->overrideSession()->mirSession() == trusted_session) {
615+ app->setOverrideSession(QSharedPointer<Session>());
616+ }
617+
618+ if (m_focusedApplication == app) {
619+ focusApplication(app->appId());
620+ }
621+ }
622+}
623+
624+
625 void ApplicationManager::setFocused(Application *application)
626 {
627 DLOG("ApplicationManager::setFocused (appId=%s)", qPrintable(application->appId()));
628@@ -699,29 +798,34 @@
629 else
630 m_sideStageApplication = application;
631
632+ auto lastFocusedApp = m_focusedApplication;
633 m_focusedApplication = application;
634 m_focusedApplication->setFocused(true);
635 m_focusedApplication->setState(Application::Running);
636 Q_EMIT focusedApplicationIdChanged();
637 m_dbusWindowStack->FocusedWindowChanged(0, application->appId(), application->stage());
638-}
639-
640-Application* ApplicationManager::findApplicationWithSession(const std::shared_ptr<msh::Session> &session)
641-{
642- return findApplicationWithSession(session.get());
643-}
644-
645-Application* ApplicationManager::findApplicationWithSession(const msh::Session *session)
646-{
647- for (Application *app : m_applications) {
648- if (app->session().get() == session) {
649- return app;
650+
651+ // stop trusted session when focus changes.
652+ if (lastFocusedApp && lastFocusedApp->overrideSession()) {
653+ auto overrideMirSession = lastFocusedApp->overrideSession()->mirSession();
654+ if (overrideMirSession->get_trusted_session()) {
655+ m_mirServer->the_frontend_shell()->stop_trusted_session(overrideMirSession->get_trusted_session()->id());
656 }
657 }
658- return nullptr;
659-}
660-
661-Application* ApplicationManager::findApplicationWithPid(const qint64 pid)
662+}
663+
664+Application* ApplicationManager::findApplicationWithSession(const std::shared_ptr<msh::Session> &session, bool checkSessions)
665+{
666+ return findApplicationWithSession(session.get(), checkSessions);
667+}
668+
669+Application* ApplicationManager::findApplicationWithSession(const msh::Session *session, bool checkSessions)
670+{
671+ if (!session) { return NULL; }
672+ return findApplicationWithPid(session->process_id(), checkSessions);
673+}
674+
675+Application* ApplicationManager::findApplicationWithPid(const qint64 pid, bool checkSessions)
676 {
677 if (pid <= 0)
678 return nullptr;
679@@ -730,17 +834,23 @@
680 if (app->m_pid == pid) {
681 return app;
682 }
683+
684+ if (checkSessions && app->session()) {
685+ if (app->session()->hasProcess(pid)) {
686+ return app;
687+ }
688+ }
689 }
690 return nullptr;
691 }
692
693-Application* ApplicationManager::findLastExecutedApplication()
694+QSharedPointer<Session> ApplicationManager::findSessionForPid(pid_t pid)
695 {
696- if (m_applications.length() > 0) {
697- return m_applications.last();
698- } else {
699- return NULL;
700+ auto iter = m_sessions.find(pid);
701+ if (iter != m_sessions.end()) {
702+ return *iter;
703 }
704+ return QSharedPointer<Session>();
705 }
706
707 Application* ApplicationManager::applicationForStage(Application::Stage stage)
708
709=== modified file 'src/modules/Unity/Application/application_manager.h'
710--- src/modules/Unity/Application/application_manager.h 2014-01-27 11:29:44 +0000
711+++ src/modules/Unity/Application/application_manager.h 2014-02-26 10:27:46 +0000
712@@ -46,6 +46,7 @@
713 namespace shell {
714 class Session;
715 class Surface;
716+ class TrustedSession;
717 }
718 }
719
720@@ -87,7 +88,7 @@
721 Q_INVOKABLE void move(int from, int to);
722
723 const QList<Application*> &list() const { return m_applications; }
724- Application* findApplicationWithPid(const qint64 pid);
725+ Application* findApplicationWithPid(const qint64 pid, bool checkSessions);
726
727 // Internal helpers
728 void suspendApplication(Application *application);
729@@ -97,11 +98,13 @@
730 public Q_SLOTS:
731 void authorizeSession(const quint64 pid, bool &authorized);
732 void placeSession(mir::shell::Session const*, uint32_t &x, uint32_t &y);
733-
734+
735 void onSessionStarting(std::shared_ptr<mir::shell::Session> const& session);
736 void onSessionStopping(std::shared_ptr<mir::shell::Session> const& session);
737 void onSessionFocused(std::shared_ptr<mir::shell::Session> const& session);
738 void onSessionUnfocused();
739+ void onTrustedSessionStarted(std::shared_ptr<mir::shell::TrustedSession> const& trusted_session);
740+ void onTrustedSessionStopped(std::shared_ptr<mir::shell::TrustedSession> const& trusted_session);
741
742 void onSessionCreatedSurface(mir::shell::Session const*, std::shared_ptr<mir::shell::Surface> const&);
743
744@@ -117,11 +120,11 @@
745 void setFocused(Application *application);
746 void add(Application *application);
747 void remove(Application* application);
748- Application* findApplicationWithSession(const std::shared_ptr<mir::shell::Session> &session);
749- Application* findApplicationWithSession(const mir::shell::Session *session);
750- Application* findLastExecutedApplication();
751+ Application* findApplicationWithSession(const std::shared_ptr<mir::shell::Session> &session, bool checkSessions);
752+ Application* findApplicationWithSession(const mir::shell::Session *session, bool checkSessions);
753 Application* applicationForStage(Application::Stage stage);
754 QModelIndex findIndex(Application* application);
755+ QSharedPointer<Session> findSessionForPid(pid_t pid);
756
757 QList<Application*> m_applications;
758 Application* m_focusedApplication; // remove as Mir has API for this
759@@ -135,8 +138,10 @@
760 QSharedPointer<TaskController> m_taskController;
761 QSharedPointer<DesktopFileReader::Factory> m_desktopFileReaderFactory;
762 static ApplicationManager* the_application_manager;
763+ static QList<QByteArray> whiteListApps;
764 int m_gridUnitPx;
765- bool m_fenceNext;
766+ QList<pid_t> m_fencePIDs;
767+ QMap<pid_t, QSharedPointer<Session>> m_sessions;
768 QSize m_displaySize;
769 int m_panelHeight;
770
771
772=== modified file 'src/modules/Unity/Application/applicationscreenshotprovider.cpp'
773--- src/modules/Unity/Application/applicationscreenshotprovider.cpp 2013-12-20 03:38:43 +0000
774+++ src/modules/Unity/Application/applicationscreenshotprovider.cpp 2014-02-26 10:27:46 +0000
775@@ -20,6 +20,7 @@
776 #include "application.h"
777
778 // unity-mir
779+#include "session.h"
780 #include "logging.h"
781
782 // mir
783@@ -51,7 +52,8 @@
784
785 // TODO: if app not ready, return an app-provided splash image. If app has been stopped with saved state
786 // return the screenshot that was saved to disk.
787- if (!app->session() || !app->session()->default_surface()) {
788+ QSharedPointer<Session> session = app->session();
789+ if (!session || !session->mirSession() || !session->mirSession()->default_surface()) {
790 LOG("ApplicationScreenshotProvider - app session not found - taking screenshot too early");
791 return QImage();
792 }
793@@ -67,7 +69,7 @@
794
795 QImage image;
796
797- app->session()->take_snapshot(
798+ session->mirSession()->take_snapshot(
799 [&](mir::shell::Snapshot const& snapshot)
800 {
801 DLOG("ApplicationScreenshotProvider - Mir snapshot ready with size %d x %d",
802
803=== modified file 'src/modules/Unity/Application/dbuswindowstack.cpp'
804--- src/modules/Unity/Application/dbuswindowstack.cpp 2013-10-09 09:02:23 +0000
805+++ src/modules/Unity/Application/dbuswindowstack.cpp 2014-02-26 10:27:46 +0000
806@@ -44,7 +44,7 @@
807 {
808 AppIdDesktopFile res;
809 ApplicationManager *appMgr = static_cast<ApplicationManager*>(parent());
810- const Application* app = static_cast<Application*>(appMgr->findApplicationWithPid(pid));
811+ const Application* app = static_cast<Application*>(appMgr->findApplicationWithPid(pid, false));
812 if (app) {
813 res.app_id = app->appId();
814 res.desktop_file = app->desktopFile();
815
816=== modified file 'src/modules/Unity/Application/mirsurfacemanager.cpp'
817--- src/modules/Unity/Application/mirsurfacemanager.cpp 2013-12-20 03:38:43 +0000
818+++ src/modules/Unity/Application/mirsurfacemanager.cpp 2014-02-26 10:27:46 +0000
819@@ -103,8 +103,8 @@
820 {
821 DLOG("MirSurfaceManager::sessionCreatedSurface (this=%p) with surface name '%s'", this, surface->name().c_str());
822 ApplicationManager* appMgr = static_cast<ApplicationManager*>(ApplicationManager::singleton());
823- Application* application = appMgr->findApplicationWithSession(session);
824-
825+ Application* application = appMgr->findApplicationWithSession(session, true);
826+
827 auto qmlSurface = new MirSurface(surface, application);
828 m_surfaces.insert(surface.get(), qmlSurface);
829 Q_EMIT surfaceCreated(qmlSurface);
830@@ -134,7 +134,7 @@
831 if (fs) {
832 fs->set_default_keyboard_target(surface);
833 }
834-
835+
836 Q_EMIT shellSurfaceChanged(m_shellSurface);
837 }
838
839@@ -145,18 +145,21 @@
840
841 auto it = m_surfaces.find(surface);
842 if (it != m_surfaces.end()) {
843- it.value()->setAttribute(attribute, value);
844+ auto const& surface = it.value();
845+
846+ surface->setAttribute(attribute, value);
847 if (attribute == mir_surface_attrib_state &&
848 value == mir_surface_state_fullscreen) {
849+
850 // Only screen-wide applications are allowed to go fullscreen
851- if (it.value()->application()->stage() == Application::MainStage) {
852- it.value()->application()->setFullscreen(static_cast<bool>(value));
853+ if (surface->application() && surface->application()->stage() == Application::MainStage) {
854+ surface->application()->setFullscreen(static_cast<bool>(value));
855 ApplicationManager* appMgr = static_cast<ApplicationManager*>(ApplicationManager::singleton());
856 QSize displaySize = appMgr->displaySize();
857- it.value()->setWidth(displaySize.width());
858- it.value()->setHeight(displaySize.height());
859- it.value()->setX(0);
860- it.value()->setY(0);
861+ surface->setWidth(displaySize.width());
862+ surface->setHeight(displaySize.height());
863+ surface->setX(0);
864+ surface->setY(0);
865 }
866 }
867 }
868
869=== added file 'src/modules/Unity/Application/session.cpp'
870--- src/modules/Unity/Application/session.cpp 1970-01-01 00:00:00 +0000
871+++ src/modules/Unity/Application/session.cpp 2014-02-26 10:27:46 +0000
872@@ -0,0 +1,70 @@
873+/*
874+ * Copyright (C) 2014 Canonical, Ltd.
875+ *
876+ * This program is free software: you can redistribute it and/or modify it under
877+ * the terms of the GNU Lesser General Public License version 3, as published by
878+ * the Free Software Foundation.
879+ *
880+ * This program is distributed in the hope that it will be useful, but WITHOUT
881+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
882+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
883+ * Lesser General Public License for more details.
884+ *
885+ * You should have received a copy of the GNU Lesser General Public License
886+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
887+ */
888+
889+#include "session.h"
890+
891+// mir
892+#include <mir/shell/session.h>
893+#include <mir/shell/trusted_session.h>
894+
895+Session::Session(const std::shared_ptr<mir::shell::Session>& session)
896+: m_session(session)
897+, m_application(NULL)
898+{
899+}
900+
901+Session::~Session()
902+{
903+}
904+
905+std::shared_ptr<mir::shell::Session> Session::mirSession() const
906+{
907+ return m_session;
908+}
909+
910+void Session::setLifecycleState(MirLifecycleState state)
911+{
912+ m_session->set_lifecycle_state(state);
913+}
914+
915+void Session::setApplication(Application* application)
916+{
917+ m_application = application;
918+}
919+
920+Application* Session::application() const
921+{
922+ return m_application;
923+}
924+
925+bool Session::hasProcess(pid_t pid) const
926+{
927+ if (mirSession()->process_id() == pid) {
928+ return true;
929+ }
930+ auto trusted_session = mirSession()->get_trusted_session();
931+ if (trusted_session) {
932+ if (trusted_session->get_trusted_helper()->process_id() == pid) {
933+ return true;
934+ }
935+ for (pid_t application_pid : trusted_session->get_applications()) {
936+ if (application_pid == pid) {
937+ return true;
938+ }
939+ }
940+ }
941+ return false;
942+}
943\ No newline at end of file
944
945=== added file 'src/modules/Unity/Application/session.h'
946--- src/modules/Unity/Application/session.h 1970-01-01 00:00:00 +0000
947+++ src/modules/Unity/Application/session.h 2014-02-26 10:27:46 +0000
948@@ -0,0 +1,60 @@
949+/*
950+ * Copyright (C) 2014 Canonical, Ltd.
951+ *
952+ * This program is free software: you can redistribute it and/or modify it under
953+ * the terms of the GNU Lesser General Public License version 3, as published by
954+ * the Free Software Foundation.
955+ *
956+ * This program is distributed in the hope that it will be useful, but WITHOUT
957+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
958+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
959+ * Lesser General Public License for more details.
960+ *
961+ * You should have received a copy of the GNU Lesser General Public License
962+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
963+ */
964+
965+#ifndef SESSION_H
966+#define SESSION_H
967+
968+// std
969+#include <memory>
970+
971+// Mir
972+#include <mir_toolkit/common.h>
973+
974+ // Qt
975+#include <QSharedPointer>
976+
977+class Application;
978+namespace mir
979+{
980+namespace shell
981+{
982+class Session;
983+}
984+}
985+
986+class Session {
987+public:
988+ Session(const std::shared_ptr<mir::shell::Session>& session);
989+ virtual ~Session();
990+
991+ std::shared_ptr<mir::shell::Session> mirSession() const;
992+
993+ void setLifecycleState(MirLifecycleState state);
994+
995+ void setApplication(Application* application);
996+ Application* application() const;
997+
998+ bool hasProcess(pid_t pid) const;
999+
1000+protected:
1001+ void setParent(const QSharedPointer<Session>& parent);
1002+
1003+private:
1004+ std::shared_ptr<mir::shell::Session> m_session;
1005+ Application* m_application;
1006+};
1007+
1008+#endif // SESSION_H
1009
1010=== modified file 'src/unity-mir/sessionlistener.cpp'
1011--- src/unity-mir/sessionlistener.cpp 2013-11-20 14:39:50 +0000
1012+++ src/unity-mir/sessionlistener.cpp 2014-02-26 10:27:46 +0000
1013@@ -27,6 +27,7 @@
1014 DLOG("SessionListener::SessionListener (this=%p)", this);
1015 // need to register type to send over threads with signal/slot
1016 qRegisterMetaType<std::shared_ptr<msh::Session>>("std::shared_ptr<mir::shell::Session>");
1017+ qRegisterMetaType<std::shared_ptr<msh::TrustedSession>>("std::shared_ptr<mir::shell::TrustedSession>");
1018 }
1019
1020 SessionListener::~SessionListener()
1021@@ -71,3 +72,15 @@
1022 DLOG("SessionListener::destroying_surface (this=%p, session=%p, surface=%p)", this, &session, (void*)surface.get());
1023 Q_EMIT sessionDestroyingSurface(&session, surface);
1024 }
1025+
1026+void SessionListener::trusted_session_started(std::shared_ptr<mir::shell::TrustedSession> const& trusted_session)
1027+{
1028+ DLOG("SessionListener::trusted_session_started (this=%p, trusted_session=%p)", this, (void*)trusted_session.get());
1029+ Q_EMIT trustedSessionStarted(trusted_session);
1030+}
1031+
1032+void SessionListener::trusted_session_stopped(std::shared_ptr<mir::shell::TrustedSession> const& trusted_session)
1033+{
1034+ DLOG("SessionListener::trusted_session_stopped (this=%p, session=%p)", this, (void*)trusted_session.get());
1035+ Q_EMIT trustedSessionStopped(trusted_session);
1036+}
1037
1038=== modified file 'src/unity-mir/sessionlistener.h'
1039--- src/unity-mir/sessionlistener.h 2013-11-15 17:40:27 +0000
1040+++ src/unity-mir/sessionlistener.h 2014-02-26 10:27:46 +0000
1041@@ -36,6 +36,9 @@
1042 void surface_created(mir::shell::Session&, std::shared_ptr<mir::shell::Surface> const&) override;
1043 void destroying_surface(mir::shell::Session&, std::shared_ptr<mir::shell::Surface> const&) override;
1044
1045+ void trusted_session_started(std::shared_ptr<mir::shell::TrustedSession> const& trusted_session) override;
1046+ void trusted_session_stopped(std::shared_ptr<mir::shell::TrustedSession> const& trusted_session) override;
1047+
1048 Q_SIGNALS:
1049 void sessionStarting(std::shared_ptr<mir::shell::Session> const& session);
1050 void sessionStopping(std::shared_ptr<mir::shell::Session> const& session);
1051@@ -44,6 +47,9 @@
1052
1053 void sessionCreatedSurface(mir::shell::Session const*, std::shared_ptr<mir::shell::Surface> const&);
1054 void sessionDestroyingSurface(mir::shell::Session const*, std::shared_ptr<mir::shell::Surface> const&);
1055+
1056+ void trustedSessionStarted(std::shared_ptr<mir::shell::TrustedSession> const&);
1057+ void trustedSessionStopped(std::shared_ptr<mir::shell::TrustedSession> const&);
1058 };
1059
1060 #endif // SESSIONLISTENER_H
1061
1062=== modified file 'src/unity-mir/shellserverconfiguration.cpp'
1063--- src/unity-mir/shellserverconfiguration.cpp 2014-02-07 16:10:12 +0000
1064+++ src/unity-mir/shellserverconfiguration.cpp 2014-02-26 10:27:46 +0000
1065@@ -136,7 +136,7 @@
1066 // The rationale is that if when you do
1067 // the_session_authorizer()
1068 // get a pointer that is unique means that Mir is not
1069-// holding the pointer and thus when we return from the
1070+// holding the pointer and thus when we return from the
1071 // sessionAuthorizer()
1072 // scope the unique pointer will be destroyed so we return 0
1073 //

Subscribers

People subscribed via source and target branches