Merge lp:~nick-dedekind/qtmir/prompt_sessions into lp:qtmir

Proposed by Nick Dedekind
Status: Merged
Approved by: Gerry Boland
Approved revision: 192
Merged at revision: 216
Proposed branch: lp:~nick-dedekind/qtmir/prompt_sessions
Merge into: lp:qtmir
Diff against target: 1421 lines (+741/-56)
20 files modified
src/modules/Unity/Application/application.cpp (+73/-0)
src/modules/Unity/Application/application.h (+18/-1)
src/modules/Unity/Application/application_manager.cpp (+75/-21)
src/modules/Unity/Application/application_manager.h (+10/-4)
src/modules/Unity/Application/dbuswindowstack.cpp (+1/-1)
src/modules/Unity/Application/mirsurfaceitem.cpp (+91/-1)
src/modules/Unity/Application/mirsurfaceitem.h (+21/-0)
src/modules/Unity/Application/mirsurfacemanager.cpp (+147/-22)
src/modules/Unity/Application/mirsurfacemanager.h (+27/-4)
src/modules/Unity/Application/plugin.cpp (+1/-0)
src/platforms/mirserver/mirserver.pro (+2/-0)
src/platforms/mirserver/mirserverconfiguration.cpp (+19/-0)
src/platforms/mirserver/mirserverconfiguration.h (+4/-0)
src/platforms/mirserver/nativeinterface.cpp (+2/-0)
src/platforms/mirserver/promptsessionlistener.cpp (+64/-0)
src/platforms/mirserver/promptsessionlistener.h (+47/-0)
tests/modules/ApplicationManager/application_manager_test.cpp (+51/-2)
tests/modules/common/common.pri (+2/-0)
tests/modules/common/mock_prompt_session.h (+31/-0)
tests/modules/common/mock_prompt_session_manager.h (+55/-0)
To merge this branch: bzr merge lp:~nick-dedekind/qtmir/prompt_sessions
Reviewer Review Type Date Requested Status
Gerry Boland (community) Approve
Nick Dedekind (community) Abstain
Review via email: mp+227368@code.launchpad.net

Commit message

Added support for prompt sessions

Description of the change

Prompt Session providers are added as "surface children" of the application surface, affecting a "surface tree".

To post a comment you must log in.
Revision history for this message
Gerry Boland (gerboland) wrote :

