Merge lp:~robertcarr/mir/focus-tell-dont-ask into lp:mir
- focus-tell-dont-ask
- Merge into development-branch
Status: | Rejected |
---|---|
Rejected by: | Robert Carr |
Proposed branch: | lp:~robertcarr/mir/focus-tell-dont-ask |
Merge into: | lp:mir |
Diff against target: |
919 lines (+385/-113) 26 files modified
debian/changelog (+8/-2) include/server/mir/default_server_configuration.h (+3/-0) include/server/mir/frontend/connector_report.h (+0/-1) include/server/mir/frontend/messenger_report.h (+49/-0) include/server/mir/frontend/protobuf_ipc_factory.h (+3/-1) include/server/mir/logging/messenger_report.h (+49/-0) include/server/mir/shell/application_session.h (+6/-0) include/server/mir/shell/default_focus_mechanism.h (+2/-2) include/server/mir/shell/session.h (+5/-0) include/test/mir_test_doubles/mock_shell_session.h (+3/-0) include/test/mir_test_doubles/stub_ipc_factory.h (+6/-1) include/test/mir_test_doubles/stub_shell_session.h (+8/-0) src/server/default_server_configuration.cpp (+31/-3) src/server/frontend/CMakeLists.txt (+1/-0) src/server/frontend/null_messenger_report.cpp (+25/-0) src/server/frontend/protobuf_session_creator.cpp (+2/-2) src/server/frontend/socket_messenger.cpp (+11/-2) src/server/frontend/socket_messenger.h (+6/-1) src/server/logging/CMakeLists.txt (+1/-0) src/server/logging/messenger_report.cpp (+46/-0) src/server/shell/application_session.cpp (+39/-3) src/server/shell/default_focus_mechanism.cpp (+10/-18) tests/acceptance-tests/test_client_focus_notification.cpp (+3/-1) tests/unit-tests/frontend/CMakeLists.txt (+1/-0) tests/unit-tests/frontend/test_socket_messenger.cpp (+37/-0) tests/unit-tests/shell/test_default_focus_mechanism.cpp (+30/-76) |
To merge this branch: | bzr merge lp:~robertcarr/mir/focus-tell-dont-ask |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Robert Carr (community) | Disapprove | ||
Alan Griffiths | Needs Fixing | ||
Daniel van Vugt | Needs Fixing | ||
PS Jenkins bot (community) | continuous-integration | Needs Fixing | |
Alexandros Frantzis | Pending | ||
kevin gunn | Pending | ||
Review via email: mp+188397@code.launchpad.net |
This proposal supersedes a proposal from 2013-09-26.
Commit message
Description of the change
Broken pipe isnt present in trunk anymore so resubmitting without prereq.
===
Fixed error in ApplicationSess
Targeting to development-branch
===
Solve some of the races around focus by applying 'tell-dont-ask' in relation to internal Session state and the Focus Mechanism. Now the focus mechanism doesn't have to hold an (unsafe) shared_ptr to the last focused surface. It's ok for the Session to hold this weak_ptr, as it only attempts to lock it when holding surfaces_mutex.
This branch requires: https:/
As it will cause unfocus messages to be sent in the "connection dropped without disconnect case"(i.e. many of the protobuf tool tests which fail to call disconnect) very likely to lead to a broken pipe error.
== Old Description ==
Fix the races around focus. Essentially these stem from that holding std::shared_
So this branch changes ApplicationSession to not destroy the surface explicitly and instead rely on ~msh::Surface, which means that you really can hold a safe pointer. I think this as a reasonable choice, as the shell might want to do similar things, i.e. continue to animate a surface after a session has closed it.
==
New approach relies on ApplicationSession to hold the last focused ptr...WIP
Robert Carr (robertcarr) wrote : Posted in a previous version of this proposal | # |
Robert Carr (robertcarr) wrote : Posted in a previous version of this proposal | # |
The unsafely held surface pointer in this case is the previously focused app.
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
PASSED: Continuous integration, rev:1054
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
Alexandros Frantzis (afrantzis) wrote : Posted in a previous version of this proposal | # |
There is an inconsistency with this approach: when a session is closed its surface resources are destroyed immediately, but when a surface is explicitly destroyed the resources are not destroyed until there are no more users.
Would it (make sense|be possible) for msh::Surface to own (hold a strong pointer to) ms::Surface and rely on ~msh::Surface() in both the cases above, thus removing the msh::Surface -> ms::Surface weak_ptr dance?
Alan Griffiths (alan-griffiths) wrote : Posted in a previous version of this proposal | # |
> There is an inconsistency with this approach: when a session is closed its
> surface resources are destroyed immediately, but when a surface is explicitly
> destroyed the resources are not destroyed until there are no more users.
>
> Would it (make sense|be possible) for msh::Surface to own (hold a strong
> pointer to) ms::Surface and rely on ~msh::Surface() in both the cases above,
> thus removing the msh::Surface -> ms::Surface weak_ptr dance?
I've not yet looked at the MP, but I can contribute the origin of the "weak_ptr dance".
Once a surface has been "destroyed" it is no longer in the scenegraph (ok, SurfaceStack) and therefore not composited. If the ms::Surface continued to exist it could reach a state where it has client buffers meaning threads that require them will wait forever.
It may well be that subsequent changes (particularly the introduction of force_requests_
Alan Griffiths (alan-griffiths) wrote : Posted in a previous version of this proposal | # |
I don't think this is the right evolution of the code, but I don't think it makes things worse.
The right solution would be more complex and should probably come as part of fixing the data model.
Robert Carr (robertcarr) wrote : Posted in a previous version of this proposal | # |
I think it makes sense to not destroy the surfaces explicitly from the session (as in the last committ). It may be possible to fix the weak_ptr dance (it almost surely is possible). It's not really clear what direction this code should go in right now though (except probably not further down this one), so I am trying to just fix the crashes non invasively
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
PASSED: Continuous integration, rev:1055
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal | # |
Bug 1216727 is still happening :(
terminate called after throwing an instance of 'boost:
what(): Requesting handle for an unregistered channel
Should we just unlink it from the branch?
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal | # |
P.S. Before declaring bug 1216727 fixed, please find a machine on which you can reproduce it (using trunk). To be sure the changes are actually having an effect.
Robert Carr (robertcarr) wrote : Posted in a previous version of this proposal | # |
Can someone review this again?
Daniel van Vugt (vanvugt) : Posted in a previous version of this proposal | # |
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:1057
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal | # |
Weirdly, merging this branch now causes an almost immediate hang:
Running tests...
Test project /home/dan/
Start 1: LGPL-required
1/145 Test #1: LGPL-required .......
Start 2: GPL-required
2/145 Test #2: GPL-required .......
Start 3: acceptance-
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:1058
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal | # |
Another bug with this branch is that on Alt+Tab in demo_server_shell, the client rendering freezes. Permanently.
Robert Carr (robertcarr) wrote : Posted in a previous version of this proposal | # |
The diff noise is because I merged https:/
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:1084
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https:/
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
kevin gunn (kgunn72) wrote : Posted in a previous version of this proposal | # |
wouldn't this require a server api bump? i think so...
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:1085
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
Alan Griffiths (alan-griffiths) wrote : Posted in a previous version of this proposal | # |
On both g++ and clang 64bit builds I see:
[ FAILED ] 2 tests, listed below:
[ FAILED ] BespokeDisplayS
[ FAILED ] BespokeDisplayS
(and so does jenkins on amd64)
Robert Ancell (robert-ancell) wrote : Posted in a previous version of this proposal | # |
This merge should be moved to lp:~mir-team/mir/development-branch
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:1085
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https:/
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:1088
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https:/
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
PASSED: Continuous integration, rev:1088
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
Kevin DuBois (kdub) wrote : Posted in a previous version of this proposal | # |
I think the idea is a step in the right direction, given the problem :) (makes more sense than the shared_ptr in the focus controller)
receive_
There's some gaps with who really has the-focus though still, like with,
148 + if (surfaces.size() == 0)
149 + {
150 + targeter-
151 + return;
152 + }
when this happens, the focus controller is unaware that it could reassign the focus... perhaps the session should accept or reject the focus, and let the focus mechanism know. I Maybe we're twisting around the funny way ms::Surface is.
Alan Griffiths (alan-griffiths) wrote : Posted in a previous version of this proposal | # |
It looked weird before, it looks weird after
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal | # |
The prereq branch needs fixing or even rejecting. And therefore its dependents will need updating too.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1088
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https:/
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
Daniel van Vugt (vanvugt) wrote : | # |
The changes to debian/changelog are old and/or wrong. Even if there's a robot cleaning it up on lp:mir, the changelog entries are still not related to this proposal.
Alan Griffiths (alan-griffiths) wrote : | # |
I think the MessengerReport changes are probably spurious.
Robert Carr (robertcarr) wrote : | # |
Not required if we can land hold-surface-alive
Unmerged revisions
- 1088. By Robert Carr
-
Fix error in relinquish focus
- 1087. By Robert Carr
-
Merge socket-
messenger- reporitng - 1086. By Robert Carr
-
Merge development-branch
- 1085. By Robert Carr
-
Typo
- 1084. By Robert Carr
-
application_
session: Introduce default_ surface_ locked to dedupe some code - 1083. By Robert Carr
-
Merge fix-1226139
- 1082. By Robert Carr
-
More cleanup
- 1081. By Robert Carr
-
Merge trunk
- 1080. By Robert Carr
-
Cleanup
- 1079. By Robert Carr
-
Mutex for surface
Preview Diff
1 | === modified file 'debian/changelog' | |||
2 | --- debian/changelog 2013-09-26 02:41:07 +0000 | |||
3 | +++ debian/changelog 2013-09-30 17:13:36 +0000 | |||
4 | @@ -1,4 +1,4 @@ | |||
6 | 1 | mir (0.0.12-0ubuntu1) UNRELEASED; urgency=low | 1 | mir (0.0.12+13.10.20130926.1-0ubuntu1) saucy; urgency=low |
7 | 2 | 2 | ||
8 | 3 | [ kg ] | 3 | [ kg ] |
9 | 4 | * bump version for ABI break (LP: #1229212) | 4 | * bump version for ABI break (LP: #1229212) |
10 | @@ -6,7 +6,13 @@ | |||
11 | 6 | [ Robert Ancell ] | 6 | [ Robert Ancell ] |
12 | 7 | * Bump version to 0.0.12 | 7 | * Bump version to 0.0.12 |
13 | 8 | 8 | ||
15 | 9 | -- Robert Ancell <robert.ancell@canonical.com> Thu, 26 Sep 2013 09:34:23 +1200 | 9 | [ Alexandros Frantzis ] |
16 | 10 | * tests: Fix compiler warning about maybe-uninitialized struct member | ||
17 | 11 | |||
18 | 12 | [ Ubuntu daily release ] | ||
19 | 13 | * Automatic snapshot from revision 1084 | ||
20 | 14 | |||
21 | 15 | -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Thu, 26 Sep 2013 08:39:29 +0000 | ||
22 | 10 | 16 | ||
23 | 11 | mir (0.0.11+13.10.20130924.1-0ubuntu1) saucy; urgency=low | 17 | mir (0.0.11+13.10.20130924.1-0ubuntu1) saucy; urgency=low |
24 | 12 | 18 | ||
25 | 13 | 19 | ||
26 | === modified file 'include/server/mir/default_server_configuration.h' | |||
27 | --- include/server/mir/default_server_configuration.h 2013-09-24 11:43:27 +0000 | |||
28 | +++ include/server/mir/default_server_configuration.h 2013-09-30 17:13:36 +0000 | |||
29 | @@ -46,6 +46,7 @@ | |||
30 | 46 | class SessionCreator; | 46 | class SessionCreator; |
31 | 47 | class SessionMediatorReport; | 47 | class SessionMediatorReport; |
32 | 48 | class MessageProcessorReport; | 48 | class MessageProcessorReport; |
33 | 49 | class MessengerReport; | ||
34 | 49 | class SessionAuthorizer; | 50 | class SessionAuthorizer; |
35 | 50 | class EventSink; | 51 | class EventSink; |
36 | 51 | class DisplayChanger; | 52 | class DisplayChanger; |
37 | @@ -165,6 +166,7 @@ | |||
38 | 165 | * @{ */ | 166 | * @{ */ |
39 | 166 | virtual std::shared_ptr<frontend::SessionMediatorReport> the_session_mediator_report(); | 167 | virtual std::shared_ptr<frontend::SessionMediatorReport> the_session_mediator_report(); |
40 | 167 | virtual std::shared_ptr<frontend::MessageProcessorReport> the_message_processor_report(); | 168 | virtual std::shared_ptr<frontend::MessageProcessorReport> the_message_processor_report(); |
41 | 169 | virtual std::shared_ptr<frontend::MessengerReport> the_messenger_report(); | ||
42 | 168 | virtual std::shared_ptr<frontend::SessionAuthorizer> the_session_authorizer(); | 170 | virtual std::shared_ptr<frontend::SessionAuthorizer> the_session_authorizer(); |
43 | 169 | virtual std::shared_ptr<frontend::Shell> the_frontend_shell(); | 171 | virtual std::shared_ptr<frontend::Shell> the_frontend_shell(); |
44 | 170 | virtual std::shared_ptr<frontend::EventSink> the_global_event_sink(); | 172 | virtual std::shared_ptr<frontend::EventSink> the_global_event_sink(); |
45 | @@ -270,6 +272,7 @@ | |||
46 | 270 | CachedPtr<frontend::ProtobufIpcFactory> ipc_factory; | 272 | CachedPtr<frontend::ProtobufIpcFactory> ipc_factory; |
47 | 271 | CachedPtr<frontend::SessionMediatorReport> session_mediator_report; | 273 | CachedPtr<frontend::SessionMediatorReport> session_mediator_report; |
48 | 272 | CachedPtr<frontend::MessageProcessorReport> message_processor_report; | 274 | CachedPtr<frontend::MessageProcessorReport> message_processor_report; |
49 | 275 | CachedPtr<frontend::MessengerReport> messenger_report; | ||
50 | 273 | CachedPtr<frontend::SessionAuthorizer> session_authorizer; | 276 | CachedPtr<frontend::SessionAuthorizer> session_authorizer; |
51 | 274 | CachedPtr<frontend::EventSink> global_event_sink; | 277 | CachedPtr<frontend::EventSink> global_event_sink; |
52 | 275 | CachedPtr<frontend::SessionCreator> session_creator; | 278 | CachedPtr<frontend::SessionCreator> session_creator; |
53 | 276 | 279 | ||
54 | === modified file 'include/server/mir/frontend/connector_report.h' | |||
55 | --- include/server/mir/frontend/connector_report.h 2013-09-24 16:20:17 +0000 | |||
56 | +++ include/server/mir/frontend/connector_report.h 2013-09-30 17:13:36 +0000 | |||
57 | @@ -42,7 +42,6 @@ | |||
58 | 42 | class NullConnectorReport : public ConnectorReport | 42 | class NullConnectorReport : public ConnectorReport |
59 | 43 | { | 43 | { |
60 | 44 | public: | 44 | public: |
61 | 45 | |||
62 | 46 | void error(std::exception const& error); | 45 | void error(std::exception const& error); |
63 | 47 | }; | 46 | }; |
64 | 48 | } | 47 | } |
65 | 49 | 48 | ||
66 | === added file 'include/server/mir/frontend/messenger_report.h' | |||
67 | --- include/server/mir/frontend/messenger_report.h 1970-01-01 00:00:00 +0000 | |||
68 | +++ include/server/mir/frontend/messenger_report.h 2013-09-30 17:13:36 +0000 | |||
69 | @@ -0,0 +1,49 @@ | |||
70 | 1 | /* | ||
71 | 2 | * Copyright © 2013 Canonical Ltd. | ||
72 | 3 | * | ||
73 | 4 | * This program is free software: you can redistribute it and/or modify it | ||
74 | 5 | * under the terms of the GNU General Public License version 3, | ||
75 | 6 | * as published by the Free Software Foundation. | ||
76 | 7 | * | ||
77 | 8 | * This program is distributed in the hope that it will be useful, | ||
78 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
79 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
80 | 11 | * GNU General Public License for more details. | ||
81 | 12 | * | ||
82 | 13 | * You should have received a copy of the GNU General Public License | ||
83 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
84 | 15 | * | ||
85 | 16 | * Authored by: Robert Carr <robert.carr@canonical.com> | ||
86 | 17 | */ | ||
87 | 18 | |||
88 | 19 | #ifndef MIR_FRONTEND_MESSENGER_REPORT_H_ | ||
89 | 20 | #define MIR_FRONTEND_MESSENGER_REPORT_H_ | ||
90 | 21 | |||
91 | 22 | #include <string> | ||
92 | 23 | |||
93 | 24 | namespace mir | ||
94 | 25 | { | ||
95 | 26 | namespace frontend | ||
96 | 27 | { | ||
97 | 28 | |||
98 | 29 | class MessengerReport | ||
99 | 30 | { | ||
100 | 31 | public: | ||
101 | 32 | virtual void error(std::string const& error_message) = 0; | ||
102 | 33 | |||
103 | 34 | protected: | ||
104 | 35 | virtual ~MessengerReport() = default; | ||
105 | 36 | MessengerReport() = default; | ||
106 | 37 | MessengerReport(const MessengerReport&) = delete; | ||
107 | 38 | MessengerReport& operator=(const MessengerReport&) = delete; | ||
108 | 39 | }; | ||
109 | 40 | |||
110 | 41 | class NullMessengerReport : public MessengerReport | ||
111 | 42 | { | ||
112 | 43 | public: | ||
113 | 44 | void error(std::string const& error_message); | ||
114 | 45 | }; | ||
115 | 46 | } | ||
116 | 47 | } | ||
117 | 48 | |||
118 | 49 | #endif // MIR_FRONTEND_MESSENGER_REPORT_H_ | ||
119 | 0 | 50 | ||
120 | === modified file 'include/server/mir/frontend/protobuf_ipc_factory.h' | |||
121 | --- include/server/mir/frontend/protobuf_ipc_factory.h 2013-08-28 03:41:48 +0000 | |||
122 | +++ include/server/mir/frontend/protobuf_ipc_factory.h 2013-09-30 17:13:36 +0000 | |||
123 | @@ -32,6 +32,7 @@ | |||
124 | 32 | class EventSink; | 32 | class EventSink; |
125 | 33 | class ResourceCache; | 33 | class ResourceCache; |
126 | 34 | class MessageProcessorReport; | 34 | class MessageProcessorReport; |
127 | 35 | class MessengerReport; | ||
128 | 35 | 36 | ||
129 | 36 | class ProtobufIpcFactory | 37 | class ProtobufIpcFactory |
130 | 37 | { | 38 | { |
131 | @@ -39,7 +40,8 @@ | |||
132 | 39 | virtual std::shared_ptr<protobuf::DisplayServer> make_ipc_server( | 40 | virtual std::shared_ptr<protobuf::DisplayServer> make_ipc_server( |
133 | 40 | std::shared_ptr<EventSink> const& sink, bool authorized_to_resize_display) = 0; | 41 | std::shared_ptr<EventSink> const& sink, bool authorized_to_resize_display) = 0; |
134 | 41 | virtual std::shared_ptr<ResourceCache> resource_cache() = 0; | 42 | virtual std::shared_ptr<ResourceCache> resource_cache() = 0; |
136 | 42 | virtual std::shared_ptr<MessageProcessorReport> report() = 0; | 43 | virtual std::shared_ptr<MessageProcessorReport> message_processor_report() = 0; |
137 | 44 | virtual std::shared_ptr<MessengerReport> messenger_report() = 0; | ||
138 | 43 | 45 | ||
139 | 44 | protected: | 46 | protected: |
140 | 45 | ProtobufIpcFactory() {} | 47 | ProtobufIpcFactory() {} |
141 | 46 | 48 | ||
142 | === added file 'include/server/mir/logging/messenger_report.h' | |||
143 | --- include/server/mir/logging/messenger_report.h 1970-01-01 00:00:00 +0000 | |||
144 | +++ include/server/mir/logging/messenger_report.h 2013-09-30 17:13:36 +0000 | |||
145 | @@ -0,0 +1,49 @@ | |||
146 | 1 | /* | ||
147 | 2 | * Copyright © 2013 Canonical Ltd. | ||
148 | 3 | * | ||
149 | 4 | * This program is free software: you can redistribute it and/or modify it | ||
150 | 5 | * under the terms of the GNU General Public License version 3, | ||
151 | 6 | * as published by the Free Software Foundation. | ||
152 | 7 | * | ||
153 | 8 | * This program is distributed in the hope that it will be useful, | ||
154 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
155 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
156 | 11 | * GNU General Public License for more details. | ||
157 | 12 | * | ||
158 | 13 | * You should have received a copy of the GNU General Public License | ||
159 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
160 | 15 | * | ||
161 | 16 | * Authored by: Alan Griffiths <alan@octopull.co.uk> | ||
162 | 17 | */ | ||
163 | 18 | |||
164 | 19 | #ifndef MIR_LOGGING_MESSENGER_REPORT_H_ | ||
165 | 20 | #define MIR_LOGGING_MESSENGER_REPORT_H_ | ||
166 | 21 | |||
167 | 22 | #include "mir/frontend/messenger_report.h" | ||
168 | 23 | |||
169 | 24 | #include <memory> | ||
170 | 25 | |||
171 | 26 | namespace mir | ||
172 | 27 | { | ||
173 | 28 | namespace logging | ||
174 | 29 | { | ||
175 | 30 | class Logger; | ||
176 | 31 | |||
177 | 32 | class MessengerReport : public frontend::MessengerReport | ||
178 | 33 | { | ||
179 | 34 | public: | ||
180 | 35 | MessengerReport(std::shared_ptr<Logger> const& logger); | ||
181 | 36 | virtual ~MessengerReport() noexcept(true) = default; | ||
182 | 37 | |||
183 | 38 | void error(std::string const& error_message); | ||
184 | 39 | |||
185 | 40 | private: | ||
186 | 41 | char const* component(); | ||
187 | 42 | std::shared_ptr<Logger> const logger; | ||
188 | 43 | }; | ||
189 | 44 | |||
190 | 45 | } | ||
191 | 46 | } | ||
192 | 47 | |||
193 | 48 | |||
194 | 49 | #endif /* MIR_LOGGING_MESSENGER_REPORT_H_ */ | ||
195 | 0 | 50 | ||
196 | === modified file 'include/server/mir/shell/application_session.h' | |||
197 | --- include/server/mir/shell/application_session.h 2013-08-28 03:41:48 +0000 | |||
198 | +++ include/server/mir/shell/application_session.h 2013-09-30 17:13:36 +0000 | |||
199 | @@ -67,6 +67,9 @@ | |||
200 | 67 | 67 | ||
201 | 68 | void set_lifecycle_state(MirLifecycleState state); | 68 | void set_lifecycle_state(MirLifecycleState state); |
202 | 69 | 69 | ||
203 | 70 | void receive_focus(std::shared_ptr<InputTargeter> const& targeter, std::shared_ptr<SurfaceController> const& controller); | ||
204 | 71 | void relinquish_focus(); | ||
205 | 72 | |||
206 | 70 | protected: | 73 | protected: |
207 | 71 | ApplicationSession(ApplicationSession const&) = delete; | 74 | ApplicationSession(ApplicationSession const&) = delete; |
208 | 72 | ApplicationSession& operator=(ApplicationSession const&) = delete; | 75 | ApplicationSession& operator=(ApplicationSession const&) = delete; |
209 | @@ -79,6 +82,7 @@ | |||
210 | 79 | std::shared_ptr<frontend::EventSink> const event_sink; | 82 | std::shared_ptr<frontend::EventSink> const event_sink; |
211 | 80 | 83 | ||
212 | 81 | frontend::SurfaceId next_id(); | 84 | frontend::SurfaceId next_id(); |
213 | 85 | std::shared_ptr<Surface> default_surface_locked(std::unique_lock<std::mutex> const& lock) const; | ||
214 | 82 | 86 | ||
215 | 83 | std::atomic<int> next_surface_id; | 87 | std::atomic<int> next_surface_id; |
216 | 84 | 88 | ||
217 | @@ -86,6 +90,8 @@ | |||
218 | 86 | Surfaces::const_iterator checked_find(frontend::SurfaceId id) const; | 90 | Surfaces::const_iterator checked_find(frontend::SurfaceId id) const; |
219 | 87 | std::mutex mutable surfaces_mutex; | 91 | std::mutex mutable surfaces_mutex; |
220 | 88 | Surfaces surfaces; | 92 | Surfaces surfaces; |
221 | 93 | |||
222 | 94 | std::weak_ptr<Surface> last_focused_surface; | ||
223 | 89 | }; | 95 | }; |
224 | 90 | 96 | ||
225 | 91 | } | 97 | } |
226 | 92 | 98 | ||
227 | === modified file 'include/server/mir/shell/default_focus_mechanism.h' | |||
228 | --- include/server/mir/shell/default_focus_mechanism.h 2013-08-28 03:41:48 +0000 | |||
229 | +++ include/server/mir/shell/default_focus_mechanism.h 2013-09-30 17:13:36 +0000 | |||
230 | @@ -50,8 +50,8 @@ | |||
231 | 50 | std::shared_ptr<InputTargeter> const input_targeter; | 50 | std::shared_ptr<InputTargeter> const input_targeter; |
232 | 51 | std::shared_ptr<SurfaceController> const surface_controller; | 51 | std::shared_ptr<SurfaceController> const surface_controller; |
233 | 52 | 52 | ||
236 | 53 | std::mutex surface_focus_lock; | 53 | std::mutex focus_lock; |
237 | 54 | std::weak_ptr<Surface> currently_focused_surface; | 54 | std::weak_ptr<Session> currently_focused_session; |
238 | 55 | }; | 55 | }; |
239 | 56 | 56 | ||
240 | 57 | } | 57 | } |
241 | 58 | 58 | ||
242 | === modified file 'include/server/mir/shell/session.h' | |||
243 | --- include/server/mir/shell/session.h 2013-08-28 03:41:48 +0000 | |||
244 | +++ include/server/mir/shell/session.h 2013-09-30 17:13:36 +0000 | |||
245 | @@ -28,6 +28,8 @@ | |||
246 | 28 | namespace shell | 28 | namespace shell |
247 | 29 | { | 29 | { |
248 | 30 | class Surface; | 30 | class Surface; |
249 | 31 | class InputTargeter; | ||
250 | 32 | class SurfaceController; | ||
251 | 31 | 33 | ||
252 | 32 | class Session : public frontend::Session | 34 | class Session : public frontend::Session |
253 | 33 | { | 35 | { |
254 | @@ -37,6 +39,9 @@ | |||
255 | 37 | 39 | ||
256 | 38 | virtual void take_snapshot(SnapshotCallback const& snapshot_taken) = 0; | 40 | virtual void take_snapshot(SnapshotCallback const& snapshot_taken) = 0; |
257 | 39 | virtual std::shared_ptr<Surface> default_surface() const = 0; | 41 | virtual std::shared_ptr<Surface> default_surface() const = 0; |
258 | 42 | |||
259 | 43 | virtual void receive_focus(std::shared_ptr<InputTargeter> const& targeter, std::shared_ptr<SurfaceController> const& controller) = 0; | ||
260 | 44 | virtual void relinquish_focus() = 0; | ||
261 | 40 | }; | 45 | }; |
262 | 41 | 46 | ||
263 | 42 | } | 47 | } |
264 | 43 | 48 | ||
265 | === modified file 'include/test/mir_test_doubles/mock_shell_session.h' | |||
266 | --- include/test/mir_test_doubles/mock_shell_session.h 2013-08-28 03:41:48 +0000 | |||
267 | +++ include/test/mir_test_doubles/mock_shell_session.h 2013-09-30 17:13:36 +0000 | |||
268 | @@ -49,6 +49,9 @@ | |||
269 | 49 | 49 | ||
270 | 50 | MOCK_METHOD1(send_display_config, void(graphics::DisplayConfiguration const&)); | 50 | MOCK_METHOD1(send_display_config, void(graphics::DisplayConfiguration const&)); |
271 | 51 | MOCK_METHOD3(configure_surface, int(frontend::SurfaceId, MirSurfaceAttrib, int)); | 51 | MOCK_METHOD3(configure_surface, int(frontend::SurfaceId, MirSurfaceAttrib, int)); |
272 | 52 | |||
273 | 53 | MOCK_METHOD2(receive_focus, void(std::shared_ptr<shell::InputTargeter> const&, std::shared_ptr<shell::SurfaceController> const&)); | ||
274 | 54 | MOCK_METHOD0(relinquish_focus, void()); | ||
275 | 52 | }; | 55 | }; |
276 | 53 | 56 | ||
277 | 54 | } | 57 | } |
278 | 55 | 58 | ||
279 | === modified file 'include/test/mir_test_doubles/stub_ipc_factory.h' | |||
280 | --- include/test/mir_test_doubles/stub_ipc_factory.h 2013-08-28 03:41:48 +0000 | |||
281 | +++ include/test/mir_test_doubles/stub_ipc_factory.h 2013-09-30 17:13:36 +0000 | |||
282 | @@ -24,6 +24,7 @@ | |||
283 | 24 | #include "mir/frontend/protobuf_ipc_factory.h" | 24 | #include "mir/frontend/protobuf_ipc_factory.h" |
284 | 25 | #include "mir/frontend/resource_cache.h" | 25 | #include "mir/frontend/resource_cache.h" |
285 | 26 | #include "mir/frontend/null_message_processor_report.h" | 26 | #include "mir/frontend/null_message_processor_report.h" |
286 | 27 | #include "mir/frontend/messenger_report.h" | ||
287 | 27 | 28 | ||
288 | 28 | namespace mir | 29 | namespace mir |
289 | 29 | { | 30 | { |
290 | @@ -53,10 +54,14 @@ | |||
291 | 53 | return cache; | 54 | return cache; |
292 | 54 | } | 55 | } |
293 | 55 | 56 | ||
295 | 56 | virtual std::shared_ptr<frontend::MessageProcessorReport> report() | 57 | virtual std::shared_ptr<frontend::MessageProcessorReport> message_processor_report() |
296 | 57 | { | 58 | { |
297 | 58 | return std::make_shared<frontend::NullMessageProcessorReport>(); | 59 | return std::make_shared<frontend::NullMessageProcessorReport>(); |
298 | 59 | } | 60 | } |
299 | 61 | virtual std::shared_ptr<frontend::MessengerReport> messenger_report() | ||
300 | 62 | { | ||
301 | 63 | return std::make_shared<frontend::NullMessengerReport>(); | ||
302 | 64 | } | ||
303 | 60 | 65 | ||
304 | 61 | std::shared_ptr<protobuf::DisplayServer> server; | 66 | std::shared_ptr<protobuf::DisplayServer> server; |
305 | 62 | std::shared_ptr<frontend::ResourceCache> const cache; | 67 | std::shared_ptr<frontend::ResourceCache> const cache; |
306 | 63 | 68 | ||
307 | === modified file 'include/test/mir_test_doubles/stub_shell_session.h' | |||
308 | --- include/test/mir_test_doubles/stub_shell_session.h 2013-08-13 22:20:37 +0000 | |||
309 | +++ include/test/mir_test_doubles/stub_shell_session.h 2013-09-30 17:13:36 +0000 | |||
310 | @@ -71,6 +71,14 @@ | |||
311 | 71 | { | 71 | { |
312 | 72 | return std::shared_ptr<shell::Surface>(); | 72 | return std::shared_ptr<shell::Surface>(); |
313 | 73 | } | 73 | } |
314 | 74 | |||
315 | 75 | void receive_focus(std::shared_ptr<shell::InputTargeter> const&, | ||
316 | 76 | std::shared_ptr<shell::SurfaceController> const&) | ||
317 | 77 | { | ||
318 | 78 | } | ||
319 | 79 | void relinquish_focus() | ||
320 | 80 | { | ||
321 | 81 | } | ||
322 | 74 | }; | 82 | }; |
323 | 75 | 83 | ||
324 | 76 | } | 84 | } |
325 | 77 | 85 | ||
326 | === modified file 'src/server/default_server_configuration.cpp' | |||
327 | --- src/server/default_server_configuration.cpp 2013-09-24 17:25:47 +0000 | |||
328 | +++ src/server/default_server_configuration.cpp 2013-09-30 17:13:36 +0000 | |||
329 | @@ -30,6 +30,7 @@ | |||
330 | 30 | #include "mir/frontend/protobuf_ipc_factory.h" | 30 | #include "mir/frontend/protobuf_ipc_factory.h" |
331 | 31 | #include "mir/frontend/session_mediator_report.h" | 31 | #include "mir/frontend/session_mediator_report.h" |
332 | 32 | #include "mir/frontend/null_message_processor_report.h" | 32 | #include "mir/frontend/null_message_processor_report.h" |
333 | 33 | #include "mir/frontend/messenger_report.h" | ||
334 | 33 | #include "mir/frontend/session_mediator.h" | 34 | #include "mir/frontend/session_mediator.h" |
335 | 34 | #include "mir/frontend/session_authorizer.h" | 35 | #include "mir/frontend/session_authorizer.h" |
336 | 35 | #include "mir/frontend/global_event_sender.h" | 36 | #include "mir/frontend/global_event_sender.h" |
337 | @@ -75,6 +76,7 @@ | |||
338 | 75 | #include "mir/logging/session_mediator_report.h" | 76 | #include "mir/logging/session_mediator_report.h" |
339 | 76 | #include "mir/logging/message_processor_report.h" | 77 | #include "mir/logging/message_processor_report.h" |
340 | 77 | #include "mir/logging/display_report.h" | 78 | #include "mir/logging/display_report.h" |
341 | 79 | #include "mir/logging/messenger_report.h" | ||
342 | 78 | #include "mir/lttng/message_processor_report.h" | 80 | #include "mir/lttng/message_processor_report.h" |
343 | 79 | #include "mir/lttng/input_report.h" | 81 | #include "mir/lttng/input_report.h" |
344 | 80 | #include "mir/shell/surface_source.h" | 82 | #include "mir/shell/surface_source.h" |
345 | @@ -113,13 +115,15 @@ | |||
346 | 113 | explicit DefaultIpcFactory( | 115 | explicit DefaultIpcFactory( |
347 | 114 | std::shared_ptr<mf::Shell> const& shell, | 116 | std::shared_ptr<mf::Shell> const& shell, |
348 | 115 | std::shared_ptr<mf::SessionMediatorReport> const& sm_report, | 117 | std::shared_ptr<mf::SessionMediatorReport> const& sm_report, |
350 | 116 | std::shared_ptr<mf::MessageProcessorReport> const& mr_report, | 118 | std::shared_ptr<mf::MessageProcessorReport> const& mp_report, |
351 | 119 | std::shared_ptr<mf::MessengerReport> const& messenger_report, | ||
352 | 117 | std::shared_ptr<mg::Platform> const& graphics_platform, | 120 | std::shared_ptr<mg::Platform> const& graphics_platform, |
353 | 118 | std::shared_ptr<mf::DisplayChanger> const& display_changer, | 121 | std::shared_ptr<mf::DisplayChanger> const& display_changer, |
354 | 119 | std::shared_ptr<mg::GraphicBufferAllocator> const& buffer_allocator) : | 122 | std::shared_ptr<mg::GraphicBufferAllocator> const& buffer_allocator) : |
355 | 120 | shell(shell), | 123 | shell(shell), |
356 | 121 | sm_report(sm_report), | 124 | sm_report(sm_report), |
358 | 122 | mp_report(mr_report), | 125 | mp_report(mp_report), |
359 | 126 | msger_report(messenger_report), | ||
360 | 123 | cache(std::make_shared<mf::ResourceCache>()), | 127 | cache(std::make_shared<mf::ResourceCache>()), |
361 | 124 | graphics_platform(graphics_platform), | 128 | graphics_platform(graphics_platform), |
362 | 125 | display_changer(display_changer), | 129 | display_changer(display_changer), |
363 | @@ -131,6 +135,7 @@ | |||
364 | 131 | std::shared_ptr<mf::Shell> shell; | 135 | std::shared_ptr<mf::Shell> shell; |
365 | 132 | std::shared_ptr<mf::SessionMediatorReport> const sm_report; | 136 | std::shared_ptr<mf::SessionMediatorReport> const sm_report; |
366 | 133 | std::shared_ptr<mf::MessageProcessorReport> const mp_report; | 137 | std::shared_ptr<mf::MessageProcessorReport> const mp_report; |
367 | 138 | std::shared_ptr<mf::MessengerReport> const msger_report; | ||
368 | 134 | std::shared_ptr<mf::ResourceCache> const cache; | 139 | std::shared_ptr<mf::ResourceCache> const cache; |
369 | 135 | std::shared_ptr<mg::Platform> const graphics_platform; | 140 | std::shared_ptr<mg::Platform> const graphics_platform; |
370 | 136 | std::shared_ptr<mf::DisplayChanger> const display_changer; | 141 | std::shared_ptr<mf::DisplayChanger> const display_changer; |
371 | @@ -164,16 +169,21 @@ | |||
372 | 164 | return cache; | 169 | return cache; |
373 | 165 | } | 170 | } |
374 | 166 | 171 | ||
376 | 167 | virtual std::shared_ptr<mf::MessageProcessorReport> report() | 172 | virtual std::shared_ptr<mf::MessageProcessorReport> message_processor_report() |
377 | 168 | { | 173 | { |
378 | 169 | return mp_report; | 174 | return mp_report; |
379 | 170 | } | 175 | } |
380 | 176 | virtual std::shared_ptr<mf::MessengerReport> messenger_report() | ||
381 | 177 | { | ||
382 | 178 | return msger_report; | ||
383 | 179 | } | ||
384 | 171 | }; | 180 | }; |
385 | 172 | 181 | ||
386 | 173 | char const* const server_socket_opt = "file"; | 182 | char const* const server_socket_opt = "file"; |
387 | 174 | char const* const no_server_socket_opt = "no-file"; | 183 | char const* const no_server_socket_opt = "no-file"; |
388 | 175 | char const* const session_mediator_report_opt = "session-mediator-report"; | 184 | char const* const session_mediator_report_opt = "session-mediator-report"; |
389 | 176 | char const* const msg_processor_report_opt = "msg-processor-report"; | 185 | char const* const msg_processor_report_opt = "msg-processor-report"; |
390 | 186 | char const* const messenger_report_opt = "messenger-report"; | ||
391 | 177 | char const* const display_report_opt = "display-report"; | 187 | char const* const display_report_opt = "display-report"; |
392 | 178 | char const* const legacy_input_report_opt = "legacy-input-report"; | 188 | char const* const legacy_input_report_opt = "legacy-input-report"; |
393 | 179 | char const* const input_report_opt = "input-report"; | 189 | char const* const input_report_opt = "input-report"; |
394 | @@ -824,6 +834,7 @@ | |||
395 | 824 | shell, | 834 | shell, |
396 | 825 | the_session_mediator_report(), | 835 | the_session_mediator_report(), |
397 | 826 | the_message_processor_report(), | 836 | the_message_processor_report(), |
398 | 837 | the_messenger_report(), | ||
399 | 827 | the_graphics_platform(), | 838 | the_graphics_platform(), |
400 | 828 | the_frontend_display_changer(), allocator); | 839 | the_frontend_display_changer(), allocator); |
401 | 829 | }); | 840 | }); |
402 | @@ -890,6 +901,23 @@ | |||
403 | 890 | }); | 901 | }); |
404 | 891 | } | 902 | } |
405 | 892 | 903 | ||
406 | 904 | std::shared_ptr<mf::MessengerReport> | ||
407 | 905 | mir::DefaultServerConfiguration::the_messenger_report() | ||
408 | 906 | { | ||
409 | 907 | return messenger_report( | ||
410 | 908 | [this]() -> std::shared_ptr<mf::MessengerReport> | ||
411 | 909 | { | ||
412 | 910 | auto report_opt = the_options()->get(messenger_report_opt, off_opt_value); | ||
413 | 911 | if (report_opt == log_opt_value) | ||
414 | 912 | { | ||
415 | 913 | return std::make_shared<ml::MessengerReport>(the_logger()); | ||
416 | 914 | } | ||
417 | 915 | else | ||
418 | 916 | { | ||
419 | 917 | return std::make_shared<mf::NullMessengerReport>(); | ||
420 | 918 | } | ||
421 | 919 | }); | ||
422 | 920 | } | ||
423 | 893 | 921 | ||
424 | 894 | std::shared_ptr<ml::Logger> mir::DefaultServerConfiguration::the_logger() | 922 | std::shared_ptr<ml::Logger> mir::DefaultServerConfiguration::the_logger() |
425 | 895 | { | 923 | { |
426 | 896 | 924 | ||
427 | === modified file 'src/server/frontend/CMakeLists.txt' | |||
428 | --- src/server/frontend/CMakeLists.txt 2013-09-24 13:27:33 +0000 | |||
429 | +++ src/server/frontend/CMakeLists.txt 2013-09-30 17:13:36 +0000 | |||
430 | @@ -5,6 +5,7 @@ | |||
431 | 5 | session_mediator.cpp | 5 | session_mediator.cpp |
432 | 6 | null_session_mediator_report.cpp | 6 | null_session_mediator_report.cpp |
433 | 7 | null_message_processor_report.cpp | 7 | null_message_processor_report.cpp |
434 | 8 | null_messenger_report.cpp | ||
435 | 8 | protobuf_message_processor.cpp | 9 | protobuf_message_processor.cpp |
436 | 9 | protobuf_buffer_packer.cpp | 10 | protobuf_buffer_packer.cpp |
437 | 10 | null_message_processor.cpp | 11 | null_message_processor.cpp |
438 | 11 | 12 | ||
439 | === added file 'src/server/frontend/null_messenger_report.cpp' | |||
440 | --- src/server/frontend/null_messenger_report.cpp 1970-01-01 00:00:00 +0000 | |||
441 | +++ src/server/frontend/null_messenger_report.cpp 2013-09-30 17:13:36 +0000 | |||
442 | @@ -0,0 +1,25 @@ | |||
443 | 1 | /* | ||
444 | 2 | * Copyright © 2013 Canonical Ltd. | ||
445 | 3 | * | ||
446 | 4 | * This program is free software: you can redistribute it and/or modify it | ||
447 | 5 | * under the terms of the GNU General Public License version 3, | ||
448 | 6 | * as published by the Free Software Foundation. | ||
449 | 7 | * | ||
450 | 8 | * This program is distributed in the hope that it will be useful, | ||
451 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
452 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
453 | 11 | * GNU General Public License for more details. | ||
454 | 12 | * | ||
455 | 13 | * You should have received a copy of the GNU General Public License | ||
456 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
457 | 15 | * | ||
458 | 16 | * Authored by: Robert Carr <robert.carr@canonical.com> | ||
459 | 17 | */ | ||
460 | 18 | |||
461 | 19 | #include "mir/frontend/messenger_report.h" | ||
462 | 20 | |||
463 | 21 | namespace mf = mir::frontend; | ||
464 | 22 | |||
465 | 23 | void mf::NullMessengerReport::error(std::string const&) | ||
466 | 24 | { | ||
467 | 25 | } | ||
468 | 0 | 26 | ||
469 | === modified file 'src/server/frontend/protobuf_session_creator.cpp' | |||
470 | --- src/server/frontend/protobuf_session_creator.cpp 2013-09-24 13:27:33 +0000 | |||
471 | +++ src/server/frontend/protobuf_session_creator.cpp 2013-09-30 17:13:36 +0000 | |||
472 | @@ -53,7 +53,7 @@ | |||
473 | 53 | 53 | ||
474 | 54 | void mf::ProtobufSessionCreator::create_session_for(std::shared_ptr<ba::local::stream_protocol::socket> const& socket) | 54 | void mf::ProtobufSessionCreator::create_session_for(std::shared_ptr<ba::local::stream_protocol::socket> const& socket) |
475 | 55 | { | 55 | { |
477 | 56 | auto const messenger = std::make_shared<detail::SocketMessenger>(socket); | 56 | auto const messenger = std::make_shared<detail::SocketMessenger>(socket, ipc_factory->messenger_report()); |
478 | 57 | auto const client_pid = messenger->client_pid(); | 57 | auto const client_pid = messenger->client_pid(); |
479 | 58 | 58 | ||
480 | 59 | if (session_authorizer->connection_is_allowed(client_pid)) | 59 | if (session_authorizer->connection_is_allowed(client_pid)) |
481 | @@ -64,7 +64,7 @@ | |||
482 | 64 | messenger, | 64 | messenger, |
483 | 65 | ipc_factory->make_ipc_server(event_sink, authorized_to_resize_display), | 65 | ipc_factory->make_ipc_server(event_sink, authorized_to_resize_display), |
484 | 66 | ipc_factory->resource_cache(), | 66 | ipc_factory->resource_cache(), |
486 | 67 | ipc_factory->report()); | 67 | ipc_factory->message_processor_report()); |
487 | 68 | 68 | ||
488 | 69 | const auto& session = std::make_shared<mfd::SocketSession>(messenger, next_id(), connected_sessions, msg_processor); | 69 | const auto& session = std::make_shared<mfd::SocketSession>(messenger, next_id(), connected_sessions, msg_processor); |
489 | 70 | connected_sessions->add(session); | 70 | connected_sessions->add(session); |
490 | 71 | 71 | ||
491 | === modified file 'src/server/frontend/socket_messenger.cpp' | |||
492 | --- src/server/frontend/socket_messenger.cpp 2013-09-25 14:18:18 +0000 | |||
493 | +++ src/server/frontend/socket_messenger.cpp 2013-09-30 17:13:36 +0000 | |||
494 | @@ -18,13 +18,16 @@ | |||
495 | 18 | 18 | ||
496 | 19 | #include "socket_messenger.h" | 19 | #include "socket_messenger.h" |
497 | 20 | #include "mir/frontend/client_constants.h" | 20 | #include "mir/frontend/client_constants.h" |
498 | 21 | #include "mir/frontend/messenger_report.h" | ||
499 | 21 | 22 | ||
500 | 22 | namespace mfd = mir::frontend::detail; | 23 | namespace mfd = mir::frontend::detail; |
501 | 23 | namespace bs = boost::system; | 24 | namespace bs = boost::system; |
502 | 24 | namespace ba = boost::asio; | 25 | namespace ba = boost::asio; |
503 | 25 | 26 | ||
506 | 26 | mfd::SocketMessenger::SocketMessenger(std::shared_ptr<ba::local::stream_protocol::socket> const& socket) | 27 | mfd::SocketMessenger::SocketMessenger(std::shared_ptr<ba::local::stream_protocol::socket> const& socket, |
507 | 27 | : socket(socket) | 28 | std::shared_ptr<MessengerReport> const& report) |
508 | 29 | : socket(socket), | ||
509 | 30 | report(report) | ||
510 | 28 | { | 31 | { |
511 | 29 | whole_message.reserve(serialization_buffer_size); | 32 | whole_message.reserve(serialization_buffer_size); |
512 | 30 | } | 33 | } |
513 | @@ -59,8 +62,14 @@ | |||
514 | 59 | // function has completed (if it would be executed asynchronously. | 62 | // function has completed (if it would be executed asynchronously. |
515 | 60 | // NOTE: we rely on this synchronous behavior as per the comment in | 63 | // NOTE: we rely on this synchronous behavior as per the comment in |
516 | 61 | // mf::SessionMediator::create_surface | 64 | // mf::SessionMediator::create_surface |
517 | 65 | |||
518 | 62 | boost::system::error_code err; | 66 | boost::system::error_code err; |
519 | 63 | ba::write(*socket, ba::buffer(whole_message), err); | 67 | ba::write(*socket, ba::buffer(whole_message), err); |
520 | 68 | if (!err) | ||
521 | 69 | { | ||
522 | 70 | report->error(err.message()); | ||
523 | 71 | } | ||
524 | 72 | |||
525 | 64 | } | 73 | } |
526 | 65 | 74 | ||
527 | 66 | void mfd::SocketMessenger::send_fds(std::vector<int32_t> const& fds) | 75 | void mfd::SocketMessenger::send_fds(std::vector<int32_t> const& fds) |
528 | 67 | 76 | ||
529 | === modified file 'src/server/frontend/socket_messenger.h' | |||
530 | --- src/server/frontend/socket_messenger.h 2013-08-28 03:41:48 +0000 | |||
531 | +++ src/server/frontend/socket_messenger.h 2013-09-30 17:13:36 +0000 | |||
532 | @@ -26,13 +26,16 @@ | |||
533 | 26 | { | 26 | { |
534 | 27 | namespace frontend | 27 | namespace frontend |
535 | 28 | { | 28 | { |
536 | 29 | class MessengerReport; | ||
537 | 30 | |||
538 | 29 | namespace detail | 31 | namespace detail |
539 | 30 | { | 32 | { |
540 | 31 | class SocketMessenger : public MessageSender, | 33 | class SocketMessenger : public MessageSender, |
541 | 32 | public MessageReceiver | 34 | public MessageReceiver |
542 | 33 | { | 35 | { |
543 | 34 | public: | 36 | public: |
545 | 35 | SocketMessenger(std::shared_ptr<boost::asio::local::stream_protocol::socket> const& socket); | 37 | SocketMessenger(std::shared_ptr<boost::asio::local::stream_protocol::socket> const& socket, |
546 | 38 | std::shared_ptr<frontend::MessengerReport> const& report); | ||
547 | 36 | 39 | ||
548 | 37 | void send(std::string const& body); | 40 | void send(std::string const& body); |
549 | 38 | void send_fds(std::vector<int32_t> const& fds); | 41 | void send_fds(std::vector<int32_t> const& fds); |
550 | @@ -42,6 +45,8 @@ | |||
551 | 42 | 45 | ||
552 | 43 | private: | 46 | private: |
553 | 44 | std::shared_ptr<boost::asio::local::stream_protocol::socket> socket; | 47 | std::shared_ptr<boost::asio::local::stream_protocol::socket> socket; |
554 | 48 | std::shared_ptr<MessengerReport> const report; | ||
555 | 49 | |||
556 | 45 | std::vector<char> whole_message; | 50 | std::vector<char> whole_message; |
557 | 46 | }; | 51 | }; |
558 | 47 | } | 52 | } |
559 | 48 | 53 | ||
560 | === modified file 'src/server/logging/CMakeLists.txt' | |||
561 | --- src/server/logging/CMakeLists.txt 2013-08-28 03:41:48 +0000 | |||
562 | +++ src/server/logging/CMakeLists.txt 2013-09-30 17:13:36 +0000 | |||
563 | @@ -6,6 +6,7 @@ | |||
564 | 6 | message_processor_report.cpp | 6 | message_processor_report.cpp |
565 | 7 | display_report.cpp | 7 | display_report.cpp |
566 | 8 | input_report.cpp | 8 | input_report.cpp |
567 | 9 | messenger_report.cpp | ||
568 | 9 | ) | 10 | ) |
569 | 10 | 11 | ||
570 | 11 | add_library( | 12 | add_library( |
571 | 12 | 13 | ||
572 | === added file 'src/server/logging/messenger_report.cpp' | |||
573 | --- src/server/logging/messenger_report.cpp 1970-01-01 00:00:00 +0000 | |||
574 | +++ src/server/logging/messenger_report.cpp 2013-09-30 17:13:36 +0000 | |||
575 | @@ -0,0 +1,46 @@ | |||
576 | 1 | /* | ||
577 | 2 | * Copyright © 2013 Canonical Ltd. | ||
578 | 3 | * | ||
579 | 4 | * This program is free software: you can redistribute it and/or modify it | ||
580 | 5 | * under the terms of the GNU General Public License version 3, | ||
581 | 6 | * as published by the Free Software Foundation. | ||
582 | 7 | * | ||
583 | 8 | * This program is distributed in the hope that it will be useful, | ||
584 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
585 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
586 | 11 | * GNU General Public License for more details. | ||
587 | 12 | * | ||
588 | 13 | * You should have received a copy of the GNU General Public License | ||
589 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
590 | 15 | * | ||
591 | 16 | * Authored by: Alan Griffiths <alan@octopull.co.uk> | ||
592 | 17 | */ | ||
593 | 18 | |||
594 | 19 | #include "mir/logging/messenger_report.h" | ||
595 | 20 | #include "mir/logging/logger.h" | ||
596 | 21 | |||
597 | 22 | #include "std/MirLog.h" | ||
598 | 23 | #include <std/Log.h> | ||
599 | 24 | |||
600 | 25 | |||
601 | 26 | #include <sstream> | ||
602 | 27 | #include <cstring> | ||
603 | 28 | #include <mutex> | ||
604 | 29 | |||
605 | 30 | namespace ml = mir::logging; | ||
606 | 31 | |||
607 | 32 | ml::MessengerReport::MessengerReport(const std::shared_ptr<Logger>& logger) | ||
608 | 33 | : logger(logger) | ||
609 | 34 | { | ||
610 | 35 | } | ||
611 | 36 | |||
612 | 37 | const char* ml::MessengerReport::component() | ||
613 | 38 | { | ||
614 | 39 | static const char* s = "messenger"; | ||
615 | 40 | return s; | ||
616 | 41 | } | ||
617 | 42 | |||
618 | 43 | void ml::MessengerReport::error(std::string const& error_message) | ||
619 | 44 | { | ||
620 | 45 | logger->log<Logger::informational>(error_message, component()); | ||
621 | 46 | } | ||
622 | 0 | 47 | ||
623 | === modified file 'src/server/shell/application_session.cpp' | |||
624 | --- src/server/shell/application_session.cpp 2013-08-28 03:41:48 +0000 | |||
625 | +++ src/server/shell/application_session.cpp 2013-09-30 17:13:36 +0000 | |||
626 | @@ -21,6 +21,7 @@ | |||
627 | 21 | #include "mir/shell/surface_factory.h" | 21 | #include "mir/shell/surface_factory.h" |
628 | 22 | #include "mir/shell/snapshot_strategy.h" | 22 | #include "mir/shell/snapshot_strategy.h" |
629 | 23 | #include "mir/shell/session_listener.h" | 23 | #include "mir/shell/session_listener.h" |
630 | 24 | #include "mir/shell/input_targeter.h" | ||
631 | 24 | #include "mir/frontend/event_sink.h" | 25 | #include "mir/frontend/event_sink.h" |
632 | 25 | 26 | ||
633 | 26 | #include <boost/throw_exception.hpp> | 27 | #include <boost/throw_exception.hpp> |
634 | @@ -99,16 +100,21 @@ | |||
635 | 99 | snapshot_strategy->take_snapshot_of(default_surface(), snapshot_taken); | 100 | snapshot_strategy->take_snapshot_of(default_surface(), snapshot_taken); |
636 | 100 | } | 101 | } |
637 | 101 | 102 | ||
639 | 102 | std::shared_ptr<msh::Surface> msh::ApplicationSession::default_surface() const | 103 | std::shared_ptr<msh::Surface> msh::ApplicationSession::default_surface_locked(std::unique_lock<std::mutex> const& /* lock */) const |
640 | 103 | { | 104 | { |
641 | 104 | std::unique_lock<std::mutex> lock(surfaces_mutex); | ||
642 | 105 | |||
643 | 106 | if (surfaces.size()) | 105 | if (surfaces.size()) |
644 | 107 | return surfaces.begin()->second; | 106 | return surfaces.begin()->second; |
645 | 108 | else | 107 | else |
646 | 109 | return std::shared_ptr<msh::Surface>(); | 108 | return std::shared_ptr<msh::Surface>(); |
647 | 110 | } | 109 | } |
648 | 111 | 110 | ||
649 | 111 | std::shared_ptr<msh::Surface> msh::ApplicationSession::default_surface() const | ||
650 | 112 | { | ||
651 | 113 | std::unique_lock<std::mutex> lock(surfaces_mutex); | ||
652 | 114 | |||
653 | 115 | return default_surface_locked(lock); | ||
654 | 116 | } | ||
655 | 117 | |||
656 | 112 | void msh::ApplicationSession::destroy_surface(mf::SurfaceId id) | 118 | void msh::ApplicationSession::destroy_surface(mf::SurfaceId id) |
657 | 113 | { | 119 | { |
658 | 114 | std::unique_lock<std::mutex> lock(surfaces_mutex); | 120 | std::unique_lock<std::mutex> lock(surfaces_mutex); |
659 | @@ -171,3 +177,33 @@ | |||
660 | 171 | { | 177 | { |
661 | 172 | event_sink->handle_lifecycle_event(state); | 178 | event_sink->handle_lifecycle_event(state); |
662 | 173 | } | 179 | } |
663 | 180 | |||
664 | 181 | void msh::ApplicationSession::receive_focus(std::shared_ptr<msh::InputTargeter> const& targeter, | ||
665 | 182 | std::shared_ptr<SurfaceController> const& controller) | ||
666 | 183 | { | ||
667 | 184 | std::unique_lock<std::mutex> lock(surfaces_mutex); | ||
668 | 185 | if (surfaces.size() == 0) | ||
669 | 186 | { | ||
670 | 187 | targeter->focus_cleared(); | ||
671 | 188 | return; | ||
672 | 189 | } | ||
673 | 190 | // Use default_surface_locked idiom instead | ||
674 | 191 | auto focus_surface = surfaces.begin()->second; | ||
675 | 192 | |||
676 | 193 | focus_surface->raise(controller); | ||
677 | 194 | focus_surface->take_input_focus(targeter); | ||
678 | 195 | focus_surface->configure(mir_surface_attrib_focus, mir_surface_focused); | ||
679 | 196 | |||
680 | 197 | last_focused_surface = focus_surface; | ||
681 | 198 | } | ||
682 | 199 | |||
683 | 200 | void msh::ApplicationSession::relinquish_focus() | ||
684 | 201 | { | ||
685 | 202 | std::unique_lock<std::mutex> lock(surfaces_mutex); | ||
686 | 203 | auto surf = last_focused_surface.lock(); | ||
687 | 204 | if (surf) | ||
688 | 205 | { | ||
689 | 206 | surf->configure(mir_surface_attrib_focus, mir_surface_unfocused); | ||
690 | 207 | } | ||
691 | 208 | last_focused_surface.reset(); | ||
692 | 209 | } | ||
693 | 174 | 210 | ||
694 | === modified file 'src/server/shell/default_focus_mechanism.cpp' | |||
695 | --- src/server/shell/default_focus_mechanism.cpp 2013-08-28 03:41:48 +0000 | |||
696 | +++ src/server/shell/default_focus_mechanism.cpp 2013-09-30 17:13:36 +0000 | |||
697 | @@ -35,28 +35,20 @@ | |||
698 | 35 | 35 | ||
699 | 36 | void msh::DefaultFocusMechanism::set_focus_to(std::shared_ptr<Session> const& focus_session) | 36 | void msh::DefaultFocusMechanism::set_focus_to(std::shared_ptr<Session> const& focus_session) |
700 | 37 | { | 37 | { |
701 | 38 | std::lock_guard<std::mutex> lg(focus_lock); | ||
702 | 39 | |||
703 | 40 | auto last_session = currently_focused_session.lock(); | ||
704 | 41 | if (last_session) | ||
705 | 42 | { | ||
706 | 43 | last_session->relinquish_focus(); | ||
707 | 44 | } | ||
708 | 45 | |||
709 | 38 | // TODO: This path should be encapsulated in a seperate clear_focus message | 46 | // TODO: This path should be encapsulated in a seperate clear_focus message |
710 | 39 | if (!focus_session) | 47 | if (!focus_session) |
711 | 40 | { | 48 | { |
712 | 41 | input_targeter->focus_cleared(); | 49 | input_targeter->focus_cleared(); |
713 | 42 | return; | 50 | return; |
714 | 43 | } | 51 | } |
733 | 44 | 52 | focus_session->receive_focus(input_targeter, surface_controller); | |
734 | 45 | auto surface = focus_session->default_surface(); | 53 | currently_focused_session = focus_session; |
717 | 46 | if (surface) | ||
718 | 47 | { | ||
719 | 48 | std::lock_guard<std::mutex> lg(surface_focus_lock); | ||
720 | 49 | auto current_focus = currently_focused_surface.lock(); | ||
721 | 50 | if (current_focus) | ||
722 | 51 | current_focus->configure(mir_surface_attrib_focus, mir_surface_unfocused); | ||
723 | 52 | surface->configure(mir_surface_attrib_focus, mir_surface_focused); | ||
724 | 53 | currently_focused_surface = surface; | ||
725 | 54 | |||
726 | 55 | surface->raise(surface_controller); | ||
727 | 56 | surface->take_input_focus(input_targeter); | ||
728 | 57 | } | ||
729 | 58 | else | ||
730 | 59 | { | ||
731 | 60 | input_targeter->focus_cleared(); | ||
732 | 61 | } | ||
735 | 62 | } | 54 | } |
736 | 63 | 55 | ||
737 | === modified file 'tests/acceptance-tests/test_client_focus_notification.cpp' | |||
738 | --- tests/acceptance-tests/test_client_focus_notification.cpp 2013-09-25 18:39:57 +0000 | |||
739 | +++ tests/acceptance-tests/test_client_focus_notification.cpp 2013-09-30 17:13:36 +0000 | |||
740 | @@ -152,7 +152,9 @@ | |||
741 | 152 | void expect_events(mt::WaitCondition* all_events_received) override | 152 | void expect_events(mt::WaitCondition* all_events_received) override |
742 | 153 | { | 153 | { |
743 | 154 | EXPECT_CALL(*observer, see(Pointee(mt::SurfaceEvent(mir_surface_attrib_focus, mir_surface_focused)))).Times(1) | 154 | EXPECT_CALL(*observer, see(Pointee(mt::SurfaceEvent(mir_surface_attrib_focus, mir_surface_focused)))).Times(1) |
745 | 155 | .WillOnce(mt::WakeUp(all_events_received)); | 155 | .WillOnce(mt::WakeUp(all_events_received)); // Now we close the surface generating an unfocused event |
746 | 156 | // libmirclient guarantees we will see this before mir_surface_release finishes, so we don't need further | ||
747 | 157 | // synchronization | ||
748 | 156 | EXPECT_CALL(*observer, see(Pointee(mt::SurfaceEvent(mir_surface_attrib_focus, mir_surface_unfocused)))).Times(1); | 158 | EXPECT_CALL(*observer, see(Pointee(mt::SurfaceEvent(mir_surface_attrib_focus, mir_surface_unfocused)))).Times(1); |
749 | 157 | } | 159 | } |
750 | 158 | } client_config; | 160 | } client_config; |
751 | 159 | 161 | ||
752 | === modified file 'tests/unit-tests/frontend/CMakeLists.txt' | |||
753 | --- tests/unit-tests/frontend/CMakeLists.txt 2013-09-24 14:13:15 +0000 | |||
754 | +++ tests/unit-tests/frontend/CMakeLists.txt 2013-09-30 17:13:36 +0000 | |||
755 | @@ -8,6 +8,7 @@ | |||
756 | 8 | ${CMAKE_CURRENT_SOURCE_DIR}/test_resource_cache.cpp | 8 | ${CMAKE_CURRENT_SOURCE_DIR}/test_resource_cache.cpp |
757 | 9 | ${CMAKE_CURRENT_SOURCE_DIR}/test_session_mediator.cpp | 9 | ${CMAKE_CURRENT_SOURCE_DIR}/test_session_mediator.cpp |
758 | 10 | ${CMAKE_CURRENT_SOURCE_DIR}/test_socket_session.cpp | 10 | ${CMAKE_CURRENT_SOURCE_DIR}/test_socket_session.cpp |
759 | 11 | ${CMAKE_CURRENT_SOURCE_DIR}/test_socket_messenger.cpp | ||
760 | 11 | ${CMAKE_CURRENT_SOURCE_DIR}/test_event_sender.cpp | 12 | ${CMAKE_CURRENT_SOURCE_DIR}/test_event_sender.cpp |
761 | 12 | ${CMAKE_CURRENT_SOURCE_DIR}/test_global_event_sender.cpp | 13 | ${CMAKE_CURRENT_SOURCE_DIR}/test_global_event_sender.cpp |
762 | 13 | ) | 14 | ) |
763 | 14 | 15 | ||
764 | === added file 'tests/unit-tests/frontend/test_socket_messenger.cpp' | |||
765 | --- tests/unit-tests/frontend/test_socket_messenger.cpp 1970-01-01 00:00:00 +0000 | |||
766 | +++ tests/unit-tests/frontend/test_socket_messenger.cpp 2013-09-30 17:13:36 +0000 | |||
767 | @@ -0,0 +1,37 @@ | |||
768 | 1 | /* | ||
769 | 2 | * Copyright © 2013 Canonical Ltd. | ||
770 | 3 | * | ||
771 | 4 | * This program is free software: you can redistribute it and/or modify | ||
772 | 5 | * it under the terms of the GNU General Public License version 3 as | ||
773 | 6 | * published by the Free Software Foundation. | ||
774 | 7 | * | ||
775 | 8 | * This program is distributed in the hope that it will be useful, | ||
776 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
777 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
778 | 11 | * GNU General Public License for more details. | ||
779 | 12 | * | ||
780 | 13 | * You should have received a copy of the GNU General Public License | ||
781 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
782 | 15 | * | ||
783 | 16 | * Authored by: Daniel van Vugt <daniel.van.vugt@canonical.com> | ||
784 | 17 | */ | ||
785 | 18 | |||
786 | 19 | #include "mir/frontend/messenger_report.h" | ||
787 | 20 | #include "src/server/frontend/socket_messenger.h" | ||
788 | 21 | |||
789 | 22 | #include <gmock/gmock.h> | ||
790 | 23 | #include <gtest/gtest.h> | ||
791 | 24 | |||
792 | 25 | namespace mf = mir::frontend; | ||
793 | 26 | |||
794 | 27 | using namespace mf::detail; | ||
795 | 28 | using namespace boost::asio; | ||
796 | 29 | |||
797 | 30 | TEST(SocketMessengerTest, write_failures_never_throw) | ||
798 | 31 | { | ||
799 | 32 | io_service svc; | ||
800 | 33 | auto sock = std::make_shared<local::stream_protocol::socket>(svc); | ||
801 | 34 | SocketMessenger mess(sock, std::make_shared<mf::NullMessengerReport>()); | ||
802 | 35 | |||
803 | 36 | EXPECT_NO_THROW( mess.send("foo") ); | ||
804 | 37 | } | ||
805 | 0 | 38 | ||
806 | === modified file 'tests/unit-tests/shell/test_default_focus_mechanism.cpp' | |||
807 | --- tests/unit-tests/shell/test_default_focus_mechanism.cpp 2013-08-28 03:41:48 +0000 | |||
808 | +++ tests/unit-tests/shell/test_default_focus_mechanism.cpp 2013-09-30 17:13:36 +0000 | |||
809 | @@ -47,80 +47,34 @@ | |||
810 | 47 | namespace mt = mir::test; | 47 | namespace mt = mir::test; |
811 | 48 | namespace mtd = mir::test::doubles; | 48 | namespace mtd = mir::test::doubles; |
812 | 49 | 49 | ||
889 | 50 | TEST(DefaultFocusMechanism, raises_default_surface) | 50 | TEST(DefaultFocusMechanism, hands_focus_to_session) |
890 | 51 | { | 51 | { |
891 | 52 | using namespace ::testing; | 52 | using namespace ::testing; |
892 | 53 | 53 | ||
893 | 54 | NiceMock<mtd::MockShellSession> app1; | 54 | mtd::MockShellSession app1; |
894 | 55 | mtd::MockSurface mock_surface(&app1, std::make_shared<mtd::StubSurfaceBuilder>()); | 55 | EXPECT_CALL(app1, receive_focus(_, _)).Times(1); |
895 | 56 | { | 56 | |
896 | 57 | InSequence seq; | 57 | msh::DefaultFocusMechanism focus_mechanism(std::make_shared<mtd::StubInputTargeter>(), std::make_shared<mtd::StubSurfaceController>()); |
897 | 58 | EXPECT_CALL(app1, default_surface()).Times(1) | 58 | |
898 | 59 | .WillOnce(Return(mt::fake_shared(mock_surface))); | 59 | focus_mechanism.set_focus_to(mt::fake_shared(app1)); |
899 | 60 | } | 60 | } |
900 | 61 | 61 | ||
901 | 62 | auto controller = std::make_shared<mtd::StubSurfaceController>(); | 62 | TEST(DefaultFocusMechanism, relinquishes_focus_from_last_session) |
902 | 63 | EXPECT_CALL(mock_surface, raise(Eq(controller))).Times(1); | 63 | { |
903 | 64 | mtd::StubInputTargeter targeter; | 64 | using namespace ::testing; |
904 | 65 | msh::DefaultFocusMechanism focus_mechanism(mt::fake_shared(targeter), controller); | 65 | |
905 | 66 | 66 | auto app1 = std::make_shared<mtd::MockShellSession>(); | |
906 | 67 | focus_mechanism.set_focus_to(mt::fake_shared(app1)); | 67 | auto app2 = std::make_shared<mtd::MockShellSession>(); |
907 | 68 | } | 68 | |
908 | 69 | 69 | { | |
909 | 70 | TEST(DefaultFocusMechanism, mechanism_notifies_default_surface_of_focus_changes) | 70 | InSequence seq; |
910 | 71 | { | 71 | EXPECT_CALL(*app1, receive_focus(_, _)).Times(1); |
911 | 72 | using namespace ::testing; | 72 | EXPECT_CALL(*app1, relinquish_focus()).Times(1); |
912 | 73 | 73 | EXPECT_CALL(*app2, receive_focus(_, _)).Times(1); | |
913 | 74 | NiceMock<mtd::MockShellSession> app1, app2; | 74 | } |
914 | 75 | mtd::MockSurface mock_surface1(&app1, std::make_shared<mtd::StubSurfaceBuilder>()); | 75 | |
915 | 76 | mtd::MockSurface mock_surface2(&app2, std::make_shared<mtd::StubSurfaceBuilder>()); | 76 | msh::DefaultFocusMechanism focus_mechanism(std::make_shared<mtd::StubInputTargeter>(), std::make_shared<mtd::StubSurfaceController>()); |
916 | 77 | 77 | ||
917 | 78 | ON_CALL(app1, default_surface()).WillByDefault(Return(mt::fake_shared(mock_surface1))); | 78 | focus_mechanism.set_focus_to(app1); |
918 | 79 | ON_CALL(app2, default_surface()).WillByDefault(Return(mt::fake_shared(mock_surface2))); | 79 | focus_mechanism.set_focus_to(app2); |
843 | 80 | |||
844 | 81 | |||
845 | 82 | { | ||
846 | 83 | InSequence seq; | ||
847 | 84 | EXPECT_CALL(mock_surface1, configure(mir_surface_attrib_focus, mir_surface_focused)).Times(1); | ||
848 | 85 | EXPECT_CALL(mock_surface1, configure(mir_surface_attrib_focus, mir_surface_unfocused)).Times(1); | ||
849 | 86 | EXPECT_CALL(mock_surface2, configure(mir_surface_attrib_focus, mir_surface_focused)).Times(1); | ||
850 | 87 | } | ||
851 | 88 | |||
852 | 89 | msh::DefaultFocusMechanism focus_mechanism(std::make_shared<mtd::StubInputTargeter>(), | ||
853 | 90 | std::make_shared<mtd::StubSurfaceController>()); | ||
854 | 91 | |||
855 | 92 | focus_mechanism.set_focus_to(mt::fake_shared(app1)); | ||
856 | 93 | focus_mechanism.set_focus_to(mt::fake_shared(app2)); | ||
857 | 94 | } | ||
858 | 95 | |||
859 | 96 | TEST(DefaultFocusMechanism, sets_input_focus) | ||
860 | 97 | { | ||
861 | 98 | using namespace ::testing; | ||
862 | 99 | |||
863 | 100 | NiceMock<mtd::MockShellSession> app1; | ||
864 | 101 | mtd::MockSurface mock_surface(&app1, std::make_shared<mtd::StubSurfaceBuilder>()); | ||
865 | 102 | { | ||
866 | 103 | InSequence seq; | ||
867 | 104 | EXPECT_CALL(app1, default_surface()).Times(1) | ||
868 | 105 | .WillOnce(Return(mt::fake_shared(mock_surface))); | ||
869 | 106 | EXPECT_CALL(app1, default_surface()).Times(1) | ||
870 | 107 | .WillOnce(Return(std::shared_ptr<msh::Surface>())); | ||
871 | 108 | } | ||
872 | 109 | |||
873 | 110 | mtd::MockInputTargeter targeter; | ||
874 | 111 | |||
875 | 112 | msh::DefaultFocusMechanism focus_mechanism(mt::fake_shared(targeter), std::make_shared<mtd::StubSurfaceController>()); | ||
876 | 113 | |||
877 | 114 | { | ||
878 | 115 | InSequence seq; | ||
879 | 116 | EXPECT_CALL(mock_surface, take_input_focus(_)).Times(1); | ||
880 | 117 | // When we have no default surface. | ||
881 | 118 | EXPECT_CALL(targeter, focus_cleared()).Times(1); | ||
882 | 119 | // When we have no session. | ||
883 | 120 | EXPECT_CALL(targeter, focus_cleared()).Times(1); | ||
884 | 121 | } | ||
885 | 122 | |||
886 | 123 | focus_mechanism.set_focus_to(mt::fake_shared(app1)); | ||
887 | 124 | focus_mechanism.set_focus_to(mt::fake_shared(app1)); | ||
888 | 125 | focus_mechanism.set_focus_to(std::shared_ptr<msh::Session>()); | ||
919 | 126 | } | 80 | } |
I was able to run the stress test with continuous cursor input for the full ten minute run. There is also good reason to believe this fixes: https:/ /bugs.launchpad .net/mir/ +bug/1220845
The exception in ~SessionMediator can be triggered if session_ manager- >close_ session throws (due to this focus race), causing SessionMediator ::disconnect to fail to reset it's session member-variable pointer. This exception is caught in frontend. However now in ~SessionMediator the pointer has not been reset so it closes the session again throwing an Invalid Session exception. causing the session to be closed again in ~