Mir

Merge lp:~andreas-pokorny/mir/load-all-supported-input-platforms into lp:mir

Proposed by Andreas Pokorny
Status: Superseded
Proposed branch: lp:~andreas-pokorny/mir/load-all-supported-input-platforms
Merge into: lp:mir
Prerequisite: lp:~andreas-pokorny/mir/extend-x11-input-platform-probe
Diff against target: 734 lines (+370/-68)
19 files modified
include/platform/mir/input/platform.h (+2/-2)
include/test/mir_test_framework/executable_path.h (+1/-0)
src/include/server/mir/default_server_configuration.h (+3/-3)
src/include/server/mir/input/input_probe.h (+48/-0)
src/platform/graphics/platform_probe.cpp (+5/-1)
src/platforms/evdev/platform_factory.cpp (+1/-1)
src/platforms/mesa/server/x11/input/input.cpp (+1/-1)
src/server/input/CMakeLists.txt (+1/-0)
src/server/input/default_configuration.cpp (+16/-39)
src/server/input/input_probe.cpp (+104/-0)
src/server/symbols.map (+3/-3)
tests/mir_test_framework/CMakeLists.txt (+1/-0)
tests/mir_test_framework/executable_path.cpp (+10/-0)
tests/mir_test_framework/fake_input_device_impl.cpp (+1/-1)
tests/mir_test_framework/stub_input.cpp (+2/-2)
tests/mir_test_framework/stub_input_platform.cpp (+1/-1)
tests/umock-acceptance-tests/test_libinput.cpp (+8/-14)
tests/unit-tests/input/CMakeLists.txt (+1/-0)
tests/unit-tests/input/test_input_platform_probing.cpp (+161/-0)
To merge this branch: bzr merge lp:~andreas-pokorny/mir/load-all-supported-input-platforms
Reviewer Review Type Date Requested Status
Daniel van Vugt Needs Fixing
PS Jenkins bot (community) continuous-integration Approve
Alan Griffiths Approve
Chris Halse Rogers Approve
Review via email: mp+273452@code.launchpad.net

This proposal has been superseded by a proposal from 2015-10-14.

Commit message

Add automatic searching and probing for input platforms

With this specifying the input platform via --platform-input-lib is no longer necessary, unless the stub input platform that supports attaching fake devices is required

Description of the change

The most notable change of this MP will make the libinput and x11 platform work without additional command line parameter.

This MP adds probing for input platforms. mirserver will now search inside the default platform-path for loadable modules that fulfil the input platform ABI. Then only those modules that claim to be better than 'dummy' will be used. Hence input-stub.so will not be loaded by default, but requires loading through the platform-input-lib parameter.

Next step: remove input reader and event hub..

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: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Chris Halse Rogers (raof) wrote :

+ mir::log_info("Found input driver: %s", desc->name);

Could you also log driver version please?

+ return std::move(platforms);

Pessimisation: this breaks return value optimisation. When the Wily clang builds work again this will be an error.

+ EXPECT_THAT(platforms.size(), Eq(2)); // we cannot disable the default evdev platform with only umock dev is in place
+ EXPECT_THAT(platforms[0].get(), AnyOf(OfType<mi::evdev::Platform>(), OfType<mi::X::XInputPlatform>()));
+ EXPECT_THAT(platforms[1].get(), AnyOf(OfType<mi::evdev::Platform>(), OfType<mi::X::XInputPlatform>()));

Seems like you could replace OfType with OfPointerType and then use

EXPECT_THAT(platforms, UnorderedElementsAre(OfPointerType<mi::evdev::Platform>(), OfPointerType<mi::X::XInputPlatform>());

Which I think is both more natural and also is a slightly stronger test.

========================
Non-review comment:
+ mtf::UdevEnvironment env; // TODO replace with mock_libevdev und mock_libudev when the new input reading stack is the only in use.

Heads up: I think that doing this will provide negative value. Also, und→and :)

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

Fixed all of the above.

> ========================
> Non-review comment:
> + mtf::UdevEnvironment env; // TODO replace with mock_libevdev und
> mock_libudev when the new input reading stack is the only in use.
>
> Heads up: I think that doing this will provide negative value. Also, und→and
> :)

I want to simulate the cases no devices found, devices found and some or all can be opened, devices found and none can be opened. I cannot do that with umockdev...

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Chris Halse Rogers (raof) wrote :

On Thu, Oct 8, 2015 at 5:56 PM, Andreas Pokorny
<email address hidden> wrote:
> Fixed all of the above.
>
>> ========================
>> Non-review comment:
>> + mtf::UdevEnvironment env; // TODO replace with mock_libevdev
>> und
>> mock_libudev when the new input reading stack is the only in use.
>>
>> Heads up: I think that doing this will provide negative value.
>> Also, und→and
>> :)
>
> I want to simulate the cases no devices found, devices found and some
> or all can be opened, devices found and none can be opened. I cannot
> do that with umockdev...

You can do all except the last, and the last would be a simple patch to
umockdev.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Chris Halse Rogers (raof) wrote :

LGTM

review: Approve
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

Looks like infrastructure glitch:

  inflating: package_archive/archive/work/output/libmirclient-debug-extension1_0.17.0bzr2998pkg0wily4303+autopilot0_armhf.deb
error: closed
[timestamp] Start PPAs and local Archive : 2015-10-08T10:09:40+0000
rm: cannot remove 'ppa_sources': No such file or directory

~~~~

(Non blocking) looks like we need to bump the server ABI

Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

"The most notable change of this MP will make the libinput and x11 platform work without additional command line parameter."

Am I expecting too much?

$ sudo DISPLAY= bin/mir_demo_server --vt 1 --arw-file&
$ bin/mir_demo_server --file mir-socket --host-socket /tmp/mir_socket
[Switch to vt 1]
[Switch to vt 7]

ERROR: /home/alan/display_server/mir/src/platforms/mesa/server/common/display_helpers.cpp(256): Throw in function int mir::graphics::mesa::helpers::DRMHelper::open_drm_device(const std::shared_ptr<mir::udev::Context>&)
Dynamic exception type: boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<std::runtime_error> >
std::exception::what: Error opening DRM device
13, "Permission denied"

It looks as though the nested server is selecting the wrong drivers. (It should "agree" with the host.)

NB I can workaround like this:

$ DISPLAY= bin/mir_demo_server --file mir-socket --host-socket /tmp/mir_socket --launch bin/mir_demo_client_animated_cursor

review: Needs Information
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

OK, I don't think the auto-configuration is quite there yet. But this is a step forwards.

I guess there will be an ABI break needed for 0.18.

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

Oh .. I wasnt aware there is a mismatch between the x11 graphics and input probing.
Soooo.. a host-socket setting should win over a DISPLAY env, shouidnt it?

That should be a simple fix in graphics.cpp.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Andreas Pokorny (andreas-pokorny) wrote :

> Oh .. I wasnt aware there is a mismatch between the x11 graphics and input
> probing.
> Soooo.. a host-socket setting should win over a DISPLAY env, shouidnt it?
>
> That should be a simple fix in graphics.cpp.

Nested.. not as simple as I thought..

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Landed and then reverted:
* Modifiers don't work any more (can't move/resize windows using Alt)
* Default mouse speed too high
* A little too many log messages come from this.

Only the first issue is a blocker.

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

> Landed and then reverted:
> * Modifiers don't work any more (can't move/resize windows using Alt)

Yes modifiers are per device right now .. which isnt what we want within the dispatcher. Working on a proper abstraction/fix for that.

> * Default mouse speed too high

Yay! So mouse acceleration is working. Configuration branches are on the way..

> * A little too many log messages come from this.
>
> Only the first issue is a blocker.

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

> Landed and then reverted:
> * Modifiers don't work any more (can't move/resize windows using Alt)
> * Default mouse speed too high
> * A little too many log messages come from this.
>
> Only the first issue is a blocker.

This should fix the issue..
https://code.launchpad.net/~andreas-pokorny/mir/combine-modifier-state-accross-devices/+merge/274372

2999. By Andreas Pokorny on 2015-10-14

merge lp:mir

3000. By Andreas Pokorny on 2015-10-14

re apply merge

3001. By Andreas Pokorny on 2015-10-22

review findings addressed

3002. By Andreas Pokorny on 2015-10-26

merge mir

3003. By Andreas Pokorny on 2015-10-26

confuse ci a bit more..

3004. By Andreas Pokorny on 2015-10-27

bump here

3005. By Andreas Pokorny on 2015-10-27

merging current mir and fix test exclusions..

We should get rid of the concept of a test platform

3006. By Andreas Pokorny on 2015-10-29

test

3007. By Andreas Pokorny on 2015-11-04

merge lp:mir

3008. By Andreas Pokorny on 2015-11-06

merge lp:mir

3009. By Andreas Pokorny on 2015-11-09

revert the test..

3010. By Andreas Pokorny on 2015-11-16

merge lp:mir

3011. By Andreas Pokorny on 2015-11-17

avoid a few more ifdefs

3012. By Andreas Pokorny on 2015-11-20

merge lp:mir

3013. By Andreas Pokorny on 2015-11-20

fix merge errors

3014. By Andreas Pokorny on 2015-11-20

revert sorting

3015. By Andreas Pokorny on 2015-11-20

revert cmake change - no longer needed

3016. By Andreas Pokorny on 2015-11-20