+ if (info->contains("trust-session-demo-trusted-helper") ||
+ info->contains("unity8")) {
you removed this from unity-mir, why need it here?

Revision history for this message
Gerry Boland (gerboland) wrote :

The Application constructor in unity-mir has this line added:
    connect(this, &Application::foregroundSessionChanged, this, &Application::updateScreenshot);
Do you not need the same here?

Revision history for this message
Gerry Boland (gerboland) wrote :

> The Application constructor in unity-mir has this line added:
> connect(this, &Application::foregroundSessionChanged, this,
> &Application::updateScreenshot);
> Do you not need the same here?
No you don't. Sorry, do ignore :)

Revision history for this message
Gerry Boland (gerboland) wrote :

+ while(iter.hasNext()) {
+ if (iter.next() == promptSession) {
+ iter.remove();
+ }
https://qt-project.org/doc/qt-5/qlist.html#removeOne ?

Revision history for this message
Gerry Boland (gerboland) wrote :

    if (info->startsWith("maliit-server") || info->contains("qt5/libexec/QtWebProcess")) {
        authorized = true;
- m_fenceNExt = true;
+ m_hiddenPIDs << pid;
        return;
    }

That was done in unity-mir, needed here too, no?

Revision history for this message
Gerry Boland (gerboland) wrote :

void ApplicationManager::onPromptProviderAdded
void ApplicationManager::onPromptProviderRemoved
These have gone away (comparing with unity-mir)?

Revision history for this message
Gerry Boland (gerboland) wrote :

+void MirSurfaceItem::addChildSurface(MirSurfaceItem* surface)
there's nothing preventing a surface being made a child of the same parent twice. Mind adding a quick check for that?

+QList<QObject*> MirSurfaceItem::childSurfaces() const
+{
+ QList<QObject*> children;
+ foreachChildSurface([&](MirSurfaceItem* child) { children.append(child); });
+ return children;
+}
Why being cast to QObjects? MirSurfaceItems are registered with the qml engine.

Revision history for this message
Gerry Boland (gerboland) wrote :

> void ApplicationManager::onPromptProviderAdded
> void ApplicationManager::onPromptProviderRemoved
> These have gone away (comparing with unity-mir)?
Ignore me again

Revision history for this message
Gerry Boland (gerboland) wrote :

+void getSurfaceDecendents(MirSurfaceItem* item, QList<MirSurfaceItem*>& surfaceChildren)
am not a fan of returning the list via the argument. Why did you decide to do that? Why not just create & return a list?

+void MirSurfaceManager::refreshPromptSessionSurfaces(const Application* application)
Totally not obvious what this is doing, comment please

+ qCDebug(QTMIR_SURFACES) << "MirSurfaceManager::rehostPromptSessionSurfaces - appId=" << application->name();
comment cites incorrect method. Happens in 2 other places too.

+ MirSurfaceItem *surfaceItem = NULL;
nullptr please

+for(MirSurfaceItem* item
nit-pick: space after "for"

Revision history for this message
Gerry Boland (gerboland) wrote :

You added tests for this in unity-mir, I'd like the same tests added to this please.

review: Needs Fixing
Revision history for this message
Nick Dedekind (nick-dedekind) wrote :

> +void MirSurfaceItem::addChildSurface(MirSurfaceItem* surface)
> there's nothing preventing a surface being made a child of the same parent
> twice. Mind adding a quick check for that?
>
>
> +QList<QObject*> MirSurfaceItem::childSurfaces() const
> +{
> + QList<QObject*> children;
> + foreachChildSurface([&](MirSurfaceItem* child) { children.append(child); });
> + return children;
> +}
> Why being cast to QObjects? MirSurfaceItems are registered with the qml
> engine.

Doesn't work as an object array in qml unfortunately. Only converts QList<QObject*> properly.
QQmlListPropery<MirSurfaceItems> coulb be used, but they don't work as models for a repeater.

Revision history for this message
Nick Dedekind (nick-dedekind) wrote :

> + if (info->contains("trust-session-demo-trusted-helper") ||
> + info->contains("unity8")) {
> you removed this from unity-mir, why need it here?

Yes, need to remove. Did this before we had the trusted socket work in.

Revision history for this message
Nick Dedekind (nick-dedekind) wrote :

> if (info->startsWith("maliit-server") ||
> info->contains("qt5/libexec/QtWebProcess")) {
> authorized = true;
> - m_fenceNExt = true;
> + m_hiddenPIDs << pid;
> return;
> }
>
> That was done in unity-mir, needed here too, no?

Yep

Revision history for this message
Nick Dedekind (nick-dedekind) wrote :

> +void MirSurfaceItem::addChildSurface(MirSurfaceItem* surface)
> there's nothing preventing a surface being made a child of the same parent
> twice. Mind adding a quick check for that?

Private method. The check is made in public MirSurfaceItem::setParentSurface.

Revision history for this message
Nick Dedekind (nick-dedekind) wrote :

> +void getSurfaceDecendents(MirSurfaceItem* item, QList<MirSurfaceItem*>&
> surfaceChildren)
> am not a fan of returning the list via the argument. Why did you decide to do
> that? Why not just create & return a list?
>

Not the biggest fan either, but the method is recursive; and it's more efficient than concatenating lists together for each recursion.

184. By Nick Dedekind

review comments

Revision history for this message
Gerry Boland (gerboland) wrote :

> > +void getSurfaceDecendents(MirSurfaceItem* item, QList<MirSurfaceItem*>&
> > surfaceChildren)
> > am not a fan of returning the list via the argument. Why did you decide to
> do
> > that? Why not just create & return a list?
> >
>
> Not the biggest fan either, but the method is recursive; and it's more
> efficient than concatenating lists together for each recursion.
Ok, but do please add a quick comment saying it's used in recursion

Revision history for this message
Gerry Boland (gerboland) wrote :

> > Why being cast to QObjects? MirSurfaceItems are registered with the qml
> > engine.
>
> Doesn't work as an object array in qml unfortunately. Only converts
> QList<QObject*> properly.
> QQmlListPropery<MirSurfaceItems> coulb be used, but they don't work as models
> for a repeater.
/me suspects this is possible. Maybe we can register QList<MirSurfaceItems*> as a qml type? If no luck, I'd like a TODO or FIXME explaining why the casting

Revision history for this message
Gerry Boland (gerboland) wrote :

This breaks the test run:

./taskcontroller_test: symbol lookup error: /home/phablet/dev/qtmir/prompt_sessions/build-android/tests/modules/TaskController/../../../src/modules/Unity/Application/libunityapplicationplugin.so: undefined symbol: _ZN21PromptSessionListener21promptSessionStartingERKSt10shared_ptrIN3mir5scene13PromptSessionEE

review: Needs Fixing
Revision history for this message
Nick Dedekind (nick-dedekind) wrote :

773 + delete item;

This is wrong. shouldn't be deleting items since we're not setting the application surface to null.. hmm.

185. By Nick Dedekind

Added test for prompt session tracking

Revision history for this message
Nick Dedekind (nick-dedekind) wrote :

> You added tests for this in unity-mir, I'd like the same tests added to this
> please.

I've added a test for prompt session track, however, the surface tracking is next to impossible to mock with MAJOR effort. So I've left it for now.

Revision history for this message
Nick Dedekind (nick-dedekind) :
review: Needs Fixing
186. By Nick Dedekind

stop on destroy. disable input on surface destroy. emit removed signal rather than unparenting surfaces

Revision history for this message
Nick Dedekind (nick-dedekind) :
review: Abstain
187. By Nick Dedekind

rebased

188. By Nick Dedekind

removeOne promptSession

189. By Nick Dedekind

removeAll promptSession

Revision history for this message
Gerry Boland (gerboland) wrote :

+++ src/modules/Unity/Application/mirsurfaceitem.h
+ void removed();
how is removed different from being destroyed? I don't understand what this is for

review: Needs Information
Revision history for this message
Nick Dedekind (nick-dedekind) wrote :

> +++ src/modules/Unity/Application/mirsurfaceitem.h
> + void removed();
> how is removed different from being destroyed? I don't understand what this is
> for

If we destroy the surface, or remove it from the children, we will not be able to animate removal of the child items.
We can only do that once the UI says it's done with the surface.

Revision history for this message
Nick Dedekind (nick-dedekind) wrote :

> This breaks the test run:
>
> ./taskcontroller_test: symbol lookup error:
> /home/phablet/dev/qtmir/prompt_sessions/build-android/tests/modules/TaskContro
> ller/../../../src/modules/Unity/Application/libunityapplicationplugin.so:
> undefined symbol: _ZN21PromptSessionListener21promptSessionStartingERKSt10shar
> ed_ptrIN3mir5scene13PromptSessionEE

Not introduced by this MP. Exists in trunk.

ldd ./src/modules/Unity/Application/libunityapplicationplugin.so | grep qpa
        libqpa-mirserver.so => /usr/lib/x86_64-linux-gnu/qt5/plugins/platforms/libqpa-mirserver.so (0x00007f470de67000)

possibly something to do with:
src/modules/Unity/Application/Application.pro
QMAKE_RPATHDIR += $$[QT_INSTALL_PLUGINS]/platforms # where libqpa-mirserver.so is installed

Revision history for this message
Nick Dedekind (nick-dedekind) wrote :

> + while(iter.hasNext()) {
> + if (iter.next() == promptSession) {
> + iter.remove();
> + }
> https://qt-project.org/doc/qt-5/qlist.html#removeOne ?

Changed to removeAll

190. By Nick Dedekind

added new files to common.pri

191. By Nick Dedekind

added fixme for returning QList<QObject*> children

192. By Nick Dedekind

use qmlquicklistproperty for children surfaces

Revision history for this message
Nick Dedekind (nick-dedekind) wrote :

> > > Why being cast to QObjects? MirSurfaceItems are registered with the qml
> > > engine.
> >
> > Doesn't work as an object array in qml unfortunately. Only converts
> > QList<QObject*> properly.
> > QQmlListPropery<MirSurfaceItems> coulb be used, but they don't work as
> models
> > for a repeater.
> /me suspects this is possible. Maybe we can register QList<MirSurfaceItems*>
> as a qml type? If no luck, I'd like a TODO or FIXME explaining why the casting

Changed to QQmlListPropery<MirSurfaceItem> . problem was with namespacing.

Revision history for this message
Gerry Boland (gerboland) wrote :

LGTM

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/modules/Unity/Application/application.cpp'
2--- src/modules/Unity/Application/application.cpp 2014-07-17 12:54:30 +0000
3+++ src/modules/Unity/Application/application.cpp 2014-07-23 11:57:58 +0000
4@@ -26,6 +26,9 @@
5 // mir
6 #include <mir/scene/session.h>
7 #include <mir/scene/snapshot.h>
8+#include <mir/scene/prompt_session_manager.h>
9+
10+namespace ms = mir::scene;
11
12 namespace qtmir
13 {
14@@ -35,6 +38,7 @@
15 DesktopFileReader *desktopFileReader,
16 State state,
17 const QStringList &arguments,
18+ const std::shared_ptr<ms::PromptSessionManager>& promptSessionManager,
19 ApplicationManager *parent)
20 : ApplicationInfoInterface(desktopFileReader->appId(), parent)
21 , m_appMgr(parent)
22@@ -49,6 +53,7 @@
23 , m_arguments(arguments)
24 , m_suspendTimer(new QTimer(this))
25 , m_surface(nullptr)
26+ , m_promptSessionManager(promptSessionManager)
27 , m_screenShotGuard(new Guard)
28 {
29 qCDebug(QTMIR_APPLICATIONS) << "Application::Application - appId=" << desktopFileReader->appId() << "state=" << state;
30@@ -75,6 +80,7 @@
31 QMutexLocker lk(&screenshotMutex);
32 m_screenShotGuard.clear();
33 }
34+ stopPromptSessions();
35 delete m_desktopData;
36 delete m_surface;
37 }
38@@ -244,6 +250,7 @@
39 {
40 case Application::Suspended:
41 if (m_state == Application::Running) {
42+ stopPromptSessions();
43 session()->set_lifecycle_state(mir_lifecycle_state_will_suspend);
44 m_suspendTimer->start(3000);
45 }
46@@ -261,6 +268,7 @@
47 }
48 break;
49 case Application::Stopped:
50+ stopPromptSessions();
51 if (m_suspendTimer->isActive())
52 m_suspendTimer->stop();
53 if (m_surface) {
54@@ -406,4 +414,69 @@
55 setFullscreen(m_surface && m_surface->state() == MirSurfaceItem::Fullscreen);
56 }
57
58+void Application::appendPromptSession(const std::shared_ptr<ms::PromptSession>& promptSession)
59+{
60+ qCDebug(QTMIR_APPLICATIONS) << "Application::appendPromptSession appId=" << appId()
61+ << "promptSession=" << (promptSession ? promptSession.get() : nullptr);
62+
63+ m_promptSessions.append(promptSession);
64+}
65+
66+void Application::removePromptSession(const std::shared_ptr<ms::PromptSession>& promptSession)
67+{
68+ qCDebug(QTMIR_APPLICATIONS) << "Application::removePromptSession appId=" << appId()
69+ << "promptSession=" << (promptSession ? promptSession.get() : nullptr);
70+
71+ m_promptSessions.removeAll(promptSession);
72+}
73+
74+void Application::stopPromptSessions()
75+{
76+ QList<std::shared_ptr<ms::PromptSession>> copy(m_promptSessions);
77+
78+ QListIterator<std::shared_ptr<ms::PromptSession>> it(copy);
79+ for ( it.toBack(); it.hasPrevious(); ) {
80+ m_promptSessionManager->stop_prompt_session(it.previous());
81+ }
82+}
83+
84+std::shared_ptr<ms::PromptSession> Application::activePromptSession() const
85+{
86+ if (m_promptSessions.count() > 0)
87+ return m_promptSessions.back();
88+ return nullptr;
89+}
90+
91+void Application::foreachPromptSession(std::function<void(const std::shared_ptr<mir::scene::PromptSession>&)> f) const
92+{
93+ for (std::shared_ptr<mir::scene::PromptSession> promptSession : m_promptSessions) {
94+ f(promptSession);
95+ }
96+}
97+
98+bool Application::containsProcess(pid_t pid) const
99+{
100+ if (m_pid == pid)
101+ return true;
102+
103+ QListIterator<std::shared_ptr<ms::PromptSession>> iter(m_promptSessions);
104+ while(iter.hasNext()) {
105+ std::shared_ptr<ms::PromptSession> promptSession = iter.next();
106+
107+ std::shared_ptr<ms::Session> helper = m_promptSessionManager->helper_for(promptSession);
108+ if (helper && helper->process_id() == pid)
109+ return true;
110+
111+ bool found = false;
112+ m_promptSessionManager->for_each_provider_in(promptSession,
113+ [&found, pid](std::shared_ptr<ms::Session> const& provider) {
114+ if (provider->process_id() == pid)
115+ found = true;
116+ });
117+ if (found)
118+ return true;
119+ }
120+ return false;
121+}
122+
123 } // namespace qtmir
124
125=== modified file 'src/modules/Unity/Application/application.h'
126--- src/modules/Unity/Application/application.h 2014-07-17 11:47:18 +0000
127+++ src/modules/Unity/Application/application.h 2014-07-23 11:57:58 +0000
128@@ -31,7 +31,13 @@
129 // local
130 #include "mirsurfaceitem.h"
131
132-namespace mir { namespace scene { class Session; }}
133+namespace mir {
134+ namespace scene {
135+ class Session;
136+ class PromptSession;
137+ class PromptSessionManager;
138+ }
139+}
140
141 namespace qtmir
142 {
143@@ -69,6 +75,7 @@
144 DesktopFileReader *desktopFileReader,
145 State state,
146 const QStringList &arguments,
147+ const std::shared_ptr<mir::scene::PromptSessionManager>& promptSessionManager,
148 ApplicationManager *parent);
149 virtual ~Application();
150
151@@ -97,10 +104,14 @@
152 QString exec() const;
153 bool fullscreen() const;
154 std::shared_ptr<mir::scene::Session> session() const;
155+ std::shared_ptr<mir::scene::PromptSession> activePromptSession() const;
156+ void foreachPromptSession(std::function<void(const std::shared_ptr<mir::scene::PromptSession>&)> f) const;
157
158 Stages supportedStages() const;
159 SupportedOrientations supportedOrientations() const;
160
161+ bool containsProcess(pid_t pid) const;
162+
163 public Q_SLOTS:
164 void suspend();
165 void resume();
166@@ -127,6 +138,10 @@
167 void setSession(const std::shared_ptr<mir::scene::Session>& session);
168 void setSurface(MirSurfaceItem *surface);
169
170+ void appendPromptSession(const std::shared_ptr<mir::scene::PromptSession>& session);
171+ void removePromptSession(const std::shared_ptr<mir::scene::PromptSession>& session);
172+ void stopPromptSessions();
173+
174 void updateFullscreenProperty();
175
176 ApplicationManager* m_appMgr;
177@@ -147,6 +162,8 @@
178 QTimer* m_suspendTimer;
179 SupportedOrientations m_supportedOrientations;
180 MirSurfaceItem *m_surface;
181+ QList<std::shared_ptr<mir::scene::PromptSession>> m_promptSessions;
182+ std::shared_ptr<mir::scene::PromptSessionManager> const m_promptSessionManager;
183
184 class Guard {};
185 QSharedPointer<Guard> m_screenShotGuard;
186
187=== modified file 'src/modules/Unity/Application/application_manager.cpp'
188--- src/modules/Unity/Application/application_manager.cpp 2014-07-21 19:38:54 +0000
189+++ src/modules/Unity/Application/application_manager.cpp 2014-07-23 11:57:58 +0000
190@@ -28,6 +28,7 @@
191 #include "mirserverconfiguration.h"
192 #include "nativeinterface.h"
193 #include "sessionlistener.h"
194+#include "promptsessionlistener.h"
195 #include "sessionauthorizer.h"
196 #include "taskcontroller.h"
197 #include "logging.h"
198@@ -35,6 +36,7 @@
199 // mir
200 #include <mir/scene/surface.h>
201 #include <mir/scene/session.h>
202+#include <mir/scene/prompt_session_manager.h>
203 #include <mir/graphics/display.h>
204 #include <mir/graphics/display_buffer.h>
205 #include <mircommon/mir/geometry/rectangles.h>
206@@ -106,6 +108,14 @@
207 manager, &ApplicationManager::onSessionCreatedSurface);
208 }
209
210+void connectToPromptSessionListener(ApplicationManager * manager, PromptSessionListener * listener)
211+{
212+ QObject::connect(listener, &PromptSessionListener::promptSessionStarting,
213+ manager, &ApplicationManager::onPromptSessionStarting);
214+ QObject::connect(listener, &PromptSessionListener::promptSessionStopping,
215+ manager, &ApplicationManager::onPromptSessionStopping);
216+}
217+
218 void connectToSessionAuthorizer(ApplicationManager *manager, SessionAuthorizer *authorizer)
219 {
220 QObject::connect(authorizer, &SessionAuthorizer::requestAuthorizationForSession,
221@@ -142,6 +152,7 @@
222
223 SessionListener *sessionListener = static_cast<SessionListener*>(nativeInterface->nativeResourceForIntegration("SessionListener"));
224 SessionAuthorizer *sessionAuthorizer = static_cast<SessionAuthorizer*>(nativeInterface->nativeResourceForIntegration("SessionAuthorizer"));
225+ PromptSessionListener *promptSessionListener = static_cast<PromptSessionListener*>(nativeInterface->nativeResourceForIntegration("PromptSessionListener"));
226
227 QSharedPointer<upstart::ApplicationController> appController(new upstart::ApplicationController());
228 QSharedPointer<TaskController> taskController(new TaskController(nullptr, appController));
229@@ -161,6 +172,7 @@
230 );
231
232 connectToSessionListener(appManager, sessionListener);
233+ connectToPromptSessionListener(appManager, promptSessionListener);
234 connectToSessionAuthorizer(appManager, sessionAuthorizer);
235 connectToTaskController(appManager, taskController.data());
236
237@@ -194,7 +206,6 @@
238 , m_taskController(taskController)
239 , m_desktopFileReaderFactory(desktopFileReaderFactory)
240 , m_procInfo(procInfo)
241- , m_fenceNext(false)
242 , m_suspended(false)
243 {
244 qCDebug(QTMIR_APPLICATIONS) << "ApplicationManager::ApplicationManager (this=%p)" << this;
245@@ -450,6 +461,7 @@
246 m_desktopFileReaderFactory->createInstance(appId, m_taskController->findDesktopFileForAppId(appId)),
247 Application::Starting,
248 arguments,
249+ m_mirConfig->the_prompt_session_manager(),
250 this);
251
252 if (!application->isValid()) {
253@@ -476,7 +488,9 @@
254 m_taskController,
255 m_desktopFileReaderFactory->createInstance(appId, m_taskController->findDesktopFileForAppId(appId)),
256 Application::Starting,
257- QStringList(), this);
258+ QStringList(),
259+ m_mirConfig->the_prompt_session_manager(),
260+ this);
261
262 if (!application->isValid()) {
263 qWarning() << "Unable to instantiate application with appId" << appId;
264@@ -690,6 +704,7 @@
265
266 if (info->startsWith("maliit-server") || info->contains("qt5/libexec/QtWebProcess")) {
267 authorized = true;
268+ m_hiddenPIDs << pid;
269 return;
270 }
271
272@@ -748,7 +763,13 @@
273 << "application list with appId:" << desktopData->appId();
274
275 QStringList arguments(info->asStringList());
276- application = new Application(m_taskController, desktopData, Application::Starting, arguments, this);
277+ application = new Application(
278+ m_taskController,
279+ desktopData,
280+ Application::Starting,
281+ arguments,
282+ m_mirConfig->the_prompt_session_manager(),
283+ this);
284 application->setPid(pid);
285 application->setStage(stage);
286 application->setCanBeResumed(false);
287@@ -760,15 +781,13 @@
288 {
289 qCDebug(QTMIR_APPLICATIONS) << "ApplicationManager::onSessionStarting - sessionName=" << session->name().c_str();
290
291- if (m_fenceNext) { // needed to ignore sessions created by non-user processes (e.g. maliit)
292- m_fenceNext = false;
293- return;
294- }
295-
296- Application* application = findApplicationWithPid(session->process_id());
297+ Application* application = findApplicationWithPid(session->process_id(), false);
298 if (application && application->state() != Application::Running) {
299 application->setSession(session);
300 } else {
301+ if (m_hiddenPIDs.contains(session->process_id())) {
302+ return;
303+ }
304 qCWarning(QTMIR_APPLICATIONS) << "ApplicationManager::onSessionStarting - unmanaged application starting";
305 }
306 }
307@@ -778,7 +797,7 @@
308 qCDebug(QTMIR_APPLICATIONS) << "ApplicationManager::onSessionStopping - sessionName=" << session->name().c_str();
309
310 // in case application closed not by hand of shell, check again here:
311- Application* application = findApplicationWithSession(session);
312+ Application* application = findApplicationWithSession(session, false);
313 if (application) {
314 /* Can remove the application from the running apps list immediately in these curcumstances:
315 * 1. application is not managed by upstart (this message from Mir is only notice the app has stopped, must do
316@@ -805,6 +824,7 @@
317 application->setState(Application::Stopped);
318 }
319 }
320+ m_hiddenPIDs.removeOne(session->process_id());
321 }
322
323 void ApplicationManager::onSessionCreatedSurface(ms::Session const* session,
324@@ -813,29 +833,45 @@
325 qCDebug(QTMIR_APPLICATIONS) << "ApplicationManager::onSessionCreatedSurface - sessionName=" << session->name().c_str();
326 Q_UNUSED(surface);
327
328- Application* application = findApplicationWithSession(session);
329+ Application* application = findApplicationWithSession(session, false);
330 if (application && application->state() == Application::Starting) {
331 m_dbusWindowStack->WindowCreated(0, application->appId());
332 application->setState(Application::Running);
333 }
334 }
335
336-Application* ApplicationManager::findApplicationWithSession(const std::shared_ptr<ms::Session> &session)
337+void ApplicationManager::onPromptSessionStarting(const std::shared_ptr<ms::PromptSession>& promptSession)
338 {
339- return findApplicationWithSession(session.get());
340+ qCDebug(QTMIR_APPLICATIONS) << "ApplicationManager::onPromptSessionStarting - promptSession=" << promptSession.get();
341+
342+ Application* app = findApplicationWithSession(m_mirConfig->the_prompt_session_manager()->application_for(promptSession), false);
343+ if (app) {
344+ app->appendPromptSession(promptSession);
345+ }
346 }
347
348-Application* ApplicationManager::findApplicationWithSession(const ms::Session *session)
349+void ApplicationManager::onPromptSessionStopping(const std::shared_ptr<ms::PromptSession>& promptSession)
350 {
351+ qCDebug(QTMIR_APPLICATIONS) << "ApplicationManager::onPromptSessionStopping - promptSession=" << promptSession.get();
352+
353 for (Application *app : m_applications) {
354- if (app->session().get() == session) {
355- return app;
356- }
357+ app->removePromptSession(promptSession);
358 }
359- return nullptr;
360-}
361-
362-Application* ApplicationManager::findApplicationWithPid(const qint64 pid)
363+}
364+
365+Application* ApplicationManager::findApplicationWithSession(const std::shared_ptr<ms::Session> &session, bool includeChildSessions)
366+{
367+ return findApplicationWithSession(session.get(), includeChildSessions);
368+}
369+
370+Application* ApplicationManager::findApplicationWithSession(const ms::Session *session, bool includeChildSessions)
371+{
372+ if (!session)
373+ return nullptr;
374+ return findApplicationWithPid(session->process_id(), includeChildSessions);
375+}
376+
377+Application* ApplicationManager::findApplicationWithPid(const qint64 pid, bool includeChildSessions)
378 {
379 if (pid <= 0)
380 return nullptr;
381@@ -844,6 +880,24 @@
382 if (app->m_pid == pid) {
383 return app;
384 }
385+
386+ if (includeChildSessions && app->containsProcess(pid)) {
387+ return app;
388+ }
389+ }
390+ return nullptr;
391+}
392+
393+Application* ApplicationManager::findApplicationWithPromptSession(const mir::scene::PromptSession* promptSession)
394+{
395+ for (Application *app : m_applications) {
396+ bool found = false;
397+ app->foreachPromptSession([&](const std::shared_ptr<mir::scene::PromptSession>& ps) {
398+ if (promptSession == ps.get())
399+ found = true;
400+ });
401+ if (found)
402+ return app;
403 }
404 return nullptr;
405 }
406
407=== modified file 'src/modules/Unity/Application/application_manager.h'
408--- src/modules/Unity/Application/application_manager.h 2014-07-18 11:27:10 +0000
409+++ src/modules/Unity/Application/application_manager.h 2014-07-23 11:57:58 +0000
410@@ -35,6 +35,7 @@
411 namespace scene {
412 class Session;
413 class Surface;
414+ class PromptSession;
415 }
416 }
417
418@@ -108,7 +109,7 @@
419 bool isEmpty() const { return rowCount() == 0; }
420
421 const QList<Application*> &list() const { return m_applications; }
422- qtmir::Application* findApplicationWithPid(const qint64 pid);
423+ qtmir::Application* findApplicationWithPid(const qint64 pid, bool includeChildSessions);
424
425 public Q_SLOTS:
426 void authorizeSession(const quint64 pid, bool &authorized);
427@@ -118,6 +119,9 @@
428
429 void onSessionCreatedSurface(mir::scene::Session const*, std::shared_ptr<mir::scene::Surface> const&);
430
431+ void onPromptSessionStarting(const std::shared_ptr<mir::scene::PromptSession>& promptSession);
432+ void onPromptSessionStopping(const std::shared_ptr<mir::scene::PromptSession>& promptSession);
433+
434 void onProcessStarting(const QString& appId);
435 void onProcessStopped(const QString& appId);
436 void onProcessFailed(const QString& appId, const bool duringStartup);
437@@ -135,14 +139,16 @@
438 void setFocused(Application *application);
439 void add(Application *application);
440 void remove(Application* application);
441- Application* findApplicationWithSession(const std::shared_ptr<mir::scene::Session> &session);
442- Application* findApplicationWithSession(const mir::scene::Session *session);
443+ Application* findApplicationWithSession(const std::shared_ptr<mir::scene::Session> &session, bool includeChildSessions);
444+ Application* findApplicationWithSession(const mir::scene::Session *session, bool includeChildSessions);
445 Application* applicationForStage(Application::Stage stage);
446 QModelIndex findIndex(Application* application);
447 bool suspendApplication(Application *application);
448 void resumeApplication(Application *application);
449 QString toString() const;
450
451+ Application* findApplicationWithPromptSession(const mir::scene::PromptSession* promptSession);
452+
453 QSharedPointer<MirServerConfiguration> m_mirConfig;
454
455 QList<Application*> m_applications;
456@@ -155,7 +161,7 @@
457 QSharedPointer<DesktopFileReader::Factory> m_desktopFileReaderFactory;
458 QSharedPointer<ProcInfo> m_procInfo;
459 static ApplicationManager* the_application_manager;
460- bool m_fenceNext;
461+ QList<pid_t> m_hiddenPIDs;
462 QString m_nextFocusedAppId;
463 bool m_suspended;
464
465
466=== modified file 'src/modules/Unity/Application/dbuswindowstack.cpp'
467--- src/modules/Unity/Application/dbuswindowstack.cpp 2014-07-17 14:01:08 +0000
468+++ src/modules/Unity/Application/dbuswindowstack.cpp 2014-07-23 11:57:58 +0000
469@@ -46,7 +46,7 @@
470 {
471 AppIdDesktopFile res;
472 ApplicationManager *appMgr = static_cast<ApplicationManager*>(parent());
473- const Application *app = appMgr->findApplicationWithPid(pid);
474+ const Application *app = appMgr->findApplicationWithPid(pid, false);
475 if (app) {
476 res.app_id = app->appId();
477 res.desktop_file = app->desktopFile();
478
479=== modified file 'src/modules/Unity/Application/mirsurfaceitem.cpp'
480--- src/modules/Unity/Application/mirsurfaceitem.cpp 2014-07-22 09:48:50 +0000
481+++ src/modules/Unity/Application/mirsurfaceitem.cpp 2014-07-23 11:57:58 +0000
482@@ -260,6 +260,7 @@
483 , m_surface(surface)
484 , m_application(application)
485 , m_firstFrameDrawn(false)
486+ , m_parentSurface(nullptr)
487 , m_textureProvider(nullptr)
488 {
489 qCDebug(QTMIR_SURFACES) << "MirSurfaceItem::MirSurfaceItem";
490@@ -319,11 +320,22 @@
491 //m_surface->configure(mir_surface_attrib_focus, mir_surface_unfocused);
492 connect(this, &QQuickItem::activeFocusChanged, this, &MirSurfaceItem::updateMirSurfaceFocus);
493
494- connect(application.data(), &Application::stateChanged, this, &MirSurfaceItem::onApplicationStateChanged);
495+ if (m_application) {
496+ connect(application.data(), &Application::stateChanged, this, &MirSurfaceItem::onApplicationStateChanged);
497+ }
498 }
499
500 MirSurfaceItem::~MirSurfaceItem()
501 {
502+ QList<MirSurfaceItem*> children(m_children);
503+ for (MirSurfaceItem* child : children) {
504+ child->setParentSurface(nullptr);
505+ delete child;
506+ }
507+ if (m_parentSurface) {
508+ m_parentSurface->removeChildSurface(this);
509+ }
510+
511 qCDebug(QTMIR_SURFACES) << "MirSurfaceItem::~MirSurfaceItem - this=" << this;
512 QMutexLocker locker(&m_mutex);
513 m_surface->remove_observer(m_surfaceObserver);
514@@ -335,6 +347,15 @@
515 void MirSurfaceItem::release()
516 {
517 qCDebug(QTMIR_SURFACES) << "MirSurfaceItem::release - this=" << this;
518+
519+ QList<MirSurfaceItem*> children(m_children);
520+ for (MirSurfaceItem* child : children) {
521+ child->release();
522+ }
523+ if (m_parentSurface) {
524+ m_parentSurface->removeChildSurface(this);
525+ }
526+
527 if (m_application) {
528 m_application->setSurface(nullptr);
529 }
530@@ -684,6 +705,75 @@
531 || !m_application;
532 }
533
534+void MirSurfaceItem::setParentSurface(MirSurfaceItem* surface)
535+{
536+ if (m_parentSurface == surface || surface == this)
537+ return;
538+
539+ if (m_parentSurface) {
540+ m_parentSurface->removeChildSurface(this);
541+ }
542+
543+ m_parentSurface = surface;
544+
545+ if (m_parentSurface) {
546+ m_parentSurface->addChildSurface(this);
547+ }
548+ Q_EMIT parentSurfaceChanged(surface);
549+}
550+
551+MirSurfaceItem* MirSurfaceItem::parentSurface() const
552+{
553+ return m_parentSurface;
554+}
555+
556+void MirSurfaceItem::addChildSurface(MirSurfaceItem* surface)
557+{
558+ qDebug() << "MirSurfaceItem::addChildSurface " << surface->name() << " to " << name();
559+
560+ m_children.append(surface);
561+ Q_EMIT childSurfacesChanged();
562+}
563+
564+void MirSurfaceItem::removeChildSurface(MirSurfaceItem* surface)
565+{
566+ if (m_children.contains(surface)) {
567+ m_children.removeOne(surface);
568+
569+ Q_EMIT childSurfacesChanged();
570+ }
571+}
572+
573+void MirSurfaceItem::foreachChildSurface(std::function<void(MirSurfaceItem*)> f) const
574+{
575+ for(MirSurfaceItem* child : m_children) {
576+ f(child);
577+ }
578+}
579+
580+QQmlListProperty<MirSurfaceItem> MirSurfaceItem::childSurfaces()
581+{
582+ return QQmlListProperty<MirSurfaceItem>(this,
583+ 0,
584+ MirSurfaceItem::childSurfaceCount,
585+ MirSurfaceItem::childSurfaceAt);
586+}
587+
588+int MirSurfaceItem::childSurfaceCount(QQmlListProperty<MirSurfaceItem> *prop)
589+{
590+ MirSurfaceItem *p = qobject_cast<MirSurfaceItem*>(prop->object);
591+ return p->m_children.count();
592+}
593+
594+MirSurfaceItem* MirSurfaceItem::childSurfaceAt(QQmlListProperty<MirSurfaceItem> *prop, int index)
595+{
596+ MirSurfaceItem *p = qobject_cast<MirSurfaceItem*>(prop->object);
597+
598+ if (index < 0 || index >= p->m_children.count())
599+ return nullptr;
600+ return p->m_children[index];
601+}
602+
603 } // namespace qtmir
604
605 #include "mirsurfaceitem.moc"
606
607=== modified file 'src/modules/Unity/Application/mirsurfaceitem.h'
608--- src/modules/Unity/Application/mirsurfaceitem.h 2014-07-17 12:54:30 +0000
609+++ src/modules/Unity/Application/mirsurfaceitem.h 2014-07-23 11:57:58 +0000
610@@ -25,6 +25,7 @@
611 #include <QSet>
612 #include <QQuickItem>
613 #include <QTimer>
614+#include <QQmlListProperty>
615
616 // mir
617 #include <mir/scene/surface.h>
618@@ -72,6 +73,8 @@
619 Q_PROPERTY(Type type READ type NOTIFY typeChanged)
620 Q_PROPERTY(State state READ state NOTIFY stateChanged)
621 Q_PROPERTY(QString name READ name NOTIFY nameChanged)
622+ Q_PROPERTY(MirSurfaceItem *parentSurface READ parentSurface NOTIFY parentSurfaceChanged DESIGNABLE false FINAL)
623+ Q_PROPERTY(QQmlListProperty<qtmir::MirSurfaceItem> childSurfaces READ childSurfaces NOTIFY childSurfacesChanged DESIGNABLE false)
624
625 public:
626 explicit MirSurfaceItem(std::shared_ptr<mir::scene::Surface> surface,
627@@ -118,13 +121,21 @@
628
629 void setApplication(Application *app);
630
631+ void setParentSurface(MirSurfaceItem* surface);
632+ MirSurfaceItem* parentSurface() const;
633+ void foreachChildSurface(std::function<void(MirSurfaceItem*)> f) const;
634+
635 Q_SIGNALS:
636 void typeChanged();
637 void stateChanged();
638 void nameChanged();
639+ void parentSurfaceChanged(MirSurfaceItem* surface);
640+ void childSurfacesChanged();
641 void surfaceDestroyed();
642 void firstFrameDrawn(MirSurfaceItem *item);
643
644+ void removed();
645+
646 protected Q_SLOTS:
647 void onApplicationStateChanged();
648
649@@ -141,6 +152,13 @@
650
651 QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *);
652
653+ void addChildSurface(MirSurfaceItem* surface);
654+ void removeChildSurface(MirSurfaceItem* surface);
655+
656+ QQmlListProperty<MirSurfaceItem> childSurfaces();
657+ static int childSurfaceCount(QQmlListProperty<MirSurfaceItem> *prop);
658+ static MirSurfaceItem* childSurfaceAt(QQmlListProperty<MirSurfaceItem> *prop, int index);
659+
660 private Q_SLOTS:
661 void surfaceDamaged();
662 void dropPendingBuffers();
663@@ -175,6 +193,9 @@
664 QPointer<Application> m_application;
665 bool m_firstFrameDrawn;
666
667+ MirSurfaceItem* m_parentSurface;
668+ QList<MirSurfaceItem*> m_children;
669+
670 QMirSurfaceTextureProvider *m_textureProvider;
671
672 static UbuntuKeyboardInfo *m_ubuntuKeyboardInfo;
673
674=== modified file 'src/modules/Unity/Application/mirsurfacemanager.cpp'
675--- src/modules/Unity/Application/mirsurfacemanager.cpp 2014-07-22 10:24:24 +0000
676+++ src/modules/Unity/Application/mirsurfacemanager.cpp 2014-07-23 11:57:58 +0000
677@@ -29,6 +29,12 @@
678 #include "sessionlistener.h"
679 #include "surfaceconfigurator.h"
680 #include "logging.h"
681+#include "promptsessionlistener.h"
682+
683+// mir
684+#include <mir/scene/prompt_session.h>
685+#include <mir/scene/prompt_session_manager.h>
686+
687
688 Q_LOGGING_CATEGORY(QTMIR_SURFACES, "qtmir.surfaces")
689
690@@ -38,38 +44,62 @@
691
692 MirSurfaceManager *MirSurfaceManager::the_surface_manager = nullptr;
693
694+
695+void connectToSessionListener(MirSurfaceManager *manager, SessionListener *listener)
696+{
697+ QObject::connect(listener, &SessionListener::sessionCreatedSurface,
698+ manager, &MirSurfaceManager::onSessionCreatedSurface);
699+ QObject::connect(listener, &SessionListener::sessionDestroyingSurface,
700+ manager, &MirSurfaceManager::onSessionDestroyingSurface);
701+}
702+
703+void connectToSurfaceConfigurator(MirSurfaceManager *manager, SurfaceConfigurator *surfaceConfigurator)
704+{
705+ QObject::connect(surfaceConfigurator, &SurfaceConfigurator::surfaceAttributeChanged,
706+ manager, &MirSurfaceManager::onSurfaceAttributeChanged);
707+}
708+
709+void connectToPromptSessionListener(MirSurfaceManager * manager, PromptSessionListener * listener)
710+{
711+ QObject::connect(listener, &PromptSessionListener::promptProviderAdded,
712+ manager, &MirSurfaceManager::onPromptProviderAdded);
713+ QObject::connect(listener, &PromptSessionListener::promptProviderRemoved,
714+ manager, &MirSurfaceManager::onPromptProviderRemoved);
715+}
716+
717 MirSurfaceManager* MirSurfaceManager::singleton()
718 {
719 if (!the_surface_manager) {
720- the_surface_manager = new MirSurfaceManager();
721+
722+ NativeInterface *nativeInterface = dynamic_cast<NativeInterface*>(QGuiApplication::platformNativeInterface());
723+
724+ if (!nativeInterface) {
725+ qCritical("ERROR: Unity.Application QML plugin requires use of the 'mirserver' QPA plugin");
726+ QGuiApplication::quit();
727+ return nullptr;
728+ }
729+
730+ SessionListener *sessionListener = static_cast<SessionListener*>(nativeInterface->nativeResourceForIntegration("SessionListener"));
731+ SurfaceConfigurator *surfaceConfigurator = static_cast<SurfaceConfigurator*>(nativeInterface->nativeResourceForIntegration("SessionConfigurator"));
732+ PromptSessionListener *promptSessionListener = static_cast<PromptSessionListener*>(nativeInterface->nativeResourceForIntegration("PromptSessionListener"));
733+
734+ the_surface_manager = new MirSurfaceManager(nativeInterface->m_mirConfig);
735+
736+ connectToSessionListener(the_surface_manager, sessionListener);
737+ connectToSurfaceConfigurator(the_surface_manager, surfaceConfigurator);
738+ connectToPromptSessionListener(the_surface_manager, promptSessionListener);
739 }
740 return the_surface_manager;
741 }
742
743-MirSurfaceManager::MirSurfaceManager(QObject *parent)
744+MirSurfaceManager::MirSurfaceManager(
745+ const QSharedPointer<MirServerConfiguration>& mirConfig,
746+ QObject *parent)
747 : QAbstractListModel(parent)
748+ , m_mirConfig(mirConfig)
749 {
750 qCDebug(QTMIR_SURFACES) << "MirSurfaceManager::MirSurfaceManager - this=" << this;
751 setObjectName("qtmir::SurfaceManager");
752-
753- NativeInterface *nativeInterface = dynamic_cast<NativeInterface*>(QGuiApplication::platformNativeInterface());
754-
755- if (!nativeInterface) {
756- qCritical("ERROR: Unity.Application QML plugin requires use of the 'mirserver' QPA plugin");
757- QGuiApplication::quit();
758- return;
759- }
760-
761- SessionListener *sessionListener = static_cast<SessionListener*>(nativeInterface->nativeResourceForIntegration("SessionListener"));
762- SurfaceConfigurator *surfaceConfigurator = static_cast<SurfaceConfigurator*>(nativeInterface->nativeResourceForIntegration("SessionConfigurator"));
763-
764- QObject::connect(sessionListener, &SessionListener::sessionCreatedSurface,
765- this, &MirSurfaceManager::onSessionCreatedSurface);
766- QObject::connect(sessionListener, &SessionListener::sessionDestroyingSurface,
767- this, &MirSurfaceManager::onSessionDestroyingSurface);
768-
769- QObject::connect(surfaceConfigurator, &SurfaceConfigurator::surfaceAttributeChanged,
770- this, &MirSurfaceManager::onSurfaceAttributeChanged);
771 }
772
773 MirSurfaceManager::~MirSurfaceManager()
774@@ -94,11 +124,12 @@
775
776 ApplicationManager* appMgr = static_cast<ApplicationManager*>(ApplicationManager::singleton());
777
778- Application* application = appMgr->findApplicationWithSession(session);
779+ Application* application = appMgr->findApplicationWithSession(session, false);
780 auto qmlSurface = new MirSurfaceItem(surface, application);
781 {
782 QMutexLocker lock(&m_mutex);
783 m_mirSurfaceToItemHash.insert(surface.get(), qmlSurface);
784+ m_mirSessionToItemHash.insert(session, qmlSurface);
785 }
786
787 beginInsertRows(QModelIndex(), 0, 0);
788@@ -126,6 +157,7 @@
789 {
790 QMutexLocker lock(&m_mutex);
791 m_mirSurfaceToItemHash.remove(m_mirSurfaceToItemHash.key(mirSurfaceItem));
792+ m_mirSessionToItemHash.remove(m_mirSessionToItemHash.key(mirSurfaceItem));
793 }
794
795 int i = m_surfaceItems.indexOf(mirSurfaceItem);
796@@ -136,6 +168,8 @@
797 Q_EMIT countChanged();
798 }
799 });
800+
801+ refreshPromptSessionSurfaces(session);
802 }
803
804 void MirSurfaceManager::onSessionDestroyingSurface(const mir::scene::Session *session,
805@@ -154,6 +188,7 @@
806 {
807 QMutexLocker lock(&m_mutex);
808 m_mirSurfaceToItemHash.remove(m_mirSurfaceToItemHash.key(item));
809+ m_mirSessionToItemHash.remove(m_mirSessionToItemHash.key(item));
810 }
811
812 int i = m_surfaceItems.indexOf(item);
813@@ -163,11 +198,32 @@
814 endRemoveRows();
815 Q_EMIT countChanged();
816 }
817+
818 return;
819 }
820
821 qCritical() << "MirSurfaceManager::onSessionDestroyingSurface: unable to find MirSurfaceItem corresponding"
822 << "to surface=" << surface.get() << "surface.name=" << surface->name().c_str();
823+
824+ refreshPromptSessionSurfaces(session);
825+}
826+
827+void MirSurfaceManager::onPromptProviderAdded(const mir::scene::PromptSession *promptSession,
828+ const std::shared_ptr<mir::scene::Session> &)
829+{
830+ ApplicationManager* appMgr = static_cast<ApplicationManager*>(ApplicationManager::singleton());
831+ Application* application = appMgr->findApplicationWithPromptSession(promptSession);
832+
833+ refreshPromptSessionSurfaces(application);
834+}
835+
836+void MirSurfaceManager::onPromptProviderRemoved(const mir::scene::PromptSession *promptSession,
837+ const std::shared_ptr<mir::scene::Session> &)
838+{
839+ ApplicationManager* appMgr = static_cast<ApplicationManager*>(ApplicationManager::singleton());
840+ Application* application = appMgr->findApplicationWithPromptSession(promptSession);
841+
842+ refreshPromptSessionSurfaces(application);
843 }
844
845 // NB: Surface might be a dangling pointer here, so refrain from dereferencing it.
846@@ -209,4 +265,73 @@
847 return m_surfaceItems[index];
848 }
849
850+void getSurfaceDecendents(MirSurfaceItem* item, QList<MirSurfaceItem*>& surfaceChildren)
851+{
852+ // recursive function. fetch all decendent surface items as a list.
853+ item->foreachChildSurface([&surfaceChildren](MirSurfaceItem* child) {
854+ surfaceChildren.append(child);
855+ getSurfaceDecendents(child, surfaceChildren);
856+ });
857+}
858+
859+void MirSurfaceManager::refreshPromptSessionSurfaces(const mir::scene::Session* session)
860+{
861+ ApplicationManager* appMgr = static_cast<ApplicationManager*>(ApplicationManager::singleton());
862+ Application* application = appMgr->findApplicationWithSession(session, true);
863+
864+ refreshPromptSessionSurfaces(application);
865+}
866+
867+void MirSurfaceManager::refreshPromptSessionSurfaces(const Application* application)
868+{
869+ // Re-contruct the child surface heirachy from prompt session providers.
870+ // Each provider becomes the parent surface of the next surface,
871+ // with the application surface at the top of the heirachy.
872+
873+ if (!application)
874+ return;
875+ qCDebug(QTMIR_SURFACES) << "MirSurfaceManager::refreshPromptSessionSurfaces - appId=" << application->name();
876+
877+ std::shared_ptr<ms::PromptSessionManager> manager = m_mirConfig->the_prompt_session_manager();
878+
879+ MirSurfaceItem* parentItem = application->surface();
880+ if (!parentItem) {
881+ return;
882+ }
883+
884+ QList<MirSurfaceItem*> surfaceChildren;
885+ getSurfaceDecendents(parentItem, surfaceChildren);
886+
887+ auto refreshFn = [&](const std::shared_ptr<mir::scene::PromptSession>& promptSession) {
888+
889+ manager->for_each_provider_in(promptSession,
890+ [&](const std::shared_ptr<ms::Session> &session) {
891+ QMutexLocker lock(&m_mutex);
892+
893+ auto it = m_mirSessionToItemHash.find(session.get());
894+ MirSurfaceItem *surfaceItem = nullptr;
895+ while (it != m_mirSessionToItemHash.end() && it.key() == session.get()) {
896+ surfaceItem = it.value();
897+
898+ qCDebug(QTMIR_SURFACES) << "MirSurfaceManager::refreshPromptSessionSurfaces - " << surfaceItem->name() << "->setParent(" << parentItem->name() << ")";
899+ surfaceItem->setParentSurface(parentItem);
900+ surfaceChildren.removeOne(surfaceItem);
901+
902+ ++it;
903+ }
904+ // last session surface is parent of next provider session surface.
905+ if (surfaceItem) {
906+ parentItem = surfaceItem;
907+ }
908+ });
909+
910+ for (MirSurfaceItem* item : surfaceChildren) {
911+ qCDebug(QTMIR_SURFACES) << "MirSurfaceManager::rehostPromptSessionSurfaces - remove: " << item->name() << " from " << item->parentSurface()->name();
912+ Q_EMIT item->removed();
913+ }
914+ };
915+
916+ application->foreachPromptSession(refreshFn);
917+}
918+
919 } // namespace qtmir
920
921=== modified file 'src/modules/Unity/Application/mirsurfacemanager.h'
922--- src/modules/Unity/Application/mirsurfacemanager.h 2014-07-17 16:20:41 +0000
923+++ src/modules/Unity/Application/mirsurfacemanager.h 2014-07-23 11:57:58 +0000
924@@ -31,11 +31,19 @@
925 // local
926 #include "mirsurfaceitem.h"
927
928-namespace mir { namespace scene { class Surface; class Session; }}
929+namespace mir {
930+ namespace scene {
931+ class Surface;
932+ class Session;
933+ class PromptSession;
934+ }
935+}
936+
937+class MirServerConfiguration;
938
939 namespace qtmir {
940
941-class ShellServerConfiguration;
942+class Application;
943
944 class MirSurfaceManager : public QAbstractListModel
945 {
946@@ -51,7 +59,6 @@
947
948 static MirSurfaceManager* singleton();
949
950- MirSurfaceManager(QObject *parent = 0);
951 ~MirSurfaceManager();
952
953 // from QAbstractItemModel
954@@ -76,10 +83,26 @@
955
956 void onSurfaceAttributeChanged(const mir::scene::Surface *, MirSurfaceAttrib, int);
957
958+ void onPromptProviderAdded(const mir::scene::PromptSession *, const std::shared_ptr<mir::scene::Session> &);
959+ void onPromptProviderRemoved(const mir::scene::PromptSession *, const std::shared_ptr<mir::scene::Session> &);
960+
961+protected:
962+ MirSurfaceManager(
963+ const QSharedPointer<MirServerConfiguration>& mirConfig,
964+ QObject *parent = 0
965+ );
966+
967+ void refreshPromptSessionSurfaces(const mir::scene::Session *session);
968+ void refreshPromptSessionSurfaces(const Application* application);
969+
970+ void removePromptSessionSurface(MirSurfaceItem* surface);
971+
972 private:
973+ QSharedPointer<MirServerConfiguration> m_mirConfig;
974+
975 QHash<const mir::scene::Surface *, MirSurfaceItem *> m_mirSurfaceToItemHash;
976+ QMultiHash<const mir::scene::Session *, MirSurfaceItem *> m_mirSessionToItemHash;
977 QList<MirSurfaceItem*> m_surfaceItems;
978- ShellServerConfiguration* m_mirServer;
979 static MirSurfaceManager *the_surface_manager;
980 QMutex m_mutex;
981 };
982
983=== modified file 'src/modules/Unity/Application/plugin.cpp'
984--- src/modules/Unity/Application/plugin.cpp 2014-07-17 17:31:51 +0000
985+++ src/modules/Unity/Application/plugin.cpp 2014-07-23 11:57:58 +0000
986@@ -54,6 +54,7 @@
987 Q_ASSERT(QLatin1String(uri) == QLatin1String("Unity.Application"));
988
989 qRegisterMetaType<qtmir::ApplicationManager*>("ApplicationManager*"); //need for queueing signals
990+ qRegisterMetaType<qtmir::MirSurfaceItem*>("MirSurfaceItem*");
991
992 qmlRegisterUncreatableType<unity::shell::application::ApplicationManagerInterface>(
993 uri, 0, 1, "ApplicationManagerInterface", "Abstract interface. Cannot be created in QML");
994
995=== modified file 'src/platforms/mirserver/mirserver.pro'
996--- src/platforms/mirserver/mirserver.pro 2014-07-07 19:36:13 +0000
997+++ src/platforms/mirserver/mirserver.pro 2014-07-23 11:57:58 +0000
998@@ -28,6 +28,7 @@
999 sessionauthorizer.cpp \
1000 sessionlistener.cpp \
1001 surfaceconfigurator.cpp \
1002+ promptsessionlistener.cpp \
1003 messageprocessor.cpp \
1004 mirplacementstrategy.cpp \
1005 mirserverconfiguration.cpp \
1006@@ -52,6 +53,7 @@
1007 qmirserver.h \
1008 sessionauthorizer.h \
1009 sessionlistener.h \
1010+ promptsessionlistener.h \
1011 surfaceconfigurator.h \
1012 logging.h \
1013 messageprocessor.h \
1014
1015=== modified file 'src/platforms/mirserver/mirserverconfiguration.cpp'
1016--- src/platforms/mirserver/mirserverconfiguration.cpp 2014-07-07 19:33:56 +0000
1017+++ src/platforms/mirserver/mirserverconfiguration.cpp 2014-07-23 11:57:58 +0000
1018@@ -22,6 +22,7 @@
1019 #include "mirglconfig.h"
1020 #include "mirplacementstrategy.h"
1021 #include "mirserverstatuslistener.h"
1022+#include "promptsessionlistener.h"
1023 #include "sessionlistener.h"
1024 #include "surfaceconfigurator.h"
1025 #include "sessionauthorizer.h"
1026@@ -69,6 +70,16 @@
1027 });
1028 }
1029
1030+std::shared_ptr<ms::PromptSessionListener>
1031+MirServerConfiguration::the_prompt_session_listener()
1032+{
1033+ return prompt_session_listener(
1034+ [this]
1035+ {
1036+ return std::make_shared<PromptSessionListener>();
1037+ });
1038+}
1039+
1040 std::shared_ptr<ms::SurfaceConfigurator>
1041 MirServerConfiguration::the_surface_configurator()
1042 {
1043@@ -186,6 +197,14 @@
1044 return static_cast<SessionListener*>(sharedPtr.get());
1045 }
1046
1047+PromptSessionListener *MirServerConfiguration::promptSessionListener()
1048+{
1049+ auto sharedPtr = the_prompt_session_listener();
1050+ if (sharedPtr.unique()) return 0;
1051+
1052+ return static_cast<PromptSessionListener*>(sharedPtr.get());
1053+}
1054+
1055 SurfaceConfigurator *MirServerConfiguration::surfaceConfigurator()
1056 {
1057 auto sharedPtr = the_surface_configurator();
1058
1059=== modified file 'src/platforms/mirserver/mirserverconfiguration.h'
1060--- src/platforms/mirserver/mirserverconfiguration.h 2014-07-02 11:06:22 +0000
1061+++ src/platforms/mirserver/mirserverconfiguration.h 2014-07-23 11:57:58 +0000
1062@@ -30,6 +30,7 @@
1063 class SessionListener;
1064 class SessionAuthorizer;
1065 class SurfaceConfigurator;
1066+class PromptSessionListener;
1067
1068 class MirServerConfiguration : public QObject, public mir::DefaultServerConfiguration
1069 {
1070@@ -38,6 +39,7 @@
1071 Q_PROPERTY(SessionAuthorizer* sessionAuthorizer READ sessionAuthorizer CONSTANT)
1072 Q_PROPERTY(SessionListener* sessionListener READ sessionListener CONSTANT)
1073 Q_PROPERTY(SurfaceConfigurator* surfaceConfigurator READ surfaceConfigurator CONSTANT)
1074+ Q_PROPERTY(PromptSessionListener* promptSessionListener READ promptSessionListener CONSTANT)
1075
1076 public:
1077 MirServerConfiguration(int argc, char const* argv[], QObject* parent = 0);
1078@@ -47,6 +49,7 @@
1079 std::shared_ptr<mir::compositor::Compositor> the_compositor() override;
1080 std::shared_ptr<mir::scene::PlacementStrategy> the_placement_strategy() override;
1081 std::shared_ptr<mir::scene::SessionListener> the_session_listener() override;
1082+ std::shared_ptr<mir::scene::PromptSessionListener> the_prompt_session_listener() override;
1083 std::shared_ptr<mir::scene::SurfaceConfigurator> the_surface_configurator() override;
1084 std::shared_ptr<mir::frontend::SessionAuthorizer> the_session_authorizer() override;
1085 std::shared_ptr<mir::input::InputDispatcher> the_input_dispatcher() override;
1086@@ -59,6 +62,7 @@
1087 // getters
1088 SessionAuthorizer *sessionAuthorizer();
1089 SessionListener *sessionListener();
1090+ PromptSessionListener *promptSessionListener();
1091 SurfaceConfigurator *surfaceConfigurator();
1092
1093 private:
1094
1095=== modified file 'src/platforms/mirserver/nativeinterface.cpp'
1096--- src/platforms/mirserver/nativeinterface.cpp 2014-05-16 16:45:00 +0000
1097+++ src/platforms/mirserver/nativeinterface.cpp 2014-07-23 11:57:58 +0000
1098@@ -33,6 +33,8 @@
1099 result = m_mirConfig->surfaceConfigurator();
1100 else if (resource == "SessionListener")
1101 result = m_mirConfig->sessionListener();
1102+ else if (resource == "PromptSessionListener")
1103+ result = m_mirConfig->promptSessionListener();
1104
1105 return result;
1106 }
1107
1108=== added file 'src/platforms/mirserver/promptsessionlistener.cpp'
1109--- src/platforms/mirserver/promptsessionlistener.cpp 1970-01-01 00:00:00 +0000
1110+++ src/platforms/mirserver/promptsessionlistener.cpp 2014-07-23 11:57:58 +0000
1111@@ -0,0 +1,64 @@
1112+/*
1113+ * Copyright (C) 2014 Canonical, Ltd.
1114+ *
1115+ * This program is free software: you can redistribute it and/or modify it under
1116+ * the terms of the GNU Lesser General Public License version 3, as published by
1117+ * the Free Software Foundation.
1118+ *
1119+ * This program is distributed in the hope that it will be useful, but WITHOUT
1120+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
1121+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1122+ * Lesser General Public License for more details.
1123+ *
1124+ * You should have received a copy of the GNU Lesser General Public License
1125+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1126+ */
1127+
1128+#include "promptsessionlistener.h"
1129+#include "logging.h"
1130+
1131+namespace ms = mir::scene;
1132+
1133+Q_DECLARE_METATYPE(std::shared_ptr<ms::PromptSession>)
1134+
1135+PromptSessionListener::PromptSessionListener(QObject *parent) :
1136+ QObject(parent)
1137+{
1138+ qCDebug(QTMIR_MIR_MESSAGES) << "PromptSessionListener::PromptSessionListener - this=" << this;
1139+ qRegisterMetaType<std::shared_ptr<ms::PromptSession>>("std::shared_ptr<mir::scene::PromptSession>");
1140+}
1141+
1142+PromptSessionListener::~PromptSessionListener()
1143+{
1144+ qCDebug(QTMIR_MIR_MESSAGES) << "PromptSessionListener::~PromptSessionListener - this=" << this;
1145+}
1146+
1147+void PromptSessionListener::starting(std::shared_ptr<ms::PromptSession> const& prompt_session)
1148+{
1149+ qCDebug(QTMIR_MIR_MESSAGES) << "PromptSessionListener::starting - this=" << this << "prompt_session=" << prompt_session.get();
1150+ Q_EMIT promptSessionStarting(prompt_session);
1151+}
1152+
1153+void PromptSessionListener::stopping(std::shared_ptr<ms::PromptSession> const& prompt_session)
1154+{
1155+ qCDebug(QTMIR_MIR_MESSAGES) << "PromptSessionListener::stopping - this=" << this << "prompt_session=" << prompt_session.get();
1156+ Q_EMIT promptSessionStopping(prompt_session);
1157+}
1158+
1159+void PromptSessionListener::prompt_provider_added(ms::PromptSession const& prompt_session,
1160+ std::shared_ptr<ms::Session> const& prompt_provider)
1161+{
1162+ qCDebug(QTMIR_MIR_MESSAGES) << "PromptSessionListener::prompt_provider_added - this=" << this
1163+ << "prompt_session=" << &prompt_session
1164+ << "prompt_provider=" << prompt_provider.get();
1165+ Q_EMIT promptProviderAdded(&prompt_session, prompt_provider);
1166+}
1167+
1168+void PromptSessionListener::prompt_provider_removed(ms::PromptSession const& prompt_session,
1169+ std::shared_ptr<ms::Session> const& prompt_provider)
1170+{
1171+ qCDebug(QTMIR_MIR_MESSAGES) << "PromptSessionListener::prompt_provider_removed - this=" << this
1172+ << "prompt_session=" << &prompt_session
1173+ << "prompt_provider=" << prompt_provider.get();
1174+ Q_EMIT promptProviderRemoved(&prompt_session, prompt_provider);
1175+}
1176
1177=== added file 'src/platforms/mirserver/promptsessionlistener.h'
1178--- src/platforms/mirserver/promptsessionlistener.h 1970-01-01 00:00:00 +0000
1179+++ src/platforms/mirserver/promptsessionlistener.h 2014-07-23 11:57:58 +0000
1180@@ -0,0 +1,47 @@
1181+/*
1182+ * Copyright (C) 2014 Canonical, Ltd.
1183+ *
1184+ * This program is free software: you can redistribute it and/or modify it under
1185+ * the terms of the GNU Lesser General Public License version 3, as published by
1186+ * the Free Software Foundation.
1187+ *
1188+ * This program is distributed in the hope that it will be useful, but WITHOUT
1189+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
1190+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1191+ * Lesser General Public License for more details.
1192+ *
1193+ * You should have received a copy of the GNU Lesser General Public License
1194+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1195+ */
1196+
1197+#ifndef PROMPTSESSIONLISTENER_H
1198+#define PROMPTSESSIONLISTENER_H
1199+
1200+#include <QObject>
1201+
1202+#include "mir/scene/prompt_session_listener.h"
1203+
1204+class PromptSessionListener : public QObject, public mir::scene::PromptSessionListener
1205+{
1206+ Q_OBJECT
1207+public:
1208+ explicit PromptSessionListener(QObject *parent = 0);
1209+ ~PromptSessionListener();
1210+
1211+ void starting(std::shared_ptr<mir::scene::PromptSession> const& prompt_session) override;
1212+ void stopping(std::shared_ptr<mir::scene::PromptSession> const& prompt_session) override;
1213+
1214+ void prompt_provider_added(mir::scene::PromptSession const& prompt_session,
1215+ std::shared_ptr<mir::scene::Session> const& prompt_provider) override;
1216+ void prompt_provider_removed(mir::scene::PromptSession const& prompt_session,
1217+ std::shared_ptr<mir::scene::Session> const& prompt_provider) override;
1218+
1219+Q_SIGNALS:
1220+ void promptSessionStarting(std::shared_ptr<mir::scene::PromptSession> const& session);
1221+ void promptSessionStopping(std::shared_ptr<mir::scene::PromptSession> const& session);
1222+
1223+ void promptProviderAdded(mir::scene::PromptSession const*, std::shared_ptr<mir::scene::Session> const&);
1224+ void promptProviderRemoved(mir::scene::PromptSession const*, std::shared_ptr<mir::scene::Session> const&);
1225+};
1226+
1227+#endif // SESSIONLISTENER_H
1228
1229=== modified file 'tests/modules/ApplicationManager/application_manager_test.cpp'
1230--- tests/modules/ApplicationManager/application_manager_test.cpp 2014-07-17 11:47:18 +0000
1231+++ tests/modules/ApplicationManager/application_manager_test.cpp 2014-07-23 11:57:58 +0000
1232@@ -37,9 +37,39 @@
1233 #include "mock_proc_info.h"
1234 #include "mock_session.h"
1235 #include "mock_focus_controller.h"
1236+#include "mock_prompt_session_manager.h"
1237+#include "mock_prompt_session.h"
1238
1239 using namespace qtmir;
1240
1241+namespace ms = mir::scene;
1242+
1243+class TestMirConfiguration: public MirServerConfiguration
1244+{
1245+public:
1246+ TestMirConfiguration()
1247+ : MirServerConfiguration(0, nullptr)
1248+ , mock_prompt_session_manager(std::make_shared<testing::MockPromptSessionManager>())
1249+ {
1250+ }
1251+
1252+ std::shared_ptr<ms::PromptSessionManager> the_prompt_session_manager() override
1253+ {
1254+ return prompt_session_manager([this]()
1255+ ->std::shared_ptr<ms::PromptSessionManager>
1256+ {
1257+ return the_mock_prompt_session_manager();
1258+ });
1259+ }
1260+
1261+ std::shared_ptr<testing::MockPromptSessionManager> the_mock_prompt_session_manager()
1262+ {
1263+ return mock_prompt_session_manager;
1264+ }
1265+
1266+ std::shared_ptr<testing::MockPromptSessionManager> mock_prompt_session_manager;
1267+};
1268+
1269 class ApplicationManagerTests : public ::testing::Test
1270 {
1271 public:
1272@@ -50,7 +80,7 @@
1273 [](ProcessController::OomController*){})
1274 }
1275 , mirConfig{
1276- QSharedPointer<MirServerConfiguration> (new MirServerConfiguration(0, nullptr))
1277+ QSharedPointer<TestMirConfiguration> (new TestMirConfiguration)
1278 }
1279 , taskController{
1280 QSharedPointer<TaskController> (
1281@@ -111,7 +141,7 @@
1282 testing::NiceMock<testing::MockApplicationController> appController;
1283 testing::NiceMock<testing::MockProcInfo> procInfo;
1284 testing::NiceMock<testing::MockDesktopFileReaderFactory> desktopFileReaderFactory;
1285- QSharedPointer<MirServerConfiguration> mirConfig;
1286+ QSharedPointer<TestMirConfiguration> mirConfig;
1287 QSharedPointer<TaskController> taskController;
1288 ApplicationManager applicationManager;
1289 };
1290@@ -1901,3 +1931,22 @@
1291 cv.wait(lk, [&] { return done; } );
1292 }
1293 }
1294+
1295+TEST_F(ApplicationManagerTests, applicationTracksPromptSession)
1296+{
1297+ using namespace testing;
1298+ quint64 procId1 = 5551;
1299+
1300+ auto application = startApplication(procId1, "webapp");
1301+ auto promptSession = std::make_shared<MockPromptSession>();
1302+
1303+ ON_CALL(*mirConfig->the_mock_prompt_session_manager(), application_for(_)).WillByDefault(Return(application->session()));
1304+
1305+ applicationManager.onPromptSessionStarting(promptSession);
1306+
1307+ EXPECT_EQ(application->activePromptSession(), promptSession);
1308+
1309+ applicationManager.onPromptSessionStopping(promptSession);
1310+
1311+ EXPECT_EQ(application->activePromptSession(), nullptr);
1312+}
1313
1314=== modified file 'tests/modules/common/common.pri'
1315--- tests/modules/common/common.pri 2014-07-02 23:35:16 +0000
1316+++ tests/modules/common/common.pri 2014-07-23 11:57:58 +0000
1317@@ -10,6 +10,8 @@
1318 ../common/mock_oom_controller.h \
1319 ../common/mock_process_controller.h \
1320 ../common/mock_proc_info.h \
1321+ ../common/mock_prompt_session.h
1322+ ../common/mock_prompt_session_manager.h
1323 ../common/mock_session.h
1324
1325 INCLUDEPATH += ../../../src/modules \
1326
1327=== added file 'tests/modules/common/mock_prompt_session.h'
1328--- tests/modules/common/mock_prompt_session.h 1970-01-01 00:00:00 +0000
1329+++ tests/modules/common/mock_prompt_session.h 2014-07-23 11:57:58 +0000
1330@@ -0,0 +1,31 @@
1331+/*
1332+ * Copyright (C) 2014 Canonical, Ltd.
1333+ *
1334+ * This program is free software: you can redistribute it and/or modify it under
1335+ * the terms of the GNU Lesser General Public License version 3, as published by
1336+ * the Free Software Foundation.
1337+ *
1338+ * This program is distributed in the hope that it will be useful, but WITHOUT
1339+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
1340+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1341+ * Lesser General Public License for more details.
1342+ *
1343+ * You should have received a copy of the GNU Lesser General Public License
1344+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1345+ *
1346+ */
1347+
1348+#ifndef MOCK_MIR_PROMPT_SESSION_H
1349+#define MOCK_MIR_PROMPT_SESSION_H
1350+
1351+#include <mir/scene/prompt_session.h>
1352+#include <gmock/gmock.h>
1353+
1354+namespace testing
1355+{
1356+struct MockPromptSession : public mir::scene::PromptSession
1357+{
1358+};
1359+}
1360+
1361+#endif // MOCK_MIR_PROMPT_SESSION_H
1362
1363=== added file 'tests/modules/common/mock_prompt_session_manager.h'
1364--- tests/modules/common/mock_prompt_session_manager.h 1970-01-01 00:00:00 +0000
1365+++ tests/modules/common/mock_prompt_session_manager.h 2014-07-23 11:57:58 +0000
1366@@ -0,0 +1,55 @@
1367+/*
1368+ * Copyright (C) 2014 Canonical, Ltd.
1369+ *
1370+ * This program is free software: you can redistribute it and/or modify it under
1371+ * the terms of the GNU Lesser General Public License version 3, as published by
1372+ * the Free Software Foundation.
1373+ *
1374+ * This program is distributed in the hope that it will be useful, but WITHOUT
1375+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
1376+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1377+ * Lesser General Public License for more details.
1378+ *
1379+ * You should have received a copy of the GNU Lesser General Public License
1380+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1381+ *
1382+ */
1383+
1384+#ifndef MOCK_MIR_SCENE_PROMPT_SESSION_MANAGER_H_
1385+#define MOCK_MIR_SCENE_PROMPT_SESSION_MANAGER_H_
1386+
1387+#include "mir/scene/prompt_session_manager.h"
1388+#include "mir/scene/prompt_session_creation_parameters.h"
1389+
1390+#include <gmock/gmock.h>
1391+
1392+namespace testing
1393+{
1394+class MockPromptSessionManager: public mir::scene::PromptSessionManager
1395+{
1396+public:
1397+ MOCK_CONST_METHOD2(start_prompt_session_for, std::shared_ptr<mir::scene::PromptSession>(std::shared_ptr<mir::scene::Session> const&,
1398+ mir::scene::PromptSessionCreationParameters const&));
1399+
1400+ MOCK_CONST_METHOD1(stop_prompt_session, void(std::shared_ptr<mir::scene::PromptSession> const&));
1401+
1402+ MOCK_CONST_METHOD2(add_prompt_provider, void(std::shared_ptr<mir::scene::PromptSession> const&,
1403+ std::shared_ptr<mir::scene::Session> const&));
1404+
1405+ MOCK_CONST_METHOD2(add_prompt_provider_by_pid, void(std::shared_ptr<mir::scene::PromptSession> const&,
1406+ pid_t));
1407+
1408+ MOCK_CONST_METHOD1(add_expected_session, void(std::shared_ptr<mir::scene::Session> const&));
1409+
1410+ MOCK_CONST_METHOD1(remove_session, void(std::shared_ptr<mir::scene::Session> const&));
1411+
1412+ MOCK_CONST_METHOD1(application_for, std::shared_ptr<mir::scene::Session>(std::shared_ptr<mir::scene::PromptSession> const&));
1413+
1414+ MOCK_CONST_METHOD1(helper_for, std::shared_ptr<mir::scene::Session>(std::shared_ptr<mir::scene::PromptSession> const&));
1415+
1416+ MOCK_CONST_METHOD2(for_each_provider_in, void(std::shared_ptr<mir::scene::PromptSession> const&,
1417+ std::function<void(std::shared_ptr<mir::scene::Session> const&)> const&));
1418+};
1419+} // namespace testing
1420+
1421+#endif // MOCK_MIR_SCENE_PROMPT_SESSION_MANAGER_H_

Subscribers

People subscribed via source and target branches