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