Mir

Merge lp:~alan-griffiths/mir/nested-server-applies-display-config-policy into lp:mir

Proposed by Alan Griffiths
Status: Merged
Approved by: Alan Griffiths
Approved revision: no longer in the source branch.
Merged at revision: 3056
Proposed branch: lp:~alan-griffiths/mir/nested-server-applies-display-config-policy
Merge into: lp:mir
Diff against target: 225 lines (+119/-17)
4 files modified
include/platform/mir/graphics/display_configuration.h (+3/-0)
src/platform/graphics/display_configuration.cpp (+23/-0)
src/server/graphics/nested/display.cpp (+9/-2)
tests/acceptance-tests/test_nested_mir.cpp (+84/-15)
To merge this branch: bzr merge lp:~alan-griffiths/mir/nested-server-applies-display-config-policy
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Kevin DuBois (community) Approve
Alexandros Frantzis (community) Approve
Andreas Pokorny (community) Approve
Review via email: mp+275542@code.launchpad.net

Commit message

nested: Apply the display config policy during startup

Description of the change

nested: Apply the display config policy during startup

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

Looks good.

Before my final approval, though, I would like for Andreas to review because I remember him mentioning that applying the config at startup had created problems for the greeter in the past (something to do with power modes but I don't remember the details).

review: Needs Information
Revision history for this message
Andreas Pokorny (andreas-pokorny) wrote :

Looks like a good opportunity to use the new shiny std::equa std::equal which takes two ranges in c++14

Revision history for this message
Andreas Pokorny (andreas-pokorny) wrote :

@alf: The sequence of what happens with the separated greeter process was:
 - usc receives the trigger to turn the screen off
 - changes the config to turn the screen off
 - usc/lightm? starts a greeter process to be on top when the display is turned on again
 - (greeter is a nested server with indicators as clients..)
 - greeter submits a display configuration (like in the MP here)
 - usc focuses the greeter session
 - on focus change the sessions display configuration with powermode == on is applied
 - graphics platform turns screen on again..

a cleaner solution would have been to make usc mediate the display change. Currently we dont have a split out nested greeter so the problem will not occur immediately...

So apart from the std::equal comment I am happy with this..

review: Approve
Revision history for this message
Andreas Pokorny (andreas-pokorny) wrote :

oh even better..

Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

Looks good.

review: Approve
Revision history for this message
Kevin DuBois (kdub) wrote :

lgtm too

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

CI glitch?

+ sudo add-apt-repository --yes ppa:ci-train-ppa-service/stable-phone-overlay
Cannot add PPA: 'ppa:~ci-train-ppa-service/ubuntu/stable-phone-overlay'.
The team named '~ci-train-ppa-service' has no PPA named 'ubuntu/stable-phone-overlay'
Please choose from the following available PPAs:
...

Revision history for this message
PS Jenkins bot (ps-jenkins) :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'include/platform/mir/graphics/display_configuration.h'
2--- include/platform/mir/graphics/display_configuration.h 2015-10-05 05:22:49 +0000
3+++ include/platform/mir/graphics/display_configuration.h 2015-10-26 12:54:41 +0000
4@@ -181,6 +181,9 @@
5 DisplayConfiguration& operator=(DisplayConfiguration const& c) = delete;
6 };
7
8+bool operator==(DisplayConfiguration const& lhs, DisplayConfiguration const& rhs);
9+bool operator!=(DisplayConfiguration const& lhs, DisplayConfiguration const& rhs);
10+
11 std::ostream& operator<<(std::ostream& out, DisplayConfiguration const& val);
12
13 }
14
15=== modified file 'src/platform/graphics/display_configuration.cpp'
16--- src/platform/graphics/display_configuration.cpp 2015-10-02 05:14:37 +0000
17+++ src/platform/graphics/display_configuration.cpp 2015-10-26 12:54:41 +0000
18@@ -145,6 +145,7 @@
19
20 out << "\tscale: " << val.scale << std::endl;
21 out << "\tform factor: " << as_string(val.form_factor) << std::endl;
22+ out << "\torientation: " << val.orientation << '\n';
23 out << "}" << std::endl;
24
25 return out;
26@@ -219,6 +220,28 @@
27 return !(val1 == val2);
28 }
29
30+bool mg::operator==(DisplayConfiguration const& lhs, DisplayConfiguration const& rhs)
31+{
32+ std::vector<DisplayConfigurationCard> lhs_cards;
33+ std::vector<DisplayConfigurationOutput> lhs_outputs;
34+
35+ lhs.for_each_card([&lhs_cards](DisplayConfigurationCard const& card) { lhs_cards.emplace_back(card); });
36+ lhs.for_each_output([&lhs_outputs](DisplayConfigurationOutput const& output) { lhs_outputs.emplace_back(output); });
37+
38+ std::vector<DisplayConfigurationCard> rhs_cards;
39+ std::vector<DisplayConfigurationOutput> rhs_outputs;
40+
41+ rhs.for_each_card([&rhs_cards](DisplayConfigurationCard const& card) { rhs_cards.emplace_back(card); });
42+ rhs.for_each_output([&rhs_outputs](DisplayConfigurationOutput const& output) { rhs_outputs.emplace_back(output); });
43+
44+ return lhs_cards == rhs_cards && lhs_outputs == rhs_outputs;
45+}
46+
47+bool mg::operator!=(DisplayConfiguration const& lhs, DisplayConfiguration const& rhs)
48+{
49+ return !(lhs == rhs);
50+}
51+
52 namespace
53 {
54 mir::geometry::Rectangle extents_of(
55
56=== modified file 'src/server/graphics/nested/display.cpp'
57--- src/server/graphics/nested/display.cpp 2015-10-06 09:28:48 +0000
58+++ src/server/graphics/nested/display.cpp 2015-10-26 12:54:41 +0000
59@@ -163,6 +163,10 @@
60 {
61 std::shared_ptr<DisplayConfiguration> conf(configuration());
62 initial_conf_policy->apply_to(*conf);
63+
64+ if (*configuration() != *conf)
65+ apply_to_connection(*conf);
66+
67 create_surfaces(*conf);
68 }
69
70@@ -195,8 +199,11 @@
71
72 void mgn::Display::configure(mg::DisplayConfiguration const& configuration)
73 {
74- create_surfaces(configuration);
75- apply_to_connection(configuration);
76+ if (*this->configuration() != configuration)
77+ {
78+ apply_to_connection(configuration);
79+ create_surfaces(configuration);
80+ }
81 }
82
83 void mgn::Display::create_surfaces(mg::DisplayConfiguration const& configuration)
84
85=== modified file 'tests/acceptance-tests/test_nested_mir.cpp'
86--- tests/acceptance-tests/test_nested_mir.cpp 2015-10-21 10:35:51 +0000
87+++ tests/acceptance-tests/test_nested_mir.cpp 2015-10-26 12:54:41 +0000
88@@ -22,6 +22,7 @@
89 #include "mir/input/cursor_images.h"
90 #include "mir/graphics/display.h"
91 #include "mir/graphics/display_configuration.h"
92+#include "mir/graphics/display_configuration_policy.h"
93 #include "mir/graphics/display_configuration_report.h"
94 #include "mir/input/cursor_listener.h"
95 #include "mir/cached_ptr.h"
96@@ -183,10 +184,35 @@
97 bool hidden{false};
98 };
99
100+struct MockDisplayConfigurationPolicy : mg::DisplayConfigurationPolicy
101+{
102+ MOCK_METHOD1(apply_to, void (mg::DisplayConfiguration&));
103+};
104+
105 class NestedMirRunner : public mtf::HeadlessNestedServerRunner
106 {
107 public:
108 NestedMirRunner(std::string const& connection_string)
109+ : NestedMirRunner(connection_string, true)
110+ {
111+ start_server();
112+ }
113+
114+ virtual ~NestedMirRunner()
115+ {
116+ stop_server();
117+ }
118+
119+ std::shared_ptr<MockHostLifecycleEventListener> the_mock_host_lifecycle_event_listener()
120+ {
121+ return mock_host_lifecycle_event_listener([]
122+ { return std::make_shared<NiceMock<MockHostLifecycleEventListener>>(); });
123+ }
124+
125+ std::shared_ptr<CursorWrapper> cursor_wrapper;
126+
127+protected:
128+ NestedMirRunner(std::string const& connection_string, bool)
129 : mtf::HeadlessNestedServerRunner(connection_string)
130 {
131 server.override_the_host_lifecycle_event_listener([this]
132@@ -197,24 +223,21 @@
133
134 server.override_the_cursor_images([] { return std::make_shared<CursorImages>(); });
135
136- start_server();
137- }
138-
139- ~NestedMirRunner()
140- {
141- stop_server();
142- }
143-
144- std::shared_ptr<MockHostLifecycleEventListener> the_mock_host_lifecycle_event_listener()
145- {
146- return mock_host_lifecycle_event_listener([]
147- { return std::make_shared<NiceMock<MockHostLifecycleEventListener>>(); });
148- }
149-
150- std::shared_ptr<CursorWrapper> cursor_wrapper;
151+ server.wrap_display_configuration_policy([this]
152+ (std::shared_ptr<mg::DisplayConfigurationPolicy> const&)
153+ { return mock_display_configuration_policy([this]
154+ { return build_mock_display_configuration_policy(); }); });
155+ }
156
157 private:
158 mir::CachedPtr<MockHostLifecycleEventListener> mock_host_lifecycle_event_listener;
159+
160+ virtual std::shared_ptr<MockDisplayConfigurationPolicy> build_mock_display_configuration_policy()
161+ {
162+ return std::make_shared<NiceMock<MockDisplayConfigurationPolicy>>();
163+ }
164+
165+ mir::CachedPtr<MockDisplayConfigurationPolicy> mock_display_configuration_policy;
166 };
167
168 struct NestedServer : mtf::HeadlessInProcessServer
169@@ -376,6 +399,7 @@
170 // No post on surface creation
171 EXPECT_CALL(*mock_session_mediator_report, session_submit_buffer_called(_)).Times(0);
172 NestedMirRunner nested_mir{new_connection()};
173+
174 auto const connection = mir_connect_sync(nested_mir.new_connection().c_str(), __PRETTY_FUNCTION__);
175 auto const surface = mtf::make_any_surface(connection);
176
177@@ -618,3 +642,48 @@
178 // surface as the host cursor then reverts to default.
179 Mock::VerifyAndClearExpectations(mock_cursor.get());
180 }
181+
182+TEST_F(NestedServer, applies_display_config_on_startup)
183+{
184+ mt::WaitCondition condition;
185+
186+ auto const expected_config = server.the_display()->configuration();
187+ expected_config->for_each_output([](mg::UserDisplayConfigurationOutput& output)
188+ { output.orientation = mir_orientation_inverted;});
189+
190+ EXPECT_CALL(*the_mock_display_configuration_report(), new_configuration(mt::DisplayConfigMatches(std::ref(*expected_config))))
191+ .WillRepeatedly(InvokeWithoutArgs([&] { condition.wake_up_everyone(); }));
192+
193+ struct MyNestedMirRunner : NestedMirRunner
194+ {
195+ MyNestedMirRunner(std::string const& connection_string) :
196+ NestedMirRunner(connection_string, true)
197+ {
198+ start_server();
199+ }
200+
201+ std::shared_ptr<MockDisplayConfigurationPolicy> build_mock_display_configuration_policy() override
202+ {
203+ auto result = std::make_unique<MockDisplayConfigurationPolicy>();
204+ EXPECT_CALL(*result, apply_to(_)).Times(AnyNumber())
205+ .WillOnce(Invoke([](mg::DisplayConfiguration& config)
206+ {
207+ config.for_each_output([](mg::UserDisplayConfigurationOutput& output)
208+ { output.orientation = mir_orientation_inverted; });
209+ }));
210+
211+ return std::shared_ptr<MockDisplayConfigurationPolicy>(std::move(result));
212+ }
213+ } nested_mir{new_connection()};
214+
215+ auto const connection = mir_connect_sync(nested_mir.new_connection().c_str(), __PRETTY_FUNCTION__);
216+ auto const surface = make_and_paint_surface(connection);
217+
218+ condition.wait_for_at_most_seconds(1);
219+ Mock::VerifyAndClearExpectations(the_mock_display_configuration_report().get());
220+
221+ EXPECT_TRUE(condition.woken());
222+
223+ mir_surface_release_sync(surface);
224+ mir_connection_release(connection);
225+}

Subscribers

People subscribed via source and target branches