fix android builds

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'include/platform/mir/input/platform.h'
2--- include/platform/mir/input/platform.h 2015-10-12 08:08:58 +0000
3+++ include/platform/mir/input/platform.h 2015-10-14 15:31:05 +0000
4@@ -91,7 +91,7 @@
5 };
6
7 typedef mir::UniqueModulePtr<Platform>(*CreatePlatform)(
8- std::shared_ptr<options::Option> const& options,
9+ options::Option const& options,
10 std::shared_ptr<EmergencyCleanupRegistry> const& emergency_cleanup_registry,
11 std::shared_ptr<InputDeviceRegistry> const& input_device_registry,
12 std::shared_ptr<InputReport> const& report);
13@@ -123,7 +123,7 @@
14 * \ingroup platform_enablement
15 */
16 mir::UniqueModulePtr<mir::input::Platform> create_input_platform(
17- std::shared_ptr<mir::options::Option> const& options,
18+ mir::options::Option const& options,
19 std::shared_ptr<mir::EmergencyCleanupRegistry> const& emergency_cleanup_registry,
20 std::shared_ptr<mir::input::InputDeviceRegistry> const& input_device_registry,
21 std::shared_ptr<mir::input::InputReport> const& report);
22
23=== modified file 'include/test/mir_test_framework/executable_path.h'
24--- include/test/mir_test_framework/executable_path.h 2015-10-12 08:08:58 +0000
25+++ include/test/mir_test_framework/executable_path.h 2015-10-14 15:31:05 +0000
26@@ -26,6 +26,7 @@
27 std::string executable_path();
28
29 std::string library_path();
30+std::string server_platform_path();
31 std::string udev_recordings_path();
32 std::string server_platform(std::string const& name);
33 std::string server_input_platform(std::string const& name);
34
35=== modified file 'src/include/server/mir/default_server_configuration.h'
36--- src/include/server/mir/default_server_configuration.h 2015-10-12 08:08:58 +0000
37+++ src/include/server/mir/default_server_configuration.h 2015-10-14 15:31:05 +0000
38@@ -21,9 +21,11 @@
39 #include "mir/cached_ptr.h"
40 #include "mir/server_configuration.h"
41 #include "mir/shell/window_manager_builder.h"
42+#include "mir/module_deleter.h"
43
44 #include <memory>
45 #include <string>
46+#include <vector>
47
48 namespace android
49 {
50@@ -331,7 +333,6 @@
51 virtual std::shared_ptr<droidinput::InputListenerInterface> the_input_translator();
52
53 // new input reading related parts:
54- virtual std::shared_ptr<input::Platform> the_input_platform();
55 virtual std::shared_ptr<dispatch::MultiplexingDispatchable> the_input_reading_multiplexer();
56 virtual std::shared_ptr<input::InputDeviceRegistry> the_input_device_registry();
57 virtual std::shared_ptr<input::InputDeviceHub> the_input_device_hub();
58@@ -384,8 +385,7 @@
59 CachedPtr<input::CompositeEventFilter> composite_event_filter;
60 CachedPtr<input::InputManager> input_manager;
61 CachedPtr<input::SurfaceInputDispatcher> surface_input_dispatcher;
62- CachedPtr<input::DefaultInputDeviceHub> default_input_device_hub; // currently not used by default
63- CachedPtr<input::Platform> input_platform; // currently not used by default
64+ CachedPtr<input::DefaultInputDeviceHub> default_input_device_hub;
65 CachedPtr<dispatch::MultiplexingDispatchable> input_reading_multiplexer;
66 CachedPtr<input::InputDispatcher> input_dispatcher;
67 CachedPtr<input::InputSender> input_sender;
68
69=== added file 'src/include/server/mir/input/input_probe.h'
70--- src/include/server/mir/input/input_probe.h 1970-01-01 00:00:00 +0000
71+++ src/include/server/mir/input/input_probe.h 2015-10-14 15:31:05 +0000
72@@ -0,0 +1,48 @@
73+/*
74+ * Copyright © 2015 Canonical Ltd.
75+ *
76+ * This program is free software: you can redistribute it and/or modify it
77+ * under the terms of the GNU General Public License version 3,
78+ * as published by the Free Software Foundation.
79+ *
80+ * This program is distributed in the hope that it will be useful,
81+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
82+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
83+ * GNU General Public License for more details.
84+ *
85+ * You should have received a copy of the GNU General Public License
86+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
87+ *
88+ * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com>
89+ */
90+
91+#ifndef MIR_INPUT_PROBE_H_
92+#define MIR_INPUT_PROBE_H_
93+
94+#include <vector>
95+#include "mir/module_deleter.h"
96+
97+namespace mir
98+{
99+namespace options
100+{
101+class Option;
102+}
103+class EmergencyCleanupRegistry;
104+class SharedLibraryProberReport;
105+
106+namespace input
107+{
108+class InputReport;
109+class Platform;
110+class InputDeviceRegistry;
111+
112+std::vector<mir::UniqueModulePtr<Platform>> probe_input_platforms(
113+ options::Option const& options, std::shared_ptr<EmergencyCleanupRegistry> const& emergency_cleanup,
114+ std::shared_ptr<InputDeviceRegistry> const& device_registry, std::shared_ptr<InputReport> const& input_report,
115+ SharedLibraryProberReport & prober_report);
116+
117+}
118+}
119+
120+#endif
121
122=== modified file 'src/platform/graphics/platform_probe.cpp'
123--- src/platform/graphics/platform_probe.cpp 2015-10-12 08:08:58 +0000
124+++ src/platform/graphics/platform_probe.cpp 2015-10-14 15:31:05 +0000
125@@ -46,7 +46,11 @@
126 "describe_graphics_module",
127 MIR_SERVER_GRAPHICS_PLATFORM_VERSION);
128 auto desc = describe();
129- mir::log_info("Found graphics driver: %s", desc->name);
130+ mir::log_info("Found graphics driver: %s, (version: %d.%d.%d)",
131+ desc->name,
132+ desc->major_version,
133+ desc->minor_version,
134+ desc->micro_version);
135 }
136 catch (std::runtime_error const&)
137 {
138
139=== modified file 'src/platforms/evdev/platform_factory.cpp'
140--- src/platforms/evdev/platform_factory.cpp 2015-10-12 08:08:58 +0000
141+++ src/platforms/evdev/platform_factory.cpp 2015-10-14 15:31:05 +0000
142@@ -67,7 +67,7 @@
143 }
144
145 mir::UniqueModulePtr<mi::Platform> create_input_platform(
146- std::shared_ptr<mo::Option> const& /*options*/,
147+ mo::Option const& /*options*/,
148 std::shared_ptr<mir::EmergencyCleanupRegistry> const& /*emergency_cleanup_registry*/,
149 std::shared_ptr<mi::InputDeviceRegistry> const& input_device_registry,
150 std::shared_ptr<mi::InputReport> const& report)
151
152=== modified file 'src/platforms/mesa/server/x11/input/input.cpp'
153--- src/platforms/mesa/server/x11/input/input.cpp 2015-10-12 08:08:58 +0000
154+++ src/platforms/mesa/server/x11/input/input.cpp 2015-10-14 15:31:05 +0000
155@@ -28,7 +28,7 @@
156 extern mx::X11Resources x11_resources;
157
158 mir::UniqueModulePtr<mi::Platform> create_input_platform(
159- std::shared_ptr<mo::Option> const& /*options*/,
160+ mo::Option const& /*options*/,
161 std::shared_ptr<mir::EmergencyCleanupRegistry> const& /*emergency_cleanup_registry*/,
162 std::shared_ptr<mi::InputDeviceRegistry> const& input_device_registry,
163 std::shared_ptr<mi::InputReport> const& /*report*/)
164
165=== modified file 'src/server/input/CMakeLists.txt'
166--- src/server/input/CMakeLists.txt 2015-10-12 19:30:14 +0000
167+++ src/server/input/CMakeLists.txt 2015-10-14 15:31:05 +0000
168@@ -22,6 +22,7 @@
169 touchspot_controller.cpp
170 key_repeat_dispatcher.cpp
171 validator.cpp
172+ input_probe.cpp
173 )
174
175 add_subdirectory(android)
176
177=== modified file 'src/server/input/default_configuration.cpp'
178--- src/server/input/default_configuration.cpp 2015-10-13 17:42:07 +0000
179+++ src/server/input/default_configuration.cpp 2015-10-14 15:31:05 +0000
180@@ -39,16 +39,16 @@
181 #include "surface_input_dispatcher.h"
182
183 #include "mir/input/touch_visualizer.h"
184+#include "mir/input/input_probe.h"
185 #include "mir/input/platform.h"
186 #include "mir/options/configuration.h"
187 #include "mir/options/option.h"
188 #include "mir/dispatch/multiplexing_dispatchable.h"
189 #include "mir/compositor/scene.h"
190 #include "mir/emergency_cleanup.h"
191-#include "mir/report/legacy_input_report.h"
192 #include "mir/main_loop.h"
193-#include "mir/shared_library.h"
194 #include "mir/glib_main_loop.h"
195+#include "mir/log.h"
196 #include "mir/dispatch/action_queue.h"
197
198 #include "mir_toolkit/cursors.h"
199@@ -290,26 +290,6 @@
200 });
201 }
202
203-std::shared_ptr<mi::Platform>
204-mir::DefaultServerConfiguration::the_input_platform()
205-{
206- return input_platform(
207- [this]() -> std::shared_ptr<mi::Platform>
208- {
209- auto options = the_options();
210-
211- if (!options->is_set(options::platform_input_lib))
212- return nullptr;
213-
214- auto lib = std::make_shared<mir::SharedLibrary>(
215- options->get<std::string>(options::platform_input_lib));
216- auto create = lib->load_function<mi::CreatePlatform>(
217- "create_input_platform",
218- MIR_SERVER_INPUT_PLATFORM_VERSION);
219- return create(the_options(), the_emergency_cleanup(), the_input_device_registry(), the_input_report());
220- });
221-}
222-
223 namespace
224 {
225 class NullLegacyInputDispatchable : public mi::LegacyInputDispatchable
226@@ -341,23 +321,20 @@
227 }
228 else
229 {
230- if (options->get<std::string>(options::legacy_input_report_opt) == options::log_opt_value)
231- mr::legacy_input::initialize(the_logger());
232-
233- if (auto platform = the_input_platform())
234- {
235- auto const ret = std::make_shared<mi::DefaultInputManager>(
236- the_input_reading_multiplexer(),
237- std::make_shared<NullLegacyInputDispatchable>());
238-
239- ret->add_platform(platform);
240- return ret;
241- }
242- else
243- {
244- return std::make_shared<mi::DefaultInputManager>(
245- the_input_reading_multiplexer(), the_legacy_input_dispatchable());
246- }
247+ auto platforms = probe_input_platforms(*options, the_emergency_cleanup(), the_input_device_registry(),
248+ the_input_report(), *the_shared_library_prober_report());
249+
250+ if (platforms.empty())
251+ BOOST_THROW_EXCEPTION(std::runtime_error("No input platforms found"));
252+
253+ auto const ret = std::make_shared<mi::DefaultInputManager>(
254+ the_input_reading_multiplexer(),
255+ std::make_shared<NullLegacyInputDispatchable>());
256+
257+ for (auto & platform : platforms)
258+ ret->add_platform(std::move(platform));
259+
260+ return ret;
261 }
262 }
263 );
264
265=== added file 'src/server/input/input_probe.cpp'
266--- src/server/input/input_probe.cpp 1970-01-01 00:00:00 +0000
267+++ src/server/input/input_probe.cpp 2015-10-14 15:31:05 +0000
268@@ -0,0 +1,104 @@
269+/*
270+ * Copyright © 2015 Canonical Ltd.
271+ *
272+ * This program is free software: you can redistribute it and/or modify it
273+ * under the terms of the GNU General Public License version 3,
274+ * as published by the Free Software Foundation.
275+ *
276+ * This program is distributed in the hope that it will be useful,
277+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
278+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
279+ * GNU General Public License for more details.
280+ *
281+ * You should have received a copy of the GNU General Public License
282+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
283+ *
284+ * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com>
285+ */
286+
287+#include "mir/input/input_probe.h"
288+#include "mir/input/platform.h"
289+
290+#include "mir/options/configuration.h"
291+#include "mir/options/option.h"
292+
293+#include "mir/shared_library_prober.h"
294+#include "mir/shared_library.h"
295+#include "mir/log.h"
296+#include "mir/module_deleter.h"
297+
298+#include <stdexcept>
299+
300+namespace mi = mir::input;
301+namespace mo = mir::options;
302+
303+namespace
304+{
305+auto probe_input_platform(mir::SharedLibrary const& lib, mir::options::Option const& options)
306+{
307+ auto probe = lib.load_function<mi::ProbePlatform>("probe_input_platform", MIR_SERVER_INPUT_PLATFORM_VERSION);
308+
309+ return probe(options);
310+}
311+
312+void describe_input_platform(mir::SharedLibrary const& lib)
313+{
314+ auto describe =
315+ lib.load_function<mi::DescribeModule>("describe_input_module", MIR_SERVER_INPUT_PLATFORM_VERSION);
316+ auto desc = describe();
317+ mir::log_info("Selected input driver: %s (version: %d.%d.%d)", desc->name, desc->major_version, desc->minor_version,
318+ desc->micro_version);
319+}
320+
321+mir::UniqueModulePtr<mi::Platform> create_input_platform(
322+ mir::SharedLibrary const& lib, mir::options::Option const& options,
323+ std::shared_ptr<mir::EmergencyCleanupRegistry> const& cleanup_registry,
324+ std::shared_ptr<mi::InputDeviceRegistry> const& registry, std::shared_ptr<mi::InputReport> const& report)
325+{
326+
327+ auto create = lib.load_function<mi::CreatePlatform>("create_input_platform", MIR_SERVER_INPUT_PLATFORM_VERSION);
328+
329+ return create(options, cleanup_registry, registry, report);
330+}
331+}
332+
333+std::vector<mir::UniqueModulePtr<mi::Platform>> mi::probe_input_platforms(
334+ mo::Option const& options, std::shared_ptr<EmergencyCleanupRegistry> const& emergency_cleanup,
335+ std::shared_ptr<mi::InputDeviceRegistry> const& device_registry, std::shared_ptr<mi::InputReport> const& input_report,
336+ mir::SharedLibraryProberReport& prober_report)
337+{
338+ std::vector<UniqueModulePtr<Platform>> platforms;
339+
340+ if (options.is_set(mo::platform_input_lib))
341+ {
342+ mir::SharedLibrary lib(options.get<std::string>(mo::platform_input_lib));
343+
344+ platforms.emplace_back(create_input_platform(lib, options, emergency_cleanup, device_registry, input_report));
345+
346+ describe_input_platform(lib);
347+ }
348+ else
349+ {
350+ auto const& path = options.get<std::string>(mo::platform_path);
351+ auto platforms_libs = mir::libraries_for_path(path, prober_report);
352+
353+ for (auto const& platform_lib : platforms_libs)
354+ {
355+ try
356+ {
357+ if (probe_input_platform(*platform_lib, options) > mi::PlatformPriority::dummy)
358+ {
359+ platforms.emplace_back(
360+ create_input_platform(*platform_lib, options, emergency_cleanup, device_registry, input_report));
361+
362+ describe_input_platform(*platform_lib);
363+ }
364+ }
365+ catch (std::runtime_error const&)
366+ {
367+ }
368+ }
369+ }
370+
371+ return platforms;
372+}
373
374=== modified file 'src/server/symbols.map'
375--- src/server/symbols.map 2015-10-12 08:08:58 +0000
376+++ src/server/symbols.map 2015-10-14 15:31:05 +0000
377@@ -57,12 +57,13 @@
378 mir::input::InputDispatcher::?InputDispatcher*;
379 mir::input::InputManager::InputManager*;
380 mir::input::InputManager::operator*;
381- mir::input::Surface::operator*;
382 mir::input::Surface::?Surface*;
383 mir::input::Surface::Surface*;
384- mir::input::TouchVisualizer::operator*;
385+ mir::input::Surface::operator*;
386 mir::input::TouchVisualizer::?TouchVisualizer*;
387 mir::input::TouchVisualizer::TouchVisualizer*;
388+ mir::input::TouchVisualizer::operator*;
389+ mir::input::probe_input_platforms*;
390 mir::LockableCallback::?LockableCallback*;
391 mir::LockableCallback::LockableCallback*;
392 mir::LockableCallback::operator*;
393@@ -633,7 +634,6 @@
394 mir::DefaultServerConfiguration::the_input_dispatcher*;
395 mir::DefaultServerConfiguration::the_new_input_dispatcher*;
396 mir::DefaultServerConfiguration::the_input_manager*;
397- mir::DefaultServerConfiguration::the_input_platform*;
398 mir::DefaultServerConfiguration::the_input_reader*;
399 mir::DefaultServerConfiguration::the_input_reader_policy*;
400 mir::DefaultServerConfiguration::the_input_reading_multiplexer*;
401
402=== renamed file 'tests/mir_test_framework/stub_input_platform.h' => 'tests/include/mir_test_framework/stub_input_platform.h'
403=== modified file 'tests/mir_test_framework/CMakeLists.txt'
404--- tests/mir_test_framework/CMakeLists.txt 2015-10-12 08:08:58 +0000
405+++ tests/mir_test_framework/CMakeLists.txt 2015-10-14 15:31:05 +0000
406@@ -38,6 +38,7 @@
407 process.cpp
408 server_runner.cpp
409 socket_detect_server.cpp
410+ stub_input_platform.cpp
411 stub_client_platform_factory.cpp
412 stub_server_platform_factory.cpp
413 stubbed_server_configuration.cpp
414
415=== modified file 'tests/mir_test_framework/executable_path.cpp'
416--- tests/mir_test_framework/executable_path.cpp 2015-10-12 08:08:58 +0000
417+++ tests/mir_test_framework/executable_path.cpp 2015-10-14 15:31:05 +0000
418@@ -45,6 +45,16 @@
419 return executable_path() + "/../lib";
420 }
421
422+std::string mir_test_framework::server_platform_path()
423+{
424+ for (auto const& option : {library_path() + "/server-modules/",
425+ library_path() + "/server-platform/",
426+ std::string(MIR_SERVER_PLATFORM_PATH) + '/'})
427+ if (boost::filesystem::exists(option))
428+ return option;
429+ BOOST_THROW_EXCEPTION(std::runtime_error("Failed to find server platform in standard search locations"));
430+}
431+
432 std::string mir_test_framework::udev_recordings_path()
433 {
434 std::string run_path = executable_path() + "/udev_recordings";
435
436=== modified file 'tests/mir_test_framework/fake_input_device_impl.cpp'
437--- tests/mir_test_framework/fake_input_device_impl.cpp 2015-10-12 08:08:58 +0000
438+++ tests/mir_test_framework/fake_input_device_impl.cpp 2015-10-14 15:31:05 +0000
439@@ -17,7 +17,7 @@
440 */
441
442 #include "fake_input_device_impl.h"
443-#include "stub_input_platform.h"
444+#include "mir_test_framework/stub_input_platform.h"
445
446 #include "mir/input/input_device.h"
447 #include "mir/input/input_device_info.h"
448
449=== modified file 'tests/mir_test_framework/stub_input.cpp'
450--- tests/mir_test_framework/stub_input.cpp 2015-10-12 08:08:58 +0000
451+++ tests/mir_test_framework/stub_input.cpp 2015-10-14 15:31:05 +0000
452@@ -16,7 +16,7 @@
453 * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com>
454 */
455
456-#include "stub_input_platform.h"
457+#include "mir_test_framework/stub_input_platform.h"
458 #include "fake_input_device_impl.h"
459 #include "mir/module_properties.h"
460
461@@ -25,7 +25,7 @@
462 namespace mi = mir::input;
463
464 mir::UniqueModulePtr<mi::Platform> create_input_platform(
465- std::shared_ptr<mo::Option> const& /*options*/,
466+ mo::Option const& /*options*/,
467 std::shared_ptr<mir::EmergencyCleanupRegistry> const& /*emergency_cleanup_registry*/,
468 std::shared_ptr<mi::InputDeviceRegistry> const& input_device_registry,
469 std::shared_ptr<mi::InputReport> const& /*report*/)
470
471=== modified file 'tests/mir_test_framework/stub_input_platform.cpp'
472--- tests/mir_test_framework/stub_input_platform.cpp 2015-10-12 08:08:58 +0000
473+++ tests/mir_test_framework/stub_input_platform.cpp 2015-10-14 15:31:05 +0000
474@@ -16,7 +16,7 @@
475 * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com>
476 */
477
478-#include "stub_input_platform.h"
479+#include "mir_test_framework/stub_input_platform.h"
480
481 #include "mir/input/input_device_registry.h"
482 #include "mir/dispatch/action_queue.h"
483
484=== modified file 'tests/umock-acceptance-tests/test_libinput.cpp'
485--- tests/umock-acceptance-tests/test_libinput.cpp 2015-10-12 08:08:58 +0000
486+++ tests/umock-acceptance-tests/test_libinput.cpp 2015-10-14 15:31:05 +0000
487@@ -17,8 +17,8 @@
488 */
489
490 #include "mir/input/platform.h"
491+#include "mir/test/doubles/mock_option.h"
492 #include "mir/shared_library.h"
493-#include "mir/options/option.h"
494
495 #include "mir_test_framework/udev_environment.h"
496 #include "mir_test_framework/executable_path.h"
497@@ -27,20 +27,13 @@
498 #include <gtest/gtest.h>
499
500 namespace mtf = mir_test_framework;
501+namespace mtd = mir::test::doubles;
502 namespace mo = mir::options;
503+
504 using namespace ::testing;
505 namespace
506 {
507
508-struct MockOption : mo::Option
509-{
510- MOCK_CONST_METHOD1(is_set, bool(char const*));
511- MOCK_CONST_METHOD2(get, bool(char const*, bool));
512- MOCK_CONST_METHOD2(get, int(char const*, int));
513- MOCK_CONST_METHOD2(get, std::string(char const* name, char const*));
514- MOCK_CONST_METHOD1(get, boost::any const&(char const*));
515-};
516-
517 auto get_libinput_platform()
518 {
519 auto path = mtf::server_input_platform("input-evdev");
520@@ -54,7 +47,7 @@
521
522 TEST(LibInput, DISABLED_probes_as_unsupported_without_device_access)
523 {
524- NiceMock<MockOption> options;
525+ NiceMock<mtd::MockOption> options;
526
527 // dumb assumption - nobody runs this test cases as root..
528 // or allows accessing evdev input devices from non privileged users.
529@@ -67,7 +60,7 @@
530 {
531 mtf::UdevEnvironment env;
532 env.add_standard_device("laptop-keyboard");
533- NiceMock<MockOption> options;
534+ NiceMock<mtd::MockOption> options;
535
536 auto library = get_libinput_platform();
537 auto probe_fun = library->load_function<mir::input::ProbePlatform>(probe_input_platform_symbol);
538@@ -78,7 +71,8 @@
539 {
540 mtf::UdevEnvironment env;
541 env.add_standard_device("laptop-keyboard");
542- NiceMock<MockOption> options;
543+ NiceMock<mtd::MockOption> options;
544+
545 ON_CALL(options,is_set(StrEq(host_socket_opt)))
546 .WillByDefault(Return(true));
547 ON_CALL(options,get(StrEq(host_socket_opt), Matcher<char const*>(_)))
548@@ -92,7 +86,7 @@
549 TEST(LibInput, probes_as_supported_when_umock_dev_available_or_before_input_devices_are_available)
550 {
551 mtf::UdevEnvironment env;
552- NiceMock<MockOption> options;
553+ NiceMock<mtd::MockOption> options;
554
555 auto library = get_libinput_platform();
556 auto probe_fun = library->load_function<mir::input::ProbePlatform>(probe_input_platform_symbol);
557
558=== modified file 'tests/unit-tests/input/CMakeLists.txt'
559--- tests/unit-tests/input/CMakeLists.txt 2015-10-12 20:51:03 +0000
560+++ tests/unit-tests/input/CMakeLists.txt 2015-10-14 15:31:05 +0000
561@@ -8,6 +8,7 @@
562 ${CMAKE_CURRENT_SOURCE_DIR}/test_xcursor_loader.cpp
563 ${CMAKE_CURRENT_SOURCE_DIR}/test_touchspot_controller.cpp
564 ${CMAKE_CURRENT_SOURCE_DIR}/test_input_event.cpp
565+ ${CMAKE_CURRENT_SOURCE_DIR}/test_input_platform_probing.cpp
566 ${CMAKE_CURRENT_SOURCE_DIR}/test_event_builders.cpp
567 ${CMAKE_CURRENT_SOURCE_DIR}/test_default_input_device_hub.cpp
568 ${CMAKE_CURRENT_SOURCE_DIR}/test_default_input_manager.cpp
569
570=== added file 'tests/unit-tests/input/test_input_platform_probing.cpp'
571--- tests/unit-tests/input/test_input_platform_probing.cpp 1970-01-01 00:00:00 +0000
572+++ tests/unit-tests/input/test_input_platform_probing.cpp 2015-10-14 15:31:05 +0000
573@@ -0,0 +1,161 @@
574+/*
575+ * Copyright © 2015 Canonical Ltd.
576+ *
577+ * This program is free software: you can redistribute it and/or modify
578+ * it under the terms of the GNU General Public License version 3 as
579+ * published by the Free Software Foundation.
580+ *
581+ * This program is distributed in the hope that it will be useful,
582+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
583+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
584+ * GNU General Public License for more details.
585+ *
586+ * You should have received a copy of the GNU General Public License
587+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
588+ *
589+ * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com>
590+ */
591+
592+#include <gtest/gtest.h>
593+
594+#include "mir/input/input_probe.h"
595+
596+#include "mir/input/platform.h"
597+#include "src/server/report/null_report_factory.h"
598+
599+#include "mir/options/option.h"
600+#include "mir/emergency_cleanup_registry.h"
601+
602+#include "mir_test_framework/udev_environment.h"
603+#include "mir_test_framework/executable_path.h"
604+#include "mir_test_framework/stub_input_platform.h"
605+#include "mir/test/doubles/mock_x11.h"
606+#include "mir/test/doubles/mock_libinput.h"
607+#include "mir/test/doubles/mock_option.h"
608+#include "mir/test/doubles/mock_input_device_registry.h"
609+#include "src/platforms/evdev/platform.h"
610+#include "src/platforms/mesa/server/x11/input/input_platform.h"
611+#include "mir/test/fake_shared.h"
612+
613+namespace mt = mir::test;
614+namespace mtd = mt::doubles;
615+namespace mi = mir::input;
616+namespace mr = mir::report;
617+namespace mtf = mir_test_framework;
618+
619+using namespace ::testing;
620+
621+namespace
622+{
623+struct StubEmergencyCleanupRegistry : mir::EmergencyCleanupRegistry
624+{
625+ void add(mir::EmergencyCleanupHandler const&) override {}
626+};
627+char const platform_input_lib[] = "platform-input-lib";
628+char const platform_path[] = "platform-path";
629+
630+struct InputPlatformProbe : ::testing::Test
631+{
632+ InputPlatformProbe()
633+ {
634+ ON_CALL(mock_options, is_set(StrEq(platform_input_lib))).WillByDefault(Return(false));
635+ ON_CALL(mock_options, is_set(StrEq(platform_path))).WillByDefault(Return(true));
636+ ON_CALL(mock_options, get(StrEq(platform_path),Matcher<char const*>(_)))
637+ .WillByDefault(Return(platform_path_value));
638+ ON_CALL(mock_options, get(StrEq(platform_path)))
639+ .WillByDefault(Invoke(
640+ [this](char const*) -> boost::any const&
641+ {
642+ return platform_path_value_as_any;
643+ }));
644+ ON_CALL(mock_options, get(StrEq(platform_input_lib)))
645+ .WillByDefault(Invoke(
646+ [this](char const*) -> boost::any const&
647+ {
648+ return platform_input_lib_value_as_any;
649+ }));
650+ }
651+
652+ void disable_x11()
653+ {
654+#ifdef MIR_BUILD_PLATFORM_MESA_X11
655+ ON_CALL(mock_x11, XOpenDisplay(_)).WillByDefault(Return(nullptr));
656+#endif
657+ }
658+
659+ // replace with with mocks for udev and evdev to simulate root or non-root
660+ // access on evdev devices, and enable the disabled test case(s) below.
661+ mtf::UdevEnvironment env;
662+
663+#ifdef MIR_BUILD_PLATFORM_MESA_X11
664+ NiceMock<mtd::MockX11> mock_x11;
665+#endif
666+ NiceMock<mtd::MockLibInput> mock_libinput;
667+ NiceMock<mtd::MockOption> mock_options;
668+ mtd::MockInputDeviceRegistry mock_registry;
669+ StubEmergencyCleanupRegistry stub_emergency;
670+ std::shared_ptr<mir::SharedLibraryProberReport> stub_prober_report{mr::null_shared_library_prober_report()};
671+ std::string platform_path_value{mtf::server_platform_path()};
672+ boost::any platform_path_value_as_any{platform_path_value};
673+ std::string platform_input_lib_value;
674+ boost::any platform_input_lib_value_as_any;
675+};
676+
677+template <typename Expected>
678+struct OfPtrTypeMatcher
679+{
680+ template <typename T>
681+ bool MatchAndExplain(T&& p, MatchResultListener* /* listener */) const
682+ {
683+ return dynamic_cast<Expected*>(&*p) != nullptr;
684+ }
685+ void DescribeTo(::std::ostream* os) const
686+ {
687+ *os << "is a or derived from a " << typeid(Expected).name();
688+ }
689+ void DescribeNegationTo(::std::ostream* os) const
690+ {
691+ *os << "is not or not derived from " << typeid(Expected).name();
692+ }
693+};
694+
695+template<typename Dest>
696+inline auto OfPtrType()
697+{
698+ return MakePolymorphicMatcher(OfPtrTypeMatcher<Dest>());
699+}
700+}
701+
702+
703+TEST_F(InputPlatformProbe, stub_platform_not_picked_up_by_default)
704+{
705+ disable_x11();
706+ auto platforms =
707+ mi::probe_input_platforms(mock_options, mt::fake_shared(stub_emergency), mt::fake_shared(mock_registry),
708+ mr::null_input_report(), *stub_prober_report);
709+
710+ EXPECT_THAT(platforms, ElementsAre(OfPtrType<mi::evdev::Platform>()));
711+}
712+
713+#ifdef MIR_BUILD_PLATFORM_MESA_X11
714+TEST_F(InputPlatformProbe, x11_platform_found_and_used_when_display_connection_works)
715+{
716+ auto platforms =
717+ mi::probe_input_platforms(mock_options, mt::fake_shared(stub_emergency), mt::fake_shared(mock_registry),
718+ mr::null_input_report(), *stub_prober_report);
719+
720+ EXPECT_THAT(platforms, UnorderedElementsAre(OfPtrType<mi::evdev::Platform>(), OfPtrType<mi::X::XInputPlatform>()));
721+}
722+#endif
723+
724+
725+TEST_F(InputPlatformProbe, allows_forcing_stub_input_platform)
726+{
727+ ON_CALL(mock_options, is_set(StrEq(platform_input_lib))).WillByDefault(Return(true));
728+ platform_input_lib_value = mtf::server_input_platform("input-stub.so");
729+ platform_input_lib_value_as_any = platform_input_lib_value;
730+ auto platforms =
731+ mi::probe_input_platforms(mock_options, mt::fake_shared(stub_emergency), mt::fake_shared(mock_registry),
732+ mr::null_input_report(), *stub_prober_report);
733+ EXPECT_THAT(platforms, ElementsAre(OfPtrType<mtf::StubInputPlatform>()));
734+}

Subscribers

People subscribed via source and target branches