Mir

Merge lp:~raof/mir/proper-driver-loading into lp:mir

Proposed by Chris Halse Rogers
Status: Rejected
Rejected by: Chris Halse Rogers
Proposed branch: lp:~raof/mir/proper-driver-loading
Merge into: lp:mir
Diff against target: 3783 lines (+1833/-412) (has conflicts)
94 files modified
benchmarks/frame-uniformity/CMakeLists.txt (+2/-1)
debian/control (+48/-30)
debian/mir-client-platform-android.install (+1/-1)
debian/mir-client-platform-mesa.install (+1/-1)
debian/mir-platform-graphics-android.install (+1/-1)
debian/mir-platform-graphics-mesa.install (+1/-1)
debian/mir-test-tools.install (+2/-1)
debian/rules (+5/-3)
include/platform/mir/graphics/platform.h (+36/-0)
include/platform/mir/options/configuration.h (+1/-0)
platform-ABI-sha1sums (+8/-1)
server-ABI-sha1sums (+8/-1)
src/CMakeLists.txt (+2/-0)
src/client/CMakeLists.txt (+17/-13)
src/client/android/CMakeLists.txt (+7/-22)
src/client/android/android_native_display_container.cpp (+16/-4)
src/client/android/android_native_display_container.h (+8/-1)
src/client/android/client_platform_factory.cpp (+21/-5)
src/client/android/client_platform_factory.h (+2/-5)
src/client/android/symbols.map (+5/-4)
src/client/client_context.h (+0/-1)
src/client/client_platform_factory.h (+5/-2)
src/client/connection_configuration.h (+0/-3)
src/client/default_connection_configuration.cpp (+23/-18)
src/client/default_connection_configuration.h (+0/-4)
src/client/egl_native_display_container.h (+3/-1)
src/client/mesa/CMakeLists.txt (+6/-22)
src/client/mesa/client_platform.cpp (+1/-1)
src/client/mesa/client_platform_factory.cpp (+19/-5)
src/client/mesa/client_platform_factory.h (+0/-5)
src/client/mesa/mesa_native_display_container.cpp (+5/-5)
src/client/mesa/mesa_native_display_container.h (+1/-1)
src/client/mesa/native_surface.cpp (+0/-1)
src/client/mesa/symbols.map (+6/-4)
src/client/mir_connection.cpp (+7/-9)
src/client/mir_connection.h (+2/-2)
src/client/probing_client_platform_factory.cpp (+38/-0)
src/client/probing_client_platform_factory.h (+27/-0)
src/common/graphics/android/mir_native_window.cpp (+0/-1)
src/common/symbols.map (+1/-0)
src/include/platform/mir/shared_library_loader.h (+0/-28)
src/platform/CMakeLists.txt (+22/-12)
src/platform/graphics/CMakeLists.txt (+1/-0)
src/platform/graphics/android/CMakeLists.txt (+16/-25)
src/platform/graphics/android/platform.cpp (+19/-0)
src/platform/graphics/android/symbols.map (+8/-0)
src/platform/graphics/mesa/CMakeLists.txt (+19/-26)
src/platform/graphics/mesa/platform.cpp (+28/-0)
src/platform/graphics/mesa/symbols.map (+8/-0)
src/platform/graphics/platform_probe.cpp (+50/-0)
src/platform/graphics/platform_probe.h (+37/-0)
src/platform/options/default_configuration.cpp (+67/-20)
src/platform/symbols.map (+2/-0)
src/server/CMakeLists.txt (+5/-1)
src/server/graphics/CMakeLists.txt (+1/-1)
src/server/graphics/default_configuration.cpp (+68/-5)
src/server/server.cpp (+1/-1)
tests/acceptance-tests/CMakeLists.txt (+0/-5)
tests/acceptance-tests/server_configuration_wrapping.cpp (+3/-0)
tests/acceptance-tests/test_symbols_required_by_mesa.cpp (+6/-3)
tests/include/mir_test_doubles/mock_android_alloc_device.h (+4/-0)
tests/include/mir_test_doubles/mock_client_context.h (+0/-6)
tests/include/mir_test_doubles/mock_hwc_composer_device_1.h (+5/-0)
tests/include/mir_test_framework/client_platform_factory.h (+72/-0)
tests/include/mir_test_framework/stub_client_platform_factory.h (+33/-0)
tests/include/mir_test_framework/stub_server_platform_factory.h (+45/-0)
tests/integration-tests/CMakeLists.txt (+21/-2)
tests/mir_test_doubles/CMakeLists.txt (+13/-10)
tests/mir_test_framework/CMakeLists.txt (+54/-21)
tests/mir_test_framework/headless_test.cpp (+10/-0)
tests/mir_test_framework/platform_graphics_dummy.cpp (+33/-0)
tests/mir_test_framework/stub_client_platform_factory.cpp (+147/-0)
tests/mir_test_framework/stub_client_platform_module.cpp (+35/-0)
tests/mir_test_framework/stub_server_platform_factory.cpp (+54/-0)
tests/mir_test_framework/stubbed_graphics_platform.cpp (+13/-0)
tests/mir_test_framework/stubbed_server_configuration.cpp (+2/-2)
tests/mir_test_framework/symbols-client.map (+7/-0)
tests/mir_test_framework/symbols-server.map (+8/-0)
tests/mir_test_framework/testing_client_options.cpp (+8/-6)
tests/unit-tests/CMakeLists.txt (+31/-9)
tests/unit-tests/client/CMakeLists.txt (+1/-0)
tests/unit-tests/client/android/test_android_client_platform.cpp (+4/-7)
tests/unit-tests/client/mesa/test_client_platform.cpp (+7/-6)
tests/unit-tests/client/mesa/test_mesa_native_display_container.cpp (+1/-1)
tests/unit-tests/client/test_client_platform.cpp (+109/-29)
tests/unit-tests/client/test_probing_client_platform_factory.cpp (+141/-0)
tests/unit-tests/graphics/CMakeLists.txt (+1/-0)
tests/unit-tests/graphics/android/test_platform.cpp (+24/-0)
tests/unit-tests/graphics/mesa/test_platform.cpp (+22/-0)
tests/unit-tests/graphics/test_platform_prober.cpp (+214/-0)
tests/unit-tests/shared_library_test.cpp (+3/-3)
tests/unit-tests/test_shared_library_prober.cpp (+1/-0)
tools/install_on_android.sh (+4/-3)
tools/valgrind_suppressions_armhf (+9/-0)
Text conflict in debian/control
Text conflict in debian/rules
Text conflict in platform-ABI-sha1sums
Text conflict in server-ABI-sha1sums
Text conflict in tests/mir_test_framework/headless_test.cpp
Text conflict in tests/mir_test_framework/stubbed_graphics_platform.cpp
Text conflict in tests/mir_test_framework/testing_client_options.cpp
To merge this branch: bzr merge lp:~raof/mir/proper-driver-loading
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Needs Fixing
Mir development team Pending
Review via email: mp+243007@code.launchpad.net

Commit message

Move the platform plugins into a private directory

We now probe all the DSOs in the driver directory and load the appropriate one, with the appropriate version.
DSO filenames are irrelevant, so everything is now parallel installable.

Description of the change

This is basically a resubmit of https://code.launchpad.net/~raof/mir/privatise-all-the-things/+merge/234063

I *had* hoped to additionally break it out into chunks, but LP seems to be super-confused.

The three MPs
https://code.launchpad.net/~raof/mir/client-driver-probing/+merge/242865
https://code.launchpad.net/~raof/mir/server-side-platform-probing/+merge/243005
https://code.launchpad.net/~raof/mir/plugin-probe-packaging/+merge/243006
should be stacked one on top of the other, if you'd like to review incrementalish bits (although they're not individually landable).

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

Unmerged revisions

2104. By Chris Halse Rogers

Packaging for probable client/server platform plugins

2103. By Chris Halse Rogers

Oops. Add a whole bunch of accidentally missing files

2102. By Chris Halse Rogers

Move dummy modules alongside their regular counterparts

2101. By Chris Halse Rogers

Implement server-side graphics platform probe

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'benchmarks/frame-uniformity/CMakeLists.txt'
2--- benchmarks/frame-uniformity/CMakeLists.txt 2014-11-20 09:53:04 +0000
3+++ benchmarks/frame-uniformity/CMakeLists.txt 2014-11-27 07:32:44 +0000
4@@ -24,15 +24,16 @@
5 target_link_libraries(frame_uniformity_test_client
6 mirserver
7 mirclient
8+ mirplatform
9
10 mir-test
11 mir-test-framework
12 mir-test-doubles
13 mir-test-doubles-platform
14
15+
16 # Why does this have to come after mir-test-framework here but not in tests/acceptance-tests/
17 # /CMakeLists.txt? ~racarr
18- mirplatform
19
20 3rd_party
21 ${PROTOBUF_LIBRARIES}
22
23=== modified file 'debian/control'
24--- debian/control 2014-11-27 03:48:20 +0000
25+++ debian/control 2014-11-27 07:32:44 +0000
26@@ -67,7 +67,11 @@
27 Pre-Depends: ${misc:Pre-Depends}
28 Depends: ${misc:Depends},
29 ${shlibs:Depends},
30+<<<<<<< TREE
31 libmir${platform-driver}-mesa | libmir${platform-driver}-android,
32+=======
33+ mir-platform-graphics-mesa | mir-platform-graphics-android,
34+>>>>>>> MERGE-SOURCE
35 Description: Display server for Ubuntu - server library
36 Mir is a display server running on linux systems, with a focus on efficiency,
37 robust operation and a well-defined driver model.
38@@ -144,7 +148,11 @@
39 Pre-Depends: ${misc:Pre-Depends}
40 Depends: ${misc:Depends},
41 ${shlibs:Depends},
42+<<<<<<< TREE
43 libmir${client-driver}-mesa | libmir${client-driver}-android,
44+=======
45+ mir-client-platform-mesa | mir-client-platform-android,
46+>>>>>>> MERGE-SOURCE
47 Description: Display server for Ubuntu - client library
48 Mir is a display server running on linux systems, with a focus on efficiency,
49 robust operation and a well-defined driver model.
50@@ -266,7 +274,35 @@
51 Contains the shared libraries required for the Mir server and client.
52
53 # Longer-term these drivers should move out-of-tree
54-Package: libmirclient8driver-mesa
55+Package: mir-platform-graphics-mesa
56+Section: libs
57+Architecture: i386 amd64 armhf arm64
58+Multi-Arch: same
59+Pre-Depends: ${misc:Pre-Depends}
60+Depends: ${misc:Depends},
61+ ${shlibs:Depends},
62+Description: Display server for Ubuntu - platform library for Mesa
63+ Mir is a display server running on linux systems, with a focus on efficiency,
64+ robust operation and a well-defined driver model.
65+ .
66+ Contains the shared libraries required for the Mir server to interact with
67+ the hardware platform using the Mesa drivers.
68+
69+Package: mir-platform-graphics-android
70+Section: libs
71+Architecture: i386 amd64 armhf
72+Multi-Arch: same
73+Pre-Depends: ${misc:Pre-Depends}
74+Depends: ${misc:Depends},
75+ ${shlibs:Depends},
76+Description: Display server for Ubuntu - platform library for Android
77+ Mir is a display server running on linux systems, with a focus on efficiency,
78+ robust operation and a well-defined driver model.
79+ .
80+ Contains the shared libraries required for the Mir server to interact with
81+ the hardware platform using the Android drivers.
82+
83+Package: mir-client-platform-mesa
84 Section: libs
85 Architecture: i386 amd64 armhf arm64
86 Multi-Arch: same
87@@ -280,7 +316,7 @@
88 Contains the shared libraries required for the Mir clients to interact with
89 the underlying hardware platform using the Mesa drivers.
90
91-Package: libmirclient8driver-android
92+Package: mir-client-platform-android
93 Section: libs
94 Architecture: i386 amd64 armhf
95 Multi-Arch: same
96@@ -294,42 +330,19 @@
97 Contains the shared libraries required for the Mir clients to interact with
98 the underlying hardware platform using the Android drivers.
99
100-Package: libmirplatform4driver-mesa
101-Section: libs
102-Architecture: i386 amd64 armhf arm64
103-Multi-Arch: same
104-Pre-Depends: ${misc:Pre-Depends}
105-Depends: ${misc:Depends},
106- ${shlibs:Depends},
107-Description: Display server for Ubuntu - platform library for Mesa
108- Mir is a display server running on linux systems, with a focus on efficiency,
109- robust operation and a well-defined driver model.
110- .
111- Contains the shared libraries required for the Mir server to interact with
112- the hardware platform using the Mesa drivers.
113-
114-Package: libmirplatform4driver-android
115-Section: libs
116-Architecture: i386 amd64 armhf
117-Multi-Arch: same
118-Pre-Depends: ${misc:Pre-Depends}
119-Depends: ${misc:Depends},
120- ${shlibs:Depends},
121-Description: Display server for Ubuntu - platform library for Android
122- Mir is a display server running on linux systems, with a focus on efficiency,
123- robust operation and a well-defined driver model.
124- .
125- Contains the shared libraries required for the Mir server to interact with
126- the hardware platform using the Android drivers.
127-
128 Package: mir-graphics-drivers-desktop
129 Section: libs
130 Architecture: i386 amd64 armhf arm64
131 Multi-Arch: same
132 Pre-Depends: ${misc:Pre-Depends}
133 Depends: ${misc:Depends},
134+<<<<<<< TREE
135 libmir${platform-driver}-mesa,
136 libmir${client-driver}-mesa
137+=======
138+ mir-platform-graphics-mesa,
139+ mir-client-platform-mesa,
140+>>>>>>> MERGE-SOURCE
141 Description: Display server for Ubuntu - desktop driver metapackage
142 Mir is a display server running on linux systems, with a focus on efficiency,
143 robust operation and a well-defined driver model.
144@@ -343,8 +356,13 @@
145 Multi-Arch: same
146 Pre-Depends: ${misc:Pre-Depends}
147 Depends: ${misc:Depends},
148+<<<<<<< TREE
149 libmir${platform-driver}-android,
150 libmir${client-driver}-android
151+=======
152+ mir-platform-graphics-android,
153+ mir-client-platform-android,
154+>>>>>>> MERGE-SOURCE
155 Description: Display server for Ubuntu - android driver metapackage
156 Mir is a display server running on linux systems, with a focus on efficiency,
157 robust operation and a well-defined driver model.
158
159=== renamed file 'debian/libmirclient8driver-android.install' => 'debian/mir-client-platform-android.install'
160--- debian/libmirclient8driver-android.install 2014-11-24 02:16:00 +0000
161+++ debian/mir-client-platform-android.install 2014-11-27 07:32:44 +0000
162@@ -1,1 +1,1 @@
163-usr/lib/*/mir/client*driver/android/*
164+usr/lib/*/mir/client-platform/android.so
165
166=== renamed file 'debian/libmirclient8driver-mesa.install' => 'debian/mir-client-platform-mesa.install'
167--- debian/libmirclient8driver-mesa.install 2014-11-24 02:16:00 +0000
168+++ debian/mir-client-platform-mesa.install 2014-11-27 07:32:44 +0000
169@@ -1,1 +1,1 @@
170-usr/lib/*/mir/client*driver/mesa/*
171+usr/lib/*/mir/client-platform/mesa.so
172
173=== renamed file 'debian/libmirplatform4driver-android.install' => 'debian/mir-platform-graphics-android.install'
174--- debian/libmirplatform4driver-android.install 2014-11-24 02:16:00 +0000
175+++ debian/mir-platform-graphics-android.install 2014-11-27 07:32:44 +0000
176@@ -1,1 +1,1 @@
177-usr/lib/*/mir/platform*driver/android/*
178+usr/lib/*/mir/server-platform/graphics-android.so
179
180=== renamed file 'debian/libmirplatform4driver-mesa.install' => 'debian/mir-platform-graphics-mesa.install'
181--- debian/libmirplatform4driver-mesa.install 2014-11-24 02:16:00 +0000
182+++ debian/mir-platform-graphics-mesa.install 2014-11-27 07:32:44 +0000
183@@ -1,1 +1,1 @@
184-usr/lib/*/mir/platform*driver/mesa/*
185+usr/lib/*/mir/server-platform/graphics-mesa.so
186
187=== modified file 'debian/mir-test-tools.install'
188--- debian/mir-test-tools.install 2014-11-24 02:16:00 +0000
189+++ debian/mir-test-tools.install 2014-11-27 07:32:44 +0000
190@@ -5,4 +5,5 @@
191 usr/bin/mir_performance_tests
192 usr/lib/*/mir/tools/libmirclientlttng.so
193 usr/lib/*/mir/tools/libmirserverlttng.so
194-usr/lib/*/libmirplatformstub.so
195+usr/lib/*/mir/client-platform/dummy.so
196+usr/lib/*/mir/server-platform/graphics-dummy.so
197
198=== modified file 'debian/rules'
199--- debian/rules 2014-11-27 03:48:20 +0000
200+++ debian/rules 2014-11-27 07:32:44 +0000
201@@ -13,9 +13,6 @@
202 export CC=$(DEB_HOST_GNU_TYPE)-gcc-4.9
203 export CXX=$(DEB_HOST_GNU_TYPE)-g++-4.9
204
205-export PLATFORM_DRIVER = platform4driver
206-export CLIENT_DRIVER = client8driver
207-
208 %:
209 dh $@ --parallel --fail-missing
210
211@@ -57,6 +54,7 @@
212 # Nothing outside Mir should link to libmirprotobuf directly.
213 # Delete the symlink so that --fail-missing doesn't think we've missed it
214 # accidentally.
215+<<<<<<< TREE
216 rm debian/tmp/usr/lib/*/libmirprotobuf.so
217 dh_install --fail-missing \
218 -Xusr/lib/$(DEB_HOST_MULTIARCH)/libmir$(PLATFORM_DRIVER).so \
219@@ -72,3 +70,7 @@
220 dh_gencontrol -- \
221 -Vplatform-driver=$(PLATFORM_DRIVER) \
222 -Vclient-driver=$(CLIENT_DRIVER)
223+=======
224+ -rm debian/tmp/usr/lib/*/libmirprotobuf.so
225+ dh_install --fail-missing
226+>>>>>>> MERGE-SOURCE
227
228=== modified file 'include/platform/mir/graphics/platform.h'
229--- include/platform/mir/graphics/platform.h 2014-11-27 03:48:20 +0000
230+++ include/platform/mir/graphics/platform.h 2014-11-27 07:32:44 +0000
231@@ -96,6 +96,33 @@
232 };
233
234 /**
235+ * A measure of how good this module is at supporting the current device
236+ *
237+ * \note This is compared as an integer; best + 1 is a valid PlatformPriority that
238+ * will be used in preference to a module that reports best.
239+ * Platform modules distributed with Mir will never use a priority higher
240+ * than best.
241+ */
242+enum PlatformPriority : uint32_t
243+{
244+ unsupported = 0, /**< Unable to function at all on this device */
245+ supported = 128, /**< Capable of providing a functioning Platform on this device,
246+ * possibly with degraded performance or features.
247+ */
248+ best = 256 /**< Capable of providing a Platform with the best features and
249+ * performance this device is capable of.
250+ */
251+};
252+
253+/**
254+ * Describes a platform module
255+ */
256+struct ModuleProperties
257+{
258+ char const* name;
259+};
260+
261+/**
262 * Function prototype used to return a new graphics platform.
263 *
264 * \param [in] options options to use for this platform
265@@ -118,6 +145,15 @@
266 boost::program_options::options_description& config);
267 extern "C" void add_platform_options(
268 boost::program_options::options_description& config);
269+
270+// TODO: We actually need to be more granular here; on a device with more
271+// than one graphics system we may need a different platform per GPU,
272+// so we should be associating platforms with graphics devices in some way
273+extern "C" typedef PlatformPriority(*PlatformProbe)();
274+extern "C" PlatformPriority probe_platform();
275+
276+extern "C" typedef ModuleProperties const*(*DescribeModule)();
277+extern "C" ModuleProperties const* describe_module();
278 }
279 }
280
281
282=== modified file 'include/platform/mir/options/configuration.h'
283--- include/platform/mir/options/configuration.h 2014-11-24 02:16:00 +0000
284+++ include/platform/mir/options/configuration.h 2014-11-27 07:32:44 +0000
285@@ -54,6 +54,7 @@
286 extern char const* const lttng_opt_value;
287
288 extern char const* const platform_graphics_lib;
289+extern char const* const platform_graphics_path;
290
291 class Configuration
292 {
293
294=== modified file 'platform-ABI-sha1sums'
295--- platform-ABI-sha1sums 2014-11-27 03:48:20 +0000
296+++ platform-ABI-sha1sums 2014-11-27 07:32:44 +0000
297@@ -37,12 +37,19 @@
298 5dc095474ef3e294c0aa4008e9ed997bdb21d34c include/platform/mir/graphics/gl_config.h
299 d0442a5d5d88a4be6e3e1f99e433c1c43a86bfce include/platform/mir/graphics/gl_context.h
300 979d2c1ac723ccef538d9a378228a02b0f173bd7 include/platform/mir/graphics/graphic_buffer_allocator.h
301+<<<<<<< TREE
302 9bbe7eef3a470d7c2daf74de2943a2d03f80aa20 include/platform/mir/graphics/native_platform.h
303 3bd5f663b62fd1e4be92518a27ed5a0f6a82f20b include/platform/mir/graphics/platform.h
304+=======
305+f90a35371e236a6cfec8e9a8474dbb3305c7621e include/platform/mir/graphics/internal_client.h
306+c9730cac4a3a101f9706ec6f444958abe047fd88 include/platform/mir/graphics/internal_surface.h
307+c187e4d1ca333ded84d4599c6527b13a658dd77a include/platform/mir/graphics/native_platform.h
308+3a859b3d78822d95910a3053684ab3948af176b6 include/platform/mir/graphics/platform.h
309+>>>>>>> MERGE-SOURCE
310 3b3463d2513f4c3985f2400496dab333518f9a13 include/platform/mir/graphics/platform_ipc_operations.h
311 1b77fb3290af00dc7d1c11dcc5388972dacb9ec3 include/platform/mir/graphics/platform_ipc_package.h
312 84c063346b3bd51b4624d9f940008d4c3f8be066 include/platform/mir/graphics/renderable.h
313-abeb45a8c6bfc81a12136f25e455e9803c32c10e include/platform/mir/options/configuration.h
314+93a154564a8b25a36c91492b6dc3d8663604ad06 include/platform/mir/options/configuration.h
315 47007c783c174f8e94d332c4b13c6b01358b48fb include/platform/mir/options/default_configuration.h
316 b45f14082c4f8b29efaa1b13de795dcb29deb738 include/platform/mir/options/option.h
317 3c37cc31e8b290b89c311d82f02e07d342766451 include/platform/mir/options/program_option.h
318
319=== modified file 'server-ABI-sha1sums'
320--- server-ABI-sha1sums 2014-11-27 03:48:20 +0000
321+++ server-ABI-sha1sums 2014-11-27 07:32:44 +0000
322@@ -37,12 +37,19 @@
323 5dc095474ef3e294c0aa4008e9ed997bdb21d34c include/platform/mir/graphics/gl_config.h
324 d0442a5d5d88a4be6e3e1f99e433c1c43a86bfce include/platform/mir/graphics/gl_context.h
325 979d2c1ac723ccef538d9a378228a02b0f173bd7 include/platform/mir/graphics/graphic_buffer_allocator.h
326+<<<<<<< TREE
327 9bbe7eef3a470d7c2daf74de2943a2d03f80aa20 include/platform/mir/graphics/native_platform.h
328 3bd5f663b62fd1e4be92518a27ed5a0f6a82f20b include/platform/mir/graphics/platform.h
329+=======
330+f90a35371e236a6cfec8e9a8474dbb3305c7621e include/platform/mir/graphics/internal_client.h
331+c9730cac4a3a101f9706ec6f444958abe047fd88 include/platform/mir/graphics/internal_surface.h
332+c187e4d1ca333ded84d4599c6527b13a658dd77a include/platform/mir/graphics/native_platform.h
333+3a859b3d78822d95910a3053684ab3948af176b6 include/platform/mir/graphics/platform.h
334+>>>>>>> MERGE-SOURCE
335 3b3463d2513f4c3985f2400496dab333518f9a13 include/platform/mir/graphics/platform_ipc_operations.h
336 1b77fb3290af00dc7d1c11dcc5388972dacb9ec3 include/platform/mir/graphics/platform_ipc_package.h
337 84c063346b3bd51b4624d9f940008d4c3f8be066 include/platform/mir/graphics/renderable.h
338-abeb45a8c6bfc81a12136f25e455e9803c32c10e include/platform/mir/options/configuration.h
339+93a154564a8b25a36c91492b6dc3d8663604ad06 include/platform/mir/options/configuration.h
340 47007c783c174f8e94d332c4b13c6b01358b48fb include/platform/mir/options/default_configuration.h
341 b45f14082c4f8b29efaa1b13de795dcb29deb738 include/platform/mir/options/option.h
342 3c37cc31e8b290b89c311d82f02e07d342766451 include/platform/mir/options/program_option.h
343
344=== modified file 'src/CMakeLists.txt'
345--- src/CMakeLists.txt 2014-11-24 02:16:00 +0000
346+++ src/CMakeLists.txt 2014-11-27 07:32:44 +0000
347@@ -20,3 +20,5 @@
348 set(MIR_PLATFORM_REFERENCES ${MIR_PLATFORM_REFERENCES} PARENT_SCOPE)
349 set(MIR_COMMON_OBJECTS ${MIR_COMMON_OBJECTS} PARENT_SCOPE)
350 set(MIR_COMMON_REFERENCES ${MIR_COMMON_REFERENCES} PARENT_SCOPE)
351+set(MIR_CLIENT_PLATFORM_PATH ${MIR_CLIENT_PLATFORM_PATH} PARENT_SCOPE)
352+set(MIR_SERVER_PLATFORM_PLUGIN_PATH ${MIR_SERVER_PLATFORM_PLUGIN_PATH} PARENT_SCOPE)
353
354=== modified file 'src/client/CMakeLists.txt'
355--- src/client/CMakeLists.txt 2014-11-27 03:48:20 +0000
356+++ src/client/CMakeLists.txt 2014-11-27 07:32:44 +0000
357@@ -1,13 +1,3 @@
358-set(MIRCLIENT_ABI 8)
359-set(CLIENT_DRIVER client${MIRCLIENT_ABI}driver)
360-set(MIR_CLIENT_DRIVER mir${CLIENT_DRIVER})
361-set(MIR_CLIENT_DRIVER_BINARY lib${MIR_CLIENT_DRIVER}.so
362- CACHE STRING "File name of Mir client drivers")
363-add_definitions(
364- -DMIR_CLIENT_DRIVER_BINARY="${MIR_CLIENT_DRIVER_BINARY}"
365- -DMIR_LOGGING_COMPONENT_FALLBACK="mirclient"
366-)
367-
368 set(PREFIX "${CMAKE_INSTALL_PREFIX}")
369 set(EXEC_PREFIX "${CMAKE_INSTALL_PREFIX}")
370 set(LIBDIR "${CMAKE_INSTALL_FULL_LIBDIR}")
371@@ -33,6 +23,19 @@
372 ${DRM_INCLUDE_DIRS}
373 )
374
375+set(MIRCLIENT_ABI 8)
376+set(CLIENT_PLATFORM_VERSION "MIR_CLIENT_PLATFORM_2")
377+set(symbol_map ${CMAKE_SOURCE_DIR}/src/client/symbols.map)
378+
379+set(MIR_CLIENT_PLATFORM_PATH
380+ ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/mir/client-platform
381+)
382+set(MIR_CLIENT_PLATFORM_PATH ${MIR_CLIENT_PLATFORM_PATH} PARENT_SCOPE)
383+
384+add_definitions(-DMIR_CLIENT_PLATFORM_PATH="${MIR_CLIENT_PLATFORM_PATH}/")
385+add_definitions(-DCLIENT_PLATFORM_VERSION="${CLIENT_PLATFORM_VERSION}")
386+add_definitions(-DMIR_LOGGING_COMPONENT_FALLBACK="mirclient")
387+
388 add_subdirectory(rpc/)
389 add_subdirectory(lttng/)
390
391@@ -72,6 +75,7 @@
392 mir_prompt_session.cpp
393 mir_prompt_session_api.cpp
394 mir_event_distributor.cpp
395+ probing_client_platform_factory.cpp
396 periodic_perf_report.cpp
397 )
398
399@@ -81,8 +85,6 @@
400 $<TARGET_OBJECTS:mirclientobjects>
401 )
402
403-set(symbol_map ${CMAKE_CURRENT_SOURCE_DIR}/symbols.map)
404-
405 set_target_properties(
406 mirclient
407
408@@ -91,7 +93,9 @@
409 LINK_FLAGS "-Wl,--exclude-libs=ALL -Wl,--version-script,${symbol_map}"
410 )
411
412-target_link_libraries(mirclient
413+target_link_libraries(
414+ mirclient
415+
416 mirclientrpc
417 mirclientlttngstatic
418 mircommon
419
420=== modified file 'src/client/android/CMakeLists.txt'
421--- src/client/android/CMakeLists.txt 2014-11-24 02:16:00 +0000
422+++ src/client/android/CMakeLists.txt 2014-11-27 07:32:44 +0000
423@@ -14,17 +14,18 @@
424 )
425
426 add_library(
427- mirclientplatformandroid SHARED
428-
429+ mirclientplatformandroid MODULE
430+
431 $<TARGET_OBJECTS:mirclientplatformandroidobjects>
432 $<TARGET_OBJECTS:mirclient_platformimpl>
433 )
434
435 set_target_properties(
436 mirclientplatformandroid PROPERTIES
437- OUTPUT_NAME ${MIR_CLIENT_DRIVER}
438- LIBRARY_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH}/android
439- LINK_FLAGS "-Wl,--exclude-libs=ALL -Wl,--version-script,${symbol_map}"
440+ OUTPUT_NAME android
441+ LIBRARY_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH}/client-modules
442+ PREFIX ""
443+ LINK_FLAGS "-Wl,--version-script,${symbol_map}"
444 )
445
446 target_link_libraries(mirclientplatformandroid
447@@ -33,20 +34,4 @@
448 ${LIBHARDWARE_LIBRARIES}
449 )
450
451-install(TARGETS mirclientplatformandroid LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mir/${CLIENT_DRIVER}/android)
452-
453-if (MIR_TEST_PLATFORM STREQUAL "android")
454- add_custom_command(TARGET mirclientplatformandroid
455- POST_BUILD
456- COMMAND ${CMAKE_COMMAND} -E remove ${MIR_CLIENT_DRIVER_BINARY}
457- COMMAND ${CMAKE_COMMAND} -E create_symlink android/$<TARGET_FILE_NAME:mirclientplatformandroid> ${MIR_CLIENT_DRIVER_BINARY}
458- WORKING_DIRECTORY ${LIBRARY_OUTPUT_PATH}
459- )
460-
461- install(CODE
462- "execute_process(
463- COMMAND ln -sf mir/${CLIENT_DRIVER}/android/${MIR_CLIENT_DRIVER_BINARY}
464- WORKING_DIRECTORY \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}
465- )"
466- )
467-endif()
468+install(TARGETS mirclientplatformandroid LIBRARY DESTINATION ${MIR_CLIENT_PLATFORM_PATH})
469
470=== modified file 'src/client/android/android_native_display_container.cpp'
471--- src/client/android/android_native_display_container.cpp 2014-11-24 02:16:00 +0000
472+++ src/client/android/android_native_display_container.cpp 2014-11-27 07:32:44 +0000
473@@ -62,16 +62,28 @@
474 bool
475 mcla::AndroidNativeDisplayContainer::validate(MirEGLNativeDisplayType display) const
476 {
477- return mir_connection_is_valid(static_cast<MirConnection*>(display));
478+ std::lock_guard<std::mutex> lg(guard);
479+ return (valid_displays.find(display) != valid_displays.end());
480 }
481
482 MirEGLNativeDisplayType
483-mcla::AndroidNativeDisplayContainer::create(MirConnection* connection)
484+mcla::AndroidNativeDisplayContainer::create(ClientContext* context)
485 {
486- return static_cast<MirEGLNativeDisplayType>(connection);
487+ std::lock_guard<std::mutex> lg(guard);
488+ auto egl_display = static_cast<MirEGLNativeDisplayType>(context);
489+ valid_displays.insert(egl_display);
490+
491+ return egl_display;
492 }
493
494 void
495-mcla::AndroidNativeDisplayContainer::release(MirEGLNativeDisplayType /* display */)
496+mcla::AndroidNativeDisplayContainer::release(MirEGLNativeDisplayType display)
497 {
498+ std::lock_guard<std::mutex> lg(guard);
499+
500+ auto it = valid_displays.find(display);
501+ if (it == valid_displays.end())
502+ return;
503+
504+ valid_displays.erase(it);
505 }
506
507=== modified file 'src/client/android/android_native_display_container.h'
508--- src/client/android/android_native_display_container.h 2013-05-02 00:11:18 +0000
509+++ src/client/android/android_native_display_container.h 2014-11-27 07:32:44 +0000
510@@ -23,6 +23,9 @@
511
512 #include "mir_toolkit/client_types.h"
513
514+#include <unordered_set>
515+#include <mutex>
516+
517 namespace mir
518 {
519 namespace client
520@@ -36,7 +39,7 @@
521 AndroidNativeDisplayContainer();
522 virtual ~AndroidNativeDisplayContainer();
523
524- MirEGLNativeDisplayType create(MirConnection* connection);
525+ MirEGLNativeDisplayType create(ClientContext* context) override;
526 void release(MirEGLNativeDisplayType display);
527
528 bool validate(MirEGLNativeDisplayType display) const;
529@@ -44,6 +47,10 @@
530 protected:
531 AndroidNativeDisplayContainer(AndroidNativeDisplayContainer const&) = delete;
532 AndroidNativeDisplayContainer& operator=(AndroidNativeDisplayContainer const&) = delete;
533+
534+private:
535+ std::mutex mutable guard;
536+ std::unordered_set<MirEGLNativeDisplayType> valid_displays;
537 };
538
539 }
540
541=== modified file 'src/client/android/client_platform_factory.cpp'
542--- src/client/android/client_platform_factory.cpp 2014-02-07 15:43:41 +0000
543+++ src/client/android/client_platform_factory.cpp 2014-11-27 07:32:44 +0000
544@@ -16,19 +16,35 @@
545 * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>
546 */
547
548-#include "client_platform_factory.h"
549+#include "../client_platform_factory.h"
550+#include "mir_toolkit/client_types.h"
551+#include "../client_context.h"
552 #include "android_client_platform.h"
553
554+#include <stdexcept>
555+
556 namespace mcl = mir::client;
557 namespace mcla = mcl::android;
558
559-std::shared_ptr<mcl::ClientPlatform>
560-mcla::ClientPlatformFactory::create_client_platform(mcl::ClientContext* /*context*/)
561+extern "C" std::shared_ptr<mcl::ClientPlatform>
562+mcl::create_client_platform(mcl::ClientContext* context)
563 {
564+ MirPlatformPackage platform;
565+ context->populate(platform);
566+ if (platform.data_items != 0 || platform.fd_items != 0)
567+ {
568+ throw new std::runtime_error{"Attempted to create Android client platform on non-Android server"};
569+ }
570 return std::make_shared<mcla::AndroidClientPlatform>();
571 }
572
573-extern "C" std::shared_ptr<mcl::ClientPlatformFactory> mcl::create_client_platform_factory()
574+extern "C" bool
575+mcl::is_appropriate_module(mcl::ClientContext* context)
576 {
577- return std::make_shared<mcla::ClientPlatformFactory>();
578+ MirPlatformPackage platform;
579+ context->populate(platform);
580+ // TODO: Actually check what platform we're using, rather than blindly
581+ // hope we can distinguish them from the stuff they've put in the
582+ // PlatformPackage.
583+ return platform.data_items == 0 && platform.fd_items == 0;
584 }
585
586=== modified file 'src/client/android/client_platform_factory.h'
587--- src/client/android/client_platform_factory.h 2014-02-07 15:43:41 +0000
588+++ src/client/android/client_platform_factory.h 2014-11-27 07:32:44 +0000
589@@ -28,11 +28,8 @@
590 namespace android
591 {
592
593-class ClientPlatformFactory : public client::ClientPlatformFactory
594-{
595-public:
596- std::shared_ptr<ClientPlatform> create_client_platform(ClientContext* context) override;
597-};
598+extern "C" std::shared_ptr<ClientPlatform>
599+create_client_platform(ClientContext* context);
600
601 }
602 }
603
604=== modified file 'src/client/android/symbols.map'
605--- src/client/android/symbols.map 2014-11-24 02:16:00 +0000
606+++ src/client/android/symbols.map 2014-11-27 07:32:44 +0000
607@@ -1,5 +1,6 @@
608-MIR_CLIENTPLATFORM_1 {
609- global:
610- create_client_platform_factory;
611+MIR_CLIENT_PLATFORM_2 {
612+ global:
613+ create_client_platform;
614+ is_appropriate_module;
615 local: *;
616-};
617\ No newline at end of file
618+};
619
620=== modified file 'src/client/client_context.h'
621--- src/client/client_context.h 2013-08-28 03:41:48 +0000
622+++ src/client/client_context.h 2014-11-27 07:32:44 +0000
623@@ -29,7 +29,6 @@
624 public:
625 virtual ~ClientContext() {}
626
627- virtual MirConnection* mir_connection() = 0;
628 virtual void populate(MirPlatformPackage& platform_package) = 0;
629
630 protected:
631
632=== modified file 'src/client/client_platform_factory.h'
633--- src/client/client_platform_factory.h 2014-03-06 06:05:17 +0000
634+++ src/client/client_platform_factory.h 2014-11-27 07:32:44 +0000
635@@ -41,8 +41,11 @@
636 ClientPlatformFactory& operator=(ClientPlatformFactory const& p) = delete;
637 };
638
639-extern "C" typedef std::shared_ptr<ClientPlatformFactory>(*CreateClientPlatformFactory)();
640-extern "C" std::shared_ptr<ClientPlatformFactory> create_client_platform_factory();
641+extern "C" typedef std::shared_ptr<ClientPlatform>(*CreateClientPlatform)(ClientContext* context);
642+extern "C" std::shared_ptr<ClientPlatform> create_client_platform(ClientContext* context);
643+
644+extern "C" typedef bool (*ClientPlatformProbe)(ClientContext* context);
645+extern "C" bool is_appropriate_module(ClientContext* context);
646
647 }
648 }
649
650=== modified file 'src/client/connection_configuration.h'
651--- src/client/connection_configuration.h 2014-11-24 02:16:00 +0000
652+++ src/client/connection_configuration.h 2014-11-27 07:32:44 +0000
653@@ -39,8 +39,6 @@
654 class Logger;
655 }
656
657-class SharedLibrary;
658-
659 namespace client
660 {
661 class ConnectionSurfaceMap;
662@@ -65,7 +63,6 @@
663 virtual std::shared_ptr<LifecycleControl> the_lifecycle_control() = 0;
664 virtual std::shared_ptr<EventSink> the_event_sink() = 0;
665 virtual std::shared_ptr<EventHandlerRegister> the_event_handler_register() = 0;
666- virtual std::shared_ptr<SharedLibrary> the_platform_library() = 0;
667
668 protected:
669 ConnectionConfiguration() = default;
670
671=== modified file 'src/client/default_connection_configuration.cpp'
672--- src/client/default_connection_configuration.cpp 2014-11-24 02:16:00 +0000
673+++ src/client/default_connection_configuration.cpp 2014-11-27 07:32:44 +0000
674@@ -35,6 +35,7 @@
675 #include "lifecycle_control.h"
676 #include "mir/shared_library.h"
677 #include "client_platform_factory.h"
678+#include "probing_client_platform_factory.h"
679 #include "mir_event_distributor.h"
680 #include "mir/shared_library_prober.h"
681
682@@ -47,7 +48,10 @@
683 std::string const off_opt_val{"off"};
684 std::string const log_opt_val{"log"};
685 std::string const lttng_opt_val{"lttng"};
686-std::string const default_platform_lib{MIR_CLIENT_DRIVER_BINARY};
687+
688+// Shove this here until we properly manage the lifetime of our
689+// loadable modules
690+std::shared_ptr<mcl::ProbingClientPlatformFactory> the_platform_prober;
691
692 // Hack around the way Qt loads mir:
693 // qtmir and therefore Mir are loaded via dlopen(..., RTLD_LOCAL).
694@@ -108,11 +112,23 @@
695 return client_platform_factory(
696 [this]
697 {
698- auto const create_client_platform_factory =
699- the_platform_library()->load_function<mcl::CreateClientPlatformFactory>(
700- "create_client_platform_factory");
701-
702- return create_client_platform_factory();
703+ ensure_loaded_with_rtld_global();
704+ auto const platform_override = getenv("MIR_CLIENT_PLATFORM_LIB");
705+ std::vector<std::shared_ptr<mir::SharedLibrary>> platform_plugins;
706+ if (platform_override)
707+ {
708+ platform_plugins.push_back(std::make_shared<mir::SharedLibrary>(platform_override));
709+ }
710+ else
711+ {
712+ auto const platform_path_override = getenv("MIR_CLIENT_PLATFORM_PATH");
713+ auto const platform_path = platform_path_override ? platform_path_override : MIR_CLIENT_PLATFORM_PATH;
714+ platform_plugins = mir::libraries_for_path(platform_path, *the_shared_library_prober_report());
715+ }
716+
717+ the_platform_prober = std::make_shared<mcl::ProbingClientPlatformFactory>(platform_plugins);
718+
719+ return the_platform_prober;
720 });
721 }
722
723@@ -211,6 +227,7 @@
724 {
725 auto val_raw = getenv("MIR_CLIENT_SHARED_LIBRARY_PROBER_REPORT");
726 std::string const val{val_raw ? val_raw : off_opt_val};
727+
728 if (val == log_opt_val)
729 return std::make_shared<mir::logging::SharedLibraryProberReport>(the_logger());
730 else if (val == lttng_opt_val)
731@@ -219,15 +236,3 @@
732 return std::make_shared<mir::logging::NullSharedLibraryProberReport>();
733 });
734 }
735-
736-std::shared_ptr<mir::SharedLibrary> mcl::DefaultConnectionConfiguration::the_platform_library()
737-{
738- if (!platform_library)
739- {
740- ensure_loaded_with_rtld_global();
741- auto const val_raw = getenv("MIR_CLIENT_PLATFORM_LIB");
742- std::string const libname{val_raw ? val_raw : default_platform_lib};
743- platform_library = std::make_shared<mir::SharedLibrary>(libname);
744- }
745- return platform_library;
746-}
747
748=== modified file 'src/client/default_connection_configuration.h'
749--- src/client/default_connection_configuration.h 2014-11-24 02:16:00 +0000
750+++ src/client/default_connection_configuration.h 2014-11-27 07:32:44 +0000
751@@ -60,16 +60,12 @@
752 std::shared_ptr<EventSink> the_event_sink() override;
753 std::shared_ptr<EventHandlerRegister> the_event_handler_register() override;
754 std::shared_ptr<mir::SharedLibraryProberReport> the_shared_library_prober_report();
755- std::shared_ptr<SharedLibrary> the_platform_library() override;
756
757 virtual std::string the_socket_file();
758 virtual std::shared_ptr<rpc::RpcReport> the_rpc_report();
759 virtual std::shared_ptr<input::receiver::InputReceiverReport> the_input_receiver_report();
760
761 protected:
762- // MUST be first data member so it is destroyed last.
763- std::shared_ptr<mir::SharedLibrary> platform_library;
764-
765 CachedPtr<google::protobuf::RpcChannel> rpc_channel;
766 CachedPtr<mir::logging::Logger> logger;
767 CachedPtr<ClientPlatformFactory> client_platform_factory;
768
769=== modified file 'src/client/egl_native_display_container.h'
770--- src/client/egl_native_display_container.h 2014-03-06 06:05:17 +0000
771+++ src/client/egl_native_display_container.h 2014-11-27 07:32:44 +0000
772@@ -26,12 +26,14 @@
773 namespace client
774 {
775
776+class ClientContext;
777+
778 class EGLNativeDisplayContainer
779 {
780 public:
781 virtual ~EGLNativeDisplayContainer() {}
782
783- virtual MirEGLNativeDisplayType create(MirConnection* connection) = 0;
784+ virtual MirEGLNativeDisplayType create(ClientContext* context) = 0;
785 virtual void release(MirEGLNativeDisplayType display) = 0;
786
787 virtual bool validate(MirEGLNativeDisplayType display) const = 0;
788
789=== modified file 'src/client/mesa/CMakeLists.txt'
790--- src/client/mesa/CMakeLists.txt 2014-11-24 02:16:00 +0000
791+++ src/client/mesa/CMakeLists.txt 2014-11-27 07:32:44 +0000
792@@ -15,7 +15,7 @@
793 )
794
795 add_library(
796- mirclientplatformmesa SHARED
797+ mirclientplatformmesa MODULE
798
799 $<TARGET_OBJECTS:mirclientplatformmesaobjects>
800 $<TARGET_OBJECTS:mirclient_platformimpl>
801@@ -23,9 +23,10 @@
802
803 set_target_properties(
804 mirclientplatformmesa PROPERTIES
805- OUTPUT_NAME ${MIR_CLIENT_DRIVER}
806- LIBRARY_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH}/mesa
807- LINK_FLAGS "-Wl,--exclude-libs=ALL -Wl,--version-script,${symbol_map}"
808+ OUTPUT_NAME mesa
809+ LIBRARY_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH}/client-modules
810+ PREFIX ""
811+ LINK_FLAGS "-Wl,--version-script,${symbol_map}"
812 )
813
814 target_link_libraries(mirclientplatformmesa
815@@ -33,21 +34,4 @@
816 ${DRM_LDFLAGS} ${DRM_LIBRARIES}
817 )
818
819-install(TARGETS mirclientplatformmesa LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mir/${CLIENT_DRIVER}/mesa)
820-
821-if (MIR_TEST_PLATFORM STREQUAL "mesa")
822- add_custom_command(TARGET mirclientplatformmesa
823- POST_BUILD
824- COMMAND ${CMAKE_COMMAND} -E remove ${MIR_CLIENT_DRIVER_BINARY}
825- COMMAND ${CMAKE_COMMAND} -E create_symlink mesa/$<TARGET_FILE_NAME:mirclientplatformmesa> ${MIR_CLIENT_DRIVER_BINARY}
826- WORKING_DIRECTORY ${LIBRARY_OUTPUT_PATH}
827- )
828-
829- install(CODE
830- "execute_process(
831- COMMAND ln -sf mir/${CLIENT_DRIVER}/mesa/${MIR_CLIENT_DRIVER_BINARY}
832- WORKING_DIRECTORY \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}
833- )"
834- )
835-endif()
836-
837+install(TARGETS mirclientplatformmesa LIBRARY DESTINATION ${MIR_CLIENT_PLATFORM_PATH})
838
839=== modified file 'src/client/mesa/client_platform.cpp'
840--- src/client/mesa/client_platform.cpp 2014-03-06 06:05:17 +0000
841+++ src/client/mesa/client_platform.cpp 2014-11-27 07:32:44 +0000
842@@ -95,7 +95,7 @@
843 std::shared_ptr<EGLNativeDisplayType> mclm::ClientPlatform::create_egl_native_display()
844 {
845 MirEGLNativeDisplayType *mir_native_display = new MirEGLNativeDisplayType;
846- *mir_native_display = display_container.create(context->mir_connection());
847+ *mir_native_display = display_container.create(context);
848 auto egl_native_display = reinterpret_cast<EGLNativeDisplayType*>(mir_native_display);
849
850 return std::shared_ptr<EGLNativeDisplayType>(egl_native_display, NativeDisplayDeleter(display_container));
851
852=== modified file 'src/client/mesa/client_platform_factory.cpp'
853--- src/client/mesa/client_platform_factory.cpp 2014-02-07 15:43:41 +0000
854+++ src/client/mesa/client_platform_factory.cpp 2014-11-27 07:32:44 +0000
855@@ -16,13 +16,16 @@
856 * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>
857 */
858
859-#include "client_platform_factory.h"
860+#include "../client_platform_factory.h"
861 #include "client_platform.h"
862+#include "mir_toolkit/client_types.h"
863+#include "../client_context.h"
864 #include "buffer_file_ops.h"
865 #include "../egl_native_display_container.h"
866
867 #include <sys/mman.h>
868 #include <unistd.h>
869+#include <stdexcept>
870
871 namespace mcl = mir::client;
872 namespace mclm = mcl::mesa;
873@@ -57,15 +60,26 @@
874
875 }
876
877-std::shared_ptr<mcl::ClientPlatform>
878-mclm::ClientPlatformFactory::create_client_platform(mcl::ClientContext* context)
879+extern "C" std::shared_ptr<mcl::ClientPlatform> mcl::create_client_platform(mcl::ClientContext* context)
880 {
881+ MirPlatformPackage package;
882+ context->populate(package);
883+ if (package.data_items != 0 || package.fd_items != 1)
884+ {
885+ throw std::runtime_error{"Attempted to create Mesa client platform on non-Mesa server"};
886+ }
887 auto buffer_file_ops = std::make_shared<RealBufferFileOps>();
888 return std::make_shared<mclm::ClientPlatform>(
889 context, buffer_file_ops, mcl::EGLNativeDisplayContainer::instance());
890 }
891
892-extern "C" std::shared_ptr<mcl::ClientPlatformFactory> mcl::create_client_platform_factory()
893+extern "C" bool
894+mcl::is_appropriate_module(mcl::ClientContext* context)
895 {
896- return std::make_shared<mclm::ClientPlatformFactory>();
897+ MirPlatformPackage platform;
898+ context->populate(platform);
899+ // TODO: Actually check what platform we're using, rather than blindly
900+ // hope we can distinguish them from the stuff they've put in the
901+ // PlatformPackage.
902+ return platform.data_items == 0 && platform.fd_items == 1;
903 }
904
905=== modified file 'src/client/mesa/client_platform_factory.h'
906--- src/client/mesa/client_platform_factory.h 2014-02-07 15:43:41 +0000
907+++ src/client/mesa/client_platform_factory.h 2014-11-27 07:32:44 +0000
908@@ -28,11 +28,6 @@
909 namespace mesa
910 {
911
912-class ClientPlatformFactory : public client::ClientPlatformFactory
913-{
914-public:
915- std::shared_ptr<ClientPlatform> create_client_platform(ClientContext* context) override;
916-};
917
918 }
919 }
920
921=== modified file 'src/client/mesa/mesa_native_display_container.cpp'
922--- src/client/mesa/mesa_native_display_container.cpp 2014-11-24 02:16:00 +0000
923+++ src/client/mesa/mesa_native_display_container.cpp 2014-11-27 07:32:44 +0000
924@@ -18,7 +18,7 @@
925
926 #include "mesa_native_display_container.h"
927
928-#include "mir_toolkit/mir_client_library.h"
929+#include "../client_context.h"
930
931 #include <cstring>
932 #include <unordered_set>
933@@ -35,8 +35,8 @@
934 static int egl_display_get_platform(MirMesaEGLNativeDisplay* display,
935 MirPlatformPackage* package)
936 {
937- auto connection = static_cast<MirConnection*>(display->context);
938- mir_connection_get_platform(connection, package);
939+ auto context = static_cast<mcl::ClientContext*>(display->context);
940+ context->populate(*package);
941 return MIR_MESA_TRUE;
942 }
943
944@@ -93,11 +93,11 @@
945 }
946
947 MirEGLNativeDisplayType
948-mclm::MesaNativeDisplayContainer::create(MirConnection* connection)
949+mclm::MesaNativeDisplayContainer::create(ClientContext* context)
950 {
951 MirMesaEGLNativeDisplay* display = new MirMesaEGLNativeDisplay();
952 display->display_get_platform = egl_display_get_platform;
953- display->context = connection;
954+ display->context = context;
955
956 std::lock_guard<std::mutex> lg(guard);
957 auto egl_display = static_cast<MirEGLNativeDisplayType>(display);
958
959=== modified file 'src/client/mesa/mesa_native_display_container.h'
960--- src/client/mesa/mesa_native_display_container.h 2014-03-06 06:05:17 +0000
961+++ src/client/mesa/mesa_native_display_container.h 2014-11-27 07:32:44 +0000
962@@ -40,7 +40,7 @@
963 MesaNativeDisplayContainer();
964 virtual ~MesaNativeDisplayContainer();
965
966- MirEGLNativeDisplayType create(MirConnection* connection);
967+ MirEGLNativeDisplayType create(ClientContext* context);
968 void release(MirEGLNativeDisplayType display);
969
970 bool validate(MirEGLNativeDisplayType display) const;
971
972=== modified file 'src/client/mesa/native_surface.cpp'
973--- src/client/mesa/native_surface.cpp 2014-11-24 02:16:00 +0000
974+++ src/client/mesa/native_surface.cpp 2014-11-27 07:32:44 +0000
975@@ -20,7 +20,6 @@
976 #include "../client_buffer.h"
977 #include "native_surface.h"
978
979-#include <iostream>
980 #include <boost/exception/diagnostic_information.hpp>
981
982 namespace mclm=mir::client::mesa;
983
984=== modified file 'src/client/mesa/symbols.map'
985--- src/client/mesa/symbols.map 2014-11-24 02:16:00 +0000
986+++ src/client/mesa/symbols.map 2014-11-27 07:32:44 +0000
987@@ -1,7 +1,9 @@
988-MIR_CLIENTPLATFORM_1 {
989- global:
990- create_client_platform_factory;
991+MIR_CLIENT_PLATFORM_2 {
992+ global:
993+ create_client_platform;
994+ is_appropriate_module;
995 # Needed by our Mesa EGL platform
996 mir_client_mesa_egl_native_display_is_valid;
997- local: *;
998+ local:
999+ *;
1000 };
1001
1002=== modified file 'src/client/mir_connection.cpp'
1003--- src/client/mir_connection.cpp 2014-11-24 02:16:00 +0000
1004+++ src/client/mir_connection.cpp 2014-11-27 07:32:44 +0000
1005@@ -95,11 +95,11 @@
1006 MirConnection::MirConnection(
1007 mir::client::ConnectionConfiguration& conf) :
1008 deregisterer{this},
1009- platform_library{conf.the_platform_library()},
1010 channel(conf.the_rpc_channel()),
1011 server(channel.get(), ::google::protobuf::Service::STUB_DOESNT_OWN_CHANNEL),
1012 debug(channel.get(), ::google::protobuf::Service::STUB_DOESNT_OWN_CHANNEL),
1013 logger(conf.the_logger()),
1014+ connect_done{false},
1015 client_platform_factory(conf.the_client_platform_factory()),
1016 input_platform(conf.the_input_platform()),
1017 display_configuration(conf.the_display_configuration()),
1018@@ -235,6 +235,9 @@
1019 set_error_message("Connect failed");
1020 }
1021 }
1022+
1023+ connect_done = true;
1024+
1025 /*
1026 * We need to create the client platform after the connection has been
1027 * established, to ensure that the client platform has access to all
1028@@ -370,9 +373,9 @@
1029
1030 void MirConnection::populate(MirPlatformPackage& platform_package)
1031 {
1032- std::lock_guard<decltype(mutex)> lock(mutex);
1033-
1034- if (!connect_result.has_error() && connect_result.has_platform())
1035+ // connect_result is write-once: once it's valid, we don't need to lock
1036+ // to use it.
1037+ if (connect_done && !connect_result.has_error() && connect_result.has_platform())
1038 {
1039 auto const& platform = connect_result.platform();
1040
1041@@ -428,11 +431,6 @@
1042 return platform;
1043 }
1044
1045-MirConnection* MirConnection::mir_connection()
1046-{
1047- return this;
1048-}
1049-
1050 EGLNativeDisplayType MirConnection::egl_native_display()
1051 {
1052 std::lock_guard<decltype(mutex)> lock(mutex);
1053
1054=== modified file 'src/client/mir_connection.h'
1055--- src/client/mir_connection.h 2014-11-24 02:16:00 +0000
1056+++ src/client/mir_connection.h 2014-11-27 07:32:44 +0000
1057@@ -22,6 +22,7 @@
1058 #include <memory>
1059 #include <unordered_set>
1060 #include <unordered_map>
1061+#include <atomic>
1062
1063 #include <mutex>
1064
1065@@ -117,8 +118,6 @@
1066
1067 static bool is_valid(MirConnection *connection);
1068
1069- MirConnection* mir_connection();
1070-
1071 EGLNativeDisplayType egl_native_display();
1072
1073 void on_surface_created(int id, MirSurface* surface);
1074@@ -153,6 +152,7 @@
1075 std::shared_ptr<mir::logging::Logger> const logger;
1076 mir::protobuf::Void void_response;
1077 mir::protobuf::Connection connect_result;
1078+ std::atomic<bool> connect_done;
1079 mir::protobuf::Void ignored;
1080 mir::protobuf::ConnectParameters connect_parameters;
1081 mir::protobuf::DRMAuthMagicStatus drm_auth_magic_status;
1082
1083=== added file 'src/client/probing_client_platform_factory.cpp'
1084--- src/client/probing_client_platform_factory.cpp 1970-01-01 00:00:00 +0000
1085+++ src/client/probing_client_platform_factory.cpp 2014-11-27 07:32:44 +0000
1086@@ -0,0 +1,38 @@
1087+#include "probing_client_platform_factory.h"
1088+
1089+#include <boost/exception/all.hpp>
1090+#include <stdexcept>
1091+
1092+namespace mcl = mir::client;
1093+
1094+mcl::ProbingClientPlatformFactory::ProbingClientPlatformFactory(std::vector<std::shared_ptr<mir::SharedLibrary>> const& modules)
1095+ : platform_modules{modules}
1096+{
1097+ if (modules.empty())
1098+ {
1099+ BOOST_THROW_EXCEPTION(
1100+ std::runtime_error{"Attempted to create a ClientPlatformFactory with no platform modules"});
1101+ }
1102+}
1103+
1104+std::shared_ptr<mcl::ClientPlatform>
1105+mcl::ProbingClientPlatformFactory::create_client_platform(mcl::ClientContext* context)
1106+{
1107+ for (auto& module : platform_modules)
1108+ {
1109+ try
1110+ {
1111+ auto probe = module->load_function<mir::client::ClientPlatformProbe>("is_appropriate_module", CLIENT_PLATFORM_VERSION);
1112+ if (probe(context))
1113+ {
1114+ auto factory = module->load_function<mir::client::CreateClientPlatform>("create_client_platform", CLIENT_PLATFORM_VERSION);
1115+ return factory(context);
1116+ }
1117+ }
1118+ catch(std::runtime_error)
1119+ {
1120+ // We were handled a SharedLibrary that's not a client platform module?
1121+ }
1122+ }
1123+ BOOST_THROW_EXCEPTION(std::runtime_error{"No appropriate client platform module found"});
1124+}
1125
1126=== added file 'src/client/probing_client_platform_factory.h'
1127--- src/client/probing_client_platform_factory.h 1970-01-01 00:00:00 +0000
1128+++ src/client/probing_client_platform_factory.h 2014-11-27 07:32:44 +0000
1129@@ -0,0 +1,27 @@
1130+#ifndef MIR_CLIENT_PROBING_CLIENT_PLATFORM_FACTORY_H_
1131+#define MIR_CLIENT_PROBING_CLIENT_PLATFORM_FACTORY_H_
1132+
1133+#include <vector>
1134+
1135+#include "client_platform_factory.h"
1136+#include "mir/shared_library.h"
1137+
1138+namespace mir
1139+{
1140+namespace client
1141+{
1142+class ProbingClientPlatformFactory : public ClientPlatformFactory
1143+{
1144+public:
1145+ ProbingClientPlatformFactory(std::vector<std::shared_ptr<SharedLibrary>> const& modules);
1146+
1147+ std::shared_ptr<ClientPlatform> create_client_platform(ClientContext *context) override;
1148+private:
1149+ std::vector<std::shared_ptr<SharedLibrary>> platform_modules;
1150+};
1151+
1152+
1153+}
1154+}
1155+
1156+#endif // MIR_CLIENT_PROBING_CLIENT_PLATFORM_FACTORY_H_
1157
1158=== modified file 'src/common/graphics/android/mir_native_window.cpp'
1159--- src/common/graphics/android/mir_native_window.cpp 2014-11-24 02:16:00 +0000
1160+++ src/common/graphics/android/mir_native_window.cpp 2014-11-27 07:32:44 +0000
1161@@ -20,7 +20,6 @@
1162 #include "mir/graphics/android/android_driver_interpreter.h"
1163 #include "mir/graphics/android/sync_fence.h"
1164
1165-#include <iostream>
1166 #include <boost/exception/diagnostic_information.hpp>
1167
1168 namespace mg=mir::graphics;
1169
1170=== modified file 'src/common/symbols.map'
1171--- src/common/symbols.map 2014-11-24 02:16:00 +0000
1172+++ src/common/symbols.map 2014-11-27 07:32:44 +0000
1173@@ -150,6 +150,7 @@
1174 # but they are used by libmirplatform, libmirclient or libmirserver
1175 mir::default_server_socket;
1176 mir::input::android::Lexicon::translate*;
1177+ mir::libraries_for_path*;
1178 mir::logging::input_timestamp*;
1179 mir::logging::log*;
1180 mir::logging::set_logger*;
1181
1182=== removed file 'src/include/platform/mir/shared_library_loader.h'
1183--- src/include/platform/mir/shared_library_loader.h 2014-11-24 02:16:00 +0000
1184+++ src/include/platform/mir/shared_library_loader.h 1970-01-01 00:00:00 +0000
1185@@ -1,28 +0,0 @@
1186-/*
1187- * Copyright © 2013 Canonical Ltd.
1188- *
1189- * This program is free software: you can redistribute it and/or modify it
1190- * under the terms of the GNU Lesser General Public License version 3,
1191- * as published by the Free Software Foundation.
1192- *
1193- * This program is distributed in the hope that it will be useful,
1194- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1195- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1196- * GNU Lesser General Public License for more details.
1197- *
1198- * You should have received a copy of the GNU Lesser General Public License
1199- * along with this program. If not, see <http://www.gnu.org/licenses/>.
1200- *
1201- * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
1202- */
1203-
1204-#ifndef MIR_SHARED_LIBRARY_LOADER_H_
1205-#define MIR_SHARED_LIBRARY_LOADER_H_
1206-
1207-#include <string>
1208-namespace mir
1209-{
1210-class SharedLibrary;
1211-SharedLibrary const* load_library(std::string const& libname);
1212-}
1213-#endif
1214
1215=== modified file 'src/platform/CMakeLists.txt'
1216--- src/platform/CMakeLists.txt 2014-11-27 03:48:20 +0000
1217+++ src/platform/CMakeLists.txt 2014-11-27 07:32:44 +0000
1218@@ -7,20 +7,28 @@
1219
1220 set(MIRPLATFORM_ABI 4)
1221
1222-set(PLATFORM_DRIVER platform${MIRPLATFORM_ABI}driver)
1223-set(MIR_PLATFORM_DRIVER mir${PLATFORM_DRIVER})
1224-set(MIR_PLATFORM_DRIVER_BINARY lib${MIR_PLATFORM_DRIVER}.so
1225- CACHE STRING "File name of Mir server platform drivers")
1226-add_definitions(-DMIR_PLATFORM_DRIVER_BINARY="${MIR_PLATFORM_DRIVER_BINARY}")
1227-
1228 set(symbol_map ${CMAKE_CURRENT_SOURCE_DIR}/symbols.map)
1229
1230-add_library(mirplatformobjects OBJECT
1231- shared_library_loader.cpp
1232-)
1233+# This needs to change whenever the ABI between the platform
1234+# modules and the server changes in an incompatible way.
1235+# This ABI is much smaller than the full libmirplatform ABI.
1236+#
1237+# TODO: Add an extra driver-ABI check target.
1238+set(SERVER_PLATFORM_VERSION "MIR_GRAPHICS_PLATFORM_1")
1239+set(SERVER_PLATFORM_VERSION ${SERVER_PLATFORM_VERSION} PARENT_SCOPE)
1240+
1241+set(MIR_SERVER_PLATFORM_PLUGIN_PATH
1242+ ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/mir/server-platform
1243+)
1244+set(MIR_SERVER_PLATFORM_PLUGIN_PATH
1245+ ${MIR_SERVER_PLATFORM_PLUGIN_PATH}
1246+ PARENT_SCOPE
1247+)
1248+
1249+add_definitions(-DMIR_SERVER_PLATFORM_PLUGIN_PATH="${MIR_SERVER_PLATFORM_PLUGIN_PATH}")
1250+add_definitions(-DSERVER_PLATFORM_VERSION="${SERVER_PLATFORM_VERSION}")
1251
1252 set(MIR_PLATFORM_OBJECTS
1253- $<TARGET_OBJECTS:mirplatformobjects>
1254 $<TARGET_OBJECTS:mirplatformgraphicscommon>
1255 $<TARGET_OBJECTS:miroptions>
1256 $<TARGET_OBJECTS:mirfatal>
1257@@ -39,17 +47,19 @@
1258 )
1259
1260 target_link_libraries(mirplatform
1261+
1262 mircommon
1263 ${MIR_PLATFORM_REFERENCES}
1264 )
1265
1266-set_target_properties(mirplatform
1267+set_target_properties(
1268+ mirplatform
1269+
1270 PROPERTIES
1271 SOVERSION ${MIRPLATFORM_ABI}
1272 LINK_FLAGS "-Wl,--exclude-libs=ALL -Wl,--version-script,${symbol_map}"
1273 )
1274
1275-
1276 install(TARGETS mirplatform LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
1277
1278 add_subdirectory(graphics/)
1279
1280=== modified file 'src/platform/graphics/CMakeLists.txt'
1281--- src/platform/graphics/CMakeLists.txt 2014-11-24 02:16:00 +0000
1282+++ src/platform/graphics/CMakeLists.txt 2014-11-27 07:32:44 +0000
1283@@ -12,6 +12,7 @@
1284 gl_program.cpp
1285 gl_texture.cpp
1286 tessellation_helpers.cpp
1287+ platform_probe.cpp
1288 )
1289
1290 add_library(mirplatformgraphicscommon OBJECT
1291
1292=== modified file 'src/platform/graphics/android/CMakeLists.txt'
1293--- src/platform/graphics/android/CMakeLists.txt 2014-11-24 02:16:00 +0000
1294+++ src/platform/graphics/android/CMakeLists.txt 2014-11-27 07:32:44 +0000
1295@@ -36,20 +36,17 @@
1296 ipc_operations.cpp
1297 buffer_writer.cpp
1298 )
1299+
1300 add_library(mirplatformgraphicsandroid SHARED
1301+
1302 $<TARGET_OBJECTS:mirplatformgraphicsandroidobjects>
1303 )
1304
1305-set_target_properties(
1306- mirplatformgraphicsandroid PROPERTIES
1307- OUTPUT_NAME ${MIR_PLATFORM_DRIVER}
1308- LIBRARY_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH}/android
1309- LINK_FLAGS "-Wl,--exclude-libs=ALL -Wl,--version-script,${symbol_map}"
1310-)
1311+target_link_libraries(
1312+ mirplatformgraphicsandroid
1313
1314-target_link_libraries(mirplatformgraphicsandroid
1315+ mirsharedandroid
1316 mirplatform
1317- mirsharedandroid
1318 ${Boost_PROGRAM_OPTIONS_LIBRARY}
1319 ${LIBHARDWARE_LIBRARIES}
1320 ${EGL_LDFLAGS} ${EGL_LIBRARIES}
1321@@ -57,20 +54,14 @@
1322 ${ANDROID_PROPERTIES_LDFLAGS}
1323 )
1324
1325-install(TARGETS mirplatformgraphicsandroid LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mir/${PLATFORM_DRIVER}/android)
1326-
1327-if (MIR_TEST_PLATFORM STREQUAL "android")
1328- add_custom_command(TARGET mirplatformgraphicsandroid
1329- POST_BUILD
1330- COMMAND ${CMAKE_COMMAND} -E remove ${MIR_PLATFORM_DRIVER_BINARY}
1331- COMMAND ${CMAKE_COMMAND} -E create_symlink android/$<TARGET_FILE_NAME:mirplatformgraphicsandroid> ${MIR_PLATFORM_DRIVER_BINARY}
1332- WORKING_DIRECTORY ${LIBRARY_OUTPUT_PATH}
1333- )
1334-
1335- install(CODE
1336- "execute_process(
1337- COMMAND ln -sf mir/${PLATFORM_DRIVER}/android/${MIR_PLATFORM_DRIVER_BINARY}
1338- WORKING_DIRECTORY \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}
1339- )"
1340- )
1341-endif()
1342+set(symbol_map ${CMAKE_CURRENT_SOURCE_DIR}/symbols.map)
1343+
1344+set_target_properties(
1345+ mirplatformgraphicsandroid PROPERTIES
1346+ OUTPUT_NAME graphics-android
1347+ LIBRARY_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH}/server-modules
1348+ PREFIX ""
1349+ LINK_FLAGS "-Wl,--exclude-libs=ALL -Wl,--version-script,${symbol_map}"
1350+)
1351+
1352+install(TARGETS mirplatformgraphicsandroid LIBRARY DESTINATION ${MIR_SERVER_PLATFORM_PLUGIN_PATH})
1353
1354=== modified file 'src/platform/graphics/android/platform.cpp'
1355--- src/platform/graphics/android/platform.cpp 2014-11-24 02:16:00 +0000
1356+++ src/platform/graphics/android/platform.cpp 2014-11-27 07:32:44 +0000
1357@@ -170,3 +170,22 @@
1358 boost::program_options::value<bool>()->default_value(false),
1359 "[platform-specific] Whether to disable overlay optimizations [{on,off}]");
1360 }
1361+
1362+extern "C" mg::PlatformPriority probe_platform()
1363+{
1364+ int err;
1365+ hw_module_t const* hw_module;
1366+
1367+ err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &hw_module);
1368+
1369+ return err < 0 ? mg::PlatformPriority::unsupported : mg::PlatformPriority::best;
1370+}
1371+
1372+mg::ModuleProperties const description = {
1373+ "android"
1374+};
1375+
1376+extern "C" mg::ModuleProperties const* describe_module()
1377+{
1378+ return &description;
1379+}
1380
1381=== added file 'src/platform/graphics/android/symbols.map'
1382--- src/platform/graphics/android/symbols.map 1970-01-01 00:00:00 +0000
1383+++ src/platform/graphics/android/symbols.map 2014-11-27 07:32:44 +0000
1384@@ -0,0 +1,8 @@
1385+MIR_GRAPHICS_PLATFORM_1 {
1386+ global:
1387+ add_platform_options;
1388+ create_platform;
1389+ create_native_platform;
1390+ probe_platform;
1391+ describe_module;
1392+};
1393
1394=== modified file 'src/platform/graphics/mesa/CMakeLists.txt'
1395--- src/platform/graphics/mesa/CMakeLists.txt 2014-11-24 02:16:00 +0000
1396+++ src/platform/graphics/mesa/CMakeLists.txt 2014-11-27 07:32:44 +0000
1397@@ -11,7 +11,9 @@
1398 string(REPLACE "-pedantic" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
1399 add_definitions(-D__GBM__)
1400
1401-add_library(mirplatformgraphicsmesaobjects OBJECT
1402+add_library(
1403+ mirplatformgraphicsmesaobjects OBJECT
1404+
1405 platform.cpp
1406 buffer_allocator.cpp
1407 gbm_buffer.cpp
1408@@ -36,18 +38,15 @@
1409 nested_authentication.cpp
1410 )
1411
1412-add_library(mirplatformgraphicsmesa SHARED
1413+add_library(
1414+ mirplatformgraphicsmesa MODULE
1415+
1416 $<TARGET_OBJECTS:mirplatformgraphicsmesaobjects>
1417 )
1418
1419-set_target_properties(
1420- mirplatformgraphicsmesa PROPERTIES
1421- OUTPUT_NAME ${MIR_PLATFORM_DRIVER}
1422- LIBRARY_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH}/mesa
1423- LINK_FLAGS "-Wl,--exclude-libs=ALL -Wl,--version-script,${symbol_map}"
1424-)
1425+target_link_libraries(
1426+ mirplatformgraphicsmesa
1427
1428-target_link_libraries(mirplatformgraphicsmesa
1429 mirplatform
1430 ${Boost_PROGRAM_OPTIONS_LIBRARY}
1431 ${DRM_LDFLAGS} ${DRM_LIBRARIES}
1432@@ -56,20 +55,14 @@
1433 ${GLESv2_LDFLAGS} ${GLESv2_LIBRARIES}
1434 )
1435
1436-install(TARGETS mirplatformgraphicsmesa LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mir/${PLATFORM_DRIVER}/mesa)
1437-
1438-if (MIR_TEST_PLATFORM STREQUAL "mesa")
1439- add_custom_command(TARGET mirplatformgraphicsmesa
1440- POST_BUILD
1441- COMMAND ${CMAKE_COMMAND} -E remove ${MIR_PLATFORM_DRIVER_BINARY}
1442- COMMAND ${CMAKE_COMMAND} -E create_symlink mesa/$<TARGET_FILE_NAME:mirplatformgraphicsmesa> ${MIR_PLATFORM_DRIVER_BINARY}
1443- WORKING_DIRECTORY ${LIBRARY_OUTPUT_PATH}
1444- )
1445-
1446- install(CODE
1447- "execute_process(
1448- COMMAND ln -sf mir/${PLATFORM_DRIVER}/mesa/${MIR_PLATFORM_DRIVER_BINARY}
1449- WORKING_DIRECTORY \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}
1450- )"
1451- )
1452-endif()
1453+set(symbol_map ${CMAKE_CURRENT_SOURCE_DIR}/symbols.map)
1454+
1455+set_target_properties(
1456+ mirplatformgraphicsmesa PROPERTIES
1457+ OUTPUT_NAME graphics-mesa
1458+ LIBRARY_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH}/server-modules
1459+ PREFIX ""
1460+ LINK_FLAGS "-Wl,--exclude-libs=ALL -Wl,--version-script,${symbol_map}"
1461+)
1462+
1463+install(TARGETS mirplatformgraphicsmesa LIBRARY DESTINATION ${MIR_SERVER_PLATFORM_PLUGIN_PATH})
1464
1465=== modified file 'src/platform/graphics/mesa/platform.cpp'
1466--- src/platform/graphics/mesa/platform.cpp 2014-11-24 02:16:00 +0000
1467+++ src/platform/graphics/mesa/platform.cpp 2014-11-27 07:32:44 +0000
1468@@ -28,6 +28,7 @@
1469 #include "mir/options/option.h"
1470 #include "mir/graphics/native_buffer.h"
1471 #include "mir/emergency_cleanup_registry.h"
1472+#include "mir/udev/wrapper.h"
1473
1474
1475 #include <boost/throw_exception.hpp>
1476@@ -224,3 +225,30 @@
1477 boost::program_options::value<bool>()->default_value(true),
1478 "[platform-specific] utilize the bypass optimization for fullscreen surfaces.");
1479 }
1480+
1481+extern "C" mg::PlatformPriority probe_platform()
1482+{
1483+ auto udev = std::make_shared<mir::udev::Context>();
1484+
1485+ mir::udev::Enumerator drm_devices{udev};
1486+ drm_devices.match_subsystem("drm");
1487+ drm_devices.match_sysname("card[0-9]*");
1488+ drm_devices.scan_devices();
1489+
1490+ for(auto& device : drm_devices)
1491+ {
1492+ static_cast<void>(device);
1493+ return mg::PlatformPriority::best;
1494+ }
1495+
1496+ return mg::PlatformPriority::unsupported;
1497+}
1498+
1499+mg::ModuleProperties const description = {
1500+ "mesa"
1501+};
1502+
1503+extern "C" mg::ModuleProperties const* describe_module()
1504+{
1505+ return &description;
1506+}
1507
1508=== added file 'src/platform/graphics/mesa/symbols.map'
1509--- src/platform/graphics/mesa/symbols.map 1970-01-01 00:00:00 +0000
1510+++ src/platform/graphics/mesa/symbols.map 2014-11-27 07:32:44 +0000
1511@@ -0,0 +1,8 @@
1512+MIR_GRAPHICS_PLATFORM_1 {
1513+ global:
1514+ add_platform_options;
1515+ create_platform;
1516+ create_native_platform;
1517+ probe_platform;
1518+ describe_module;
1519+};
1520
1521=== added file 'src/platform/graphics/platform_probe.cpp'
1522--- src/platform/graphics/platform_probe.cpp 1970-01-01 00:00:00 +0000
1523+++ src/platform/graphics/platform_probe.cpp 2014-11-27 07:32:44 +0000
1524@@ -0,0 +1,50 @@
1525+/*
1526+ * Copyright © 2014 Canonical Ltd.
1527+ *
1528+ * This program is free software: you can redistribute it and/or modify it
1529+ * under the terms of the GNU Lesser General Public License version 3,
1530+ * as published by the Free Software Foundation.
1531+ *
1532+ * This program is distributed in the hope that it will be useful,
1533+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1534+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1535+ * GNU Lesser General Public License for more details.
1536+ *
1537+ * You should have received a copy of the GNU Lesser General Public License
1538+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1539+ *
1540+ * Authored by: Christopher James Halse Rogers <christopher.halse.rogers@canonical.com>
1541+ */
1542+
1543+#include "mir/graphics/platform.h"
1544+#include "platform_probe.h"
1545+
1546+std::shared_ptr<mir::SharedLibrary>
1547+mir::graphics::module_for_device(std::vector<std::shared_ptr<SharedLibrary>> const& modules)
1548+{
1549+ mir::graphics::PlatformPriority best_priority_so_far = mir::graphics::unsupported;
1550+ std::shared_ptr<mir::SharedLibrary> best_module_so_far;
1551+ for(auto& module : modules)
1552+ {
1553+ try
1554+ {
1555+ auto probe = module->load_function<mir::graphics::PlatformProbe>("probe_platform",
1556+ SERVER_PLATFORM_VERSION);
1557+ auto module_priority = probe();
1558+ if (module_priority > best_priority_so_far)
1559+ {
1560+ best_priority_so_far = module_priority;
1561+ best_module_so_far = module;
1562+ }
1563+ }
1564+ catch (std::runtime_error)
1565+ {
1566+ // Tried to probe a SharedLibrary that isn't a platform module?
1567+ }
1568+ }
1569+ if (best_priority_so_far > mir::graphics::unsupported)
1570+ {
1571+ return best_module_so_far;
1572+ }
1573+ throw std::runtime_error{"Failed to find platform for current system"};
1574+}
1575
1576=== added file 'src/platform/graphics/platform_probe.h'
1577--- src/platform/graphics/platform_probe.h 1970-01-01 00:00:00 +0000
1578+++ src/platform/graphics/platform_probe.h 2014-11-27 07:32:44 +0000
1579@@ -0,0 +1,37 @@
1580+/*
1581+ * Copyright © 2014 Canonical Ltd.
1582+ *
1583+ * This program is free software: you can redistribute it and/or modify it
1584+ * under the terms of the GNU Lesser General Public License version 3,
1585+ * as published by the Free Software Foundation.
1586+ *
1587+ * This program is distributed in the hope that it will be useful,
1588+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1589+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1590+ * GNU Lesser General Public License for more details.
1591+ *
1592+ * You should have received a copy of the GNU Lesser General Public License
1593+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1594+ *
1595+ * Authored by: Christopher James Halse Rogers <christopher.halse.rogers@canonical.com>
1596+ */
1597+
1598+#ifndef MIR_GRAPHICS_PLATFORM_PROBE_H_
1599+#define MIR_GRAPHICS_PLATFORM_PROBE_H_
1600+
1601+#include <vector>
1602+#include <memory>
1603+#include "mir/shared_library.h"
1604+
1605+namespace mir
1606+{
1607+namespace graphics
1608+{
1609+class Platform;
1610+
1611+std::shared_ptr<SharedLibrary> module_for_device(std::vector<std::shared_ptr<SharedLibrary>> const& modules);
1612+
1613+}
1614+}
1615+
1616+#endif // MIR_GRAPHICS_PLATFORM_PROBE_H_
1617
1618=== modified file 'src/platform/options/default_configuration.cpp'
1619--- src/platform/options/default_configuration.cpp 2014-11-24 02:16:00 +0000
1620+++ src/platform/options/default_configuration.cpp 2014-11-27 07:32:44 +0000
1621@@ -17,11 +17,12 @@
1622 */
1623
1624 #include "mir/shared_library.h"
1625-#include "mir/shared_library_loader.h"
1626 #include "mir/options/default_configuration.h"
1627 #include "mir/graphics/platform.h"
1628 #include "mir/default_configuration.h"
1629 #include "mir/abnormal_exit.h"
1630+#include "mir/shared_library_prober.h"
1631+#include "../graphics/platform_probe.h"
1632
1633 #include <dlfcn.h>
1634
1635@@ -53,12 +54,14 @@
1636 char const* const mo::lttng_opt_value = "lttng";
1637
1638 char const* const mo::platform_graphics_lib = "platform-graphics-lib";
1639+char const* const mo::platform_graphics_path = "platform-graphics-path";
1640
1641 namespace
1642 {
1643 int const default_ipc_threads = 1;
1644 bool const enable_input_default = true;
1645-char const* const default_platform_graphics_lib = MIR_PLATFORM_DRIVER_BINARY;
1646+
1647+std::shared_ptr<mir::SharedLibrary> graphics_lib;
1648
1649 // Hack around the way Qt loads mir:
1650 // platform_api and therefore Mir are loaded via dlopen(..., RTLD_LOCAL).
1651@@ -115,8 +118,10 @@
1652 "Socket filename [string:default=$XDG_RUNTIME_DIR/mir_socket or /tmp/mir_socket]")
1653 (no_server_socket_opt, "Do not provide a socket filename for client connections")
1654 (prompt_socket_opt, "Provide a \"..._trusted\" filename for prompt helper connections")
1655- (platform_graphics_lib, po::value<std::string>()->default_value(default_platform_graphics_lib),
1656- "Library to use for platform graphics support")
1657+ (platform_graphics_lib, po::value<std::string>(),
1658+ "Library to use for platform graphics support (default: autodetect)")
1659+ (platform_graphics_path, po::value<std::string>()->default_value(MIR_SERVER_PLATFORM_PLUGIN_PATH),
1660+ "Library to use for platform graphics support (default: " MIR_SERVER_PLATFORM_PLUGIN_PATH ")")
1661 (enable_input_opt, po::value<bool>()->default_value(enable_input_default),
1662 "Enable input.")
1663 (compositor_report_opt, po::value<std::string>()->default_value(off_opt_value),
1664@@ -152,32 +157,74 @@
1665 add_platform_options();
1666 }
1667
1668+namespace
1669+{
1670+class NullSharedLibraryProberReport : public mir::SharedLibraryProberReport
1671+{
1672+public:
1673+ void probing_path(boost::filesystem::path const& /*path*/) override
1674+ {
1675+ }
1676+ void probing_failed(boost::filesystem::path const& /*path*/, std::exception const& /*error*/) override
1677+ {
1678+ }
1679+ void loading_library(boost::filesystem::path const& /*filename*/) override
1680+ {
1681+ }
1682+ void loading_failed(boost::filesystem::path const& /*filename*/, std::exception const& /*error*/) override
1683+ {
1684+ }
1685+};
1686+}
1687+
1688 void mo::DefaultConfiguration::add_platform_options()
1689 {
1690 namespace po = boost::program_options;
1691 po::options_description program_options;
1692 program_options.add_options()
1693 (platform_graphics_lib,
1694- po::value<std::string>()->default_value(default_platform_graphics_lib), "");
1695+ po::value<std::string>(), "");
1696+ program_options.add_options()
1697+ (platform_graphics_path,
1698+ po::value<std::string>()->default_value(MIR_SERVER_PLATFORM_PLUGIN_PATH),
1699+ "");
1700 mo::ProgramOption options;
1701 options.parse_arguments(program_options, argc, argv);
1702
1703- std::string graphics_libname;
1704+ ensure_loaded_with_rtld_global();
1705+
1706+ // TODO: We should just load all the platform plugins we can and present their options.
1707 auto env_libname = ::getenv("MIR_SERVER_PLATFORM_GRAPHICS_LIB");
1708- if (!options.is_set(platform_graphics_lib) && env_libname)
1709- {
1710- graphics_libname = std::string{env_libname};
1711- }
1712- else
1713- {
1714- graphics_libname = options.get<std::string>(platform_graphics_lib);
1715- }
1716-
1717- ensure_loaded_with_rtld_global();
1718-
1719- auto graphics_lib = load_library(graphics_libname);
1720- auto add_platform_options = graphics_lib->load_function<mir::graphics::AddPlatformOptions>(std::string("add_platform_options"));
1721- add_platform_options(*this->program_options);
1722+ auto env_libpath = ::getenv("MIR_SERVER_PLATFORM_GRAPHICS_PATH");
1723+ try
1724+ {
1725+ if (options.is_set(platform_graphics_lib))
1726+ {
1727+ graphics_lib = std::make_shared<mir::SharedLibrary>(options.get<std::string>(platform_graphics_lib));
1728+ }
1729+ else if (env_libname)
1730+ {
1731+ graphics_lib = std::make_shared<mir::SharedLibrary>(std::string{env_libname});
1732+ }
1733+ else
1734+ {
1735+ auto const plugin_path = env_libpath ? env_libpath : options.get<std::string>(platform_graphics_path);
1736+ NullSharedLibraryProberReport nuller;
1737+ auto plugins = mir::libraries_for_path(plugin_path, nuller);
1738+ graphics_lib = mir::graphics::module_for_device(plugins);
1739+ }
1740+
1741+ auto add_platform_options = graphics_lib->load_function<mir::graphics::AddPlatformOptions>(std::string("add_platform_options"));
1742+ add_platform_options(*this->program_options);
1743+ }
1744+ catch(...)
1745+ {
1746+ // We don't actually care at this point if this failed.
1747+ // Maybe we've been pointed at the wrong place. Maybe this platform doesn't actually
1748+ // *have* platform-specific options.
1749+ // Regardless, if we need a platform and can't find one then we'll bail later
1750+ // in startup with a useful error.
1751+ }
1752 }
1753
1754 boost::program_options::options_description_easy_init mo::DefaultConfiguration::add_options()
1755
1756=== modified file 'src/platform/symbols.map'
1757--- src/platform/symbols.map 2014-11-27 03:48:20 +0000
1758+++ src/platform/symbols.map 2014-11-27 07:32:44 +0000
1759@@ -92,6 +92,7 @@
1760 mir::graphics::InternalSurface::pixel_format*;
1761 mir::graphics::InternalSurface::size*;
1762 mir::graphics::InternalSurface::swap_buffers*;
1763+ mir::graphics::module_for_device*;
1764 mir::graphics::NativePlatform::connection_ipc_package*;
1765 mir::graphics::NativePlatform::create_buffer_allocator*;
1766 mir::graphics::NativePlatform::fill_buffer_package*;
1767@@ -147,6 +148,7 @@
1768 mir::options::glog_log_dir*;
1769 mir::options::glog_minloglevel*;
1770 mir::options::glog_stderrthreshold*;
1771+ mir::options::platform_graphics_path*;
1772 mir::options::host_socket_opt*;
1773 mir::options::input_report_opt*;
1774 mir::options::legacy_input_report_opt*;
1775
1776=== modified file 'src/server/CMakeLists.txt'
1777--- src/server/CMakeLists.txt 2014-11-27 03:48:20 +0000
1778+++ src/server/CMakeLists.txt 2014-11-27 07:32:44 +0000
1779@@ -8,6 +8,9 @@
1780 ${GLIB_INCLUDE_DIRS}
1781 )
1782
1783+add_definitions(-DMIR_SERVER_PLATFORM_PLUGIN_PATH="${MIR_SERVER_PLATFORM_PLUGIN_PATH}")
1784+add_definitions(-DSERVER_PLATFORM_VERSION="${SERVER_PLATFORM_VERSION}")
1785+
1786 add_subdirectory(compositor/)
1787 add_subdirectory(graphics/)
1788 add_subdirectory(input/)
1789@@ -71,8 +74,9 @@
1790 )
1791
1792 target_link_libraries(mirserver LINK_PUBLIC
1793+
1794+ mirclient
1795 mirplatform
1796- mirclient
1797 mircommon
1798 mirprotobuf
1799 3rd_party
1800
1801=== modified file 'src/server/graphics/CMakeLists.txt'
1802--- src/server/graphics/CMakeLists.txt 2014-11-24 02:16:00 +0000
1803+++ src/server/graphics/CMakeLists.txt 2014-11-27 07:32:44 +0000
1804@@ -1,4 +1,4 @@
1805-include_directories(${GLESv2_INCLUDE_DIRS})
1806+include_directories(${GLESv2_INCLUDE_DIRS} ${PROJECT_SOURCE_DIR})
1807
1808 add_library(
1809 mirgraphics OBJECT
1810
1811=== modified file 'src/server/graphics/default_configuration.cpp'
1812--- src/server/graphics/default_configuration.cpp 2014-11-27 03:48:20 +0000
1813+++ src/server/graphics/default_configuration.cpp 2014-11-27 07:32:44 +0000
1814@@ -28,12 +28,14 @@
1815
1816 #include "mir/graphics/gl_config.h"
1817 #include "mir/graphics/cursor.h"
1818+#include "src/platform/graphics/platform_probe.h"
1819 #include "program_factory.h"
1820
1821 #include "mir/shared_library.h"
1822-#include "mir/shared_library_loader.h"
1823+#include "mir/shared_library_prober.h"
1824 #include "mir/abnormal_exit.h"
1825 #include "mir/emergency_cleanup.h"
1826+#include "mir/logging/logger.h"
1827
1828 #include "mir_toolkit/common.h"
1829
1830@@ -44,6 +46,12 @@
1831 namespace mg = mir::graphics;
1832 namespace mgn = mir::graphics::nested;
1833
1834+namespace
1835+{
1836+// TODO: Temporary, until we actually manage module lifetimes
1837+static std::shared_ptr<mir::SharedLibrary> platform_library;
1838+}
1839+
1840 std::shared_ptr<mg::DisplayConfigurationPolicy>
1841 mir::DefaultServerConfiguration::the_display_configuration_policy()
1842 {
1843@@ -62,6 +70,32 @@
1844 return wrapped;
1845 }
1846
1847+namespace
1848+{
1849+namespace ml = mir::logging;
1850+
1851+class LoggingSharedLibraryReport : public mir::SharedLibraryProberReport
1852+{
1853+public:
1854+ void probing_path(boost::filesystem::path const& path) override
1855+ {
1856+ ml::log(ml::Severity::informational, std::string{"Scanning for platform libraries in "} + path.c_str(), "Platform Loader");
1857+ }
1858+ void probing_failed(boost::filesystem::path const& path, std::exception const& error) override
1859+ {
1860+ ml::log(ml::Severity::warning, std::string{"Failed to scan "} + path.c_str() + ": " + error.what(), "Platform Loader");
1861+ }
1862+ void loading_library(boost::filesystem::path const& filename) override
1863+ {
1864+ ml::log(ml::Severity::informational, std::string{"Loading library "} + filename.c_str(), "Platform Loader");
1865+ }
1866+ void loading_failed(boost::filesystem::path const& filename, std::exception const& error) override
1867+ {
1868+ ml::log(ml::Severity::warning, std::string{"Failed to load "} + filename.c_str() + ": " + error.what(), "Platform Loader");
1869+ }
1870+};
1871+}
1872+
1873
1874 std::shared_ptr<mg::Platform> mir::DefaultServerConfiguration::the_graphics_platform()
1875 {
1876@@ -71,8 +105,22 @@
1877 if (!the_options()->is_set(options::host_socket_opt))
1878 {
1879 // fallback to standalone if host socket is unset
1880- auto graphics_lib = mir::load_library(the_options()->get<std::string>(options::platform_graphics_lib));
1881- auto create_platform = graphics_lib->load_function<mg::CreatePlatform>("create_platform");
1882+ if (the_options()->is_set(options::platform_graphics_lib))
1883+ {
1884+ platform_library = std::make_shared<mir::SharedLibrary>(the_options()->get<std::string>(options::platform_graphics_lib));
1885+ }
1886+ else
1887+ {
1888+ LoggingSharedLibraryReport report;
1889+ auto platforms = mir::libraries_for_path(the_options()->get<std::string>(options::platform_graphics_path), report);
1890+ if (platforms.empty())
1891+ {
1892+ throw std::runtime_error("Failed to find any platform plugins in: " MIR_SERVER_PLATFORM_PLUGIN_PATH);
1893+ }
1894+ platform_library = mir::graphics::module_for_device(platforms);
1895+ }
1896+ auto create_platform = platform_library->load_function<mg::CreatePlatform>("create_platform",
1897+ SERVER_PLATFORM_VERSION);
1898 return create_platform(the_options(), the_emergency_cleanup(), the_display_report());
1899 }
1900
1901@@ -121,8 +169,23 @@
1902 return graphics_native_platform(
1903 [this]()
1904 {
1905- auto graphics_lib = mir::load_library(the_options()->get<std::string>(options::platform_graphics_lib));
1906- auto create_native_platform = graphics_lib->load_function<mg::CreateNativePlatform>("create_native_platform");
1907+ if (the_options()->is_set(options::platform_graphics_lib))
1908+ {
1909+ platform_library = std::make_shared<mir::SharedLibrary>(the_options()->get<std::string>(options::platform_graphics_lib));
1910+ }
1911+ else
1912+ {
1913+ LoggingSharedLibraryReport report;
1914+ auto platforms = mir::libraries_for_path(the_options()->get<std::string>(options::platform_graphics_path), report);
1915+ if (platforms.empty())
1916+ {
1917+ throw std::runtime_error("Failed to find any platform plugins in: " MIR_SERVER_PLATFORM_PLUGIN_PATH);
1918+ }
1919+ platform_library = mir::graphics::module_for_device(platforms);
1920+ }
1921+ auto create_native_platform = platform_library->load_function<mg::CreateNativePlatform>("create_native_platform",
1922+ SERVER_PLATFORM_VERSION);
1923+
1924 auto context = std::make_shared<MirConnectionNestedContext>(the_host_connection());
1925 return create_native_platform(the_display_report(), context);
1926 });
1927
1928=== modified file 'src/server/server.cpp'
1929--- src/server/server.cpp 2014-11-21 09:49:05 +0000
1930+++ src/server/server.cpp 2014-11-27 07:32:44 +0000
1931@@ -186,7 +186,7 @@
1932 {
1933 auto const graphics_lib = the_options()->get<std::string>(options::platform_graphics_lib);
1934
1935- if (graphics_lib != "libmirplatformstub.so")
1936+ if (graphics_lib.find("graphics-dummy.so") == std::string::npos)
1937 return mir::DefaultServerConfiguration::the_renderer_factory();
1938 else
1939 return std::make_shared<StubRendererFactory>();
1940
1941=== modified file 'tests/acceptance-tests/CMakeLists.txt'
1942--- tests/acceptance-tests/CMakeLists.txt 2014-11-27 03:48:20 +0000
1943+++ tests/acceptance-tests/CMakeLists.txt 2014-11-27 07:32:44 +0000
1944@@ -4,11 +4,6 @@
1945 ${CMAKE_SOURCE_DIR}
1946 )
1947
1948-add_definitions(
1949- -DMIR_PLATFORM_DRIVER_BINARY="${MIR_PLATFORM_DRIVER_BINARY}"
1950- -DMIR_CLIENT_DRIVER_BINARY="${MIR_CLIENT_DRIVER_BINARY}"
1951-)
1952-
1953 set(
1954 SOURCES
1955
1956
1957=== modified file 'tests/acceptance-tests/server_configuration_wrapping.cpp'
1958--- tests/acceptance-tests/server_configuration_wrapping.cpp 2014-11-06 03:56:24 +0000
1959+++ tests/acceptance-tests/server_configuration_wrapping.cpp 2014-11-27 07:32:44 +0000
1960@@ -21,11 +21,14 @@
1961
1962 #include "mir_test_framework/headless_test.h"
1963
1964+#include "mir_test_framework/executable_path.h"
1965+
1966 #include <gtest/gtest.h>
1967 #include <gmock/gmock.h>
1968
1969 namespace ms = mir::scene;
1970 namespace msh = mir::shell;
1971+namespace mtf = mir_test_framework;
1972
1973 using namespace testing;
1974
1975
1976=== modified file 'tests/acceptance-tests/test_symbols_required_by_mesa.cpp'
1977--- tests/acceptance-tests/test_symbols_required_by_mesa.cpp 2014-11-24 02:16:00 +0000
1978+++ tests/acceptance-tests/test_symbols_required_by_mesa.cpp 2014-11-27 07:32:44 +0000
1979@@ -21,11 +21,14 @@
1980
1981 #include <dlfcn.h>
1982
1983+#include "mir_test_framework/executable_path.h"
1984+
1985 using namespace testing;
1986+namespace mtf = mir_test_framework;
1987
1988-TEST(SymbolsRequiredByMesa, are_exported_by_libmirclientplatform)
1989+TEST(SymbolsRequiredByMesa, are_exported_by_client_platform_mesa)
1990 {
1991- auto const handle = dlopen(MIR_CLIENT_DRIVER_BINARY, RTLD_LAZY);
1992+ auto const handle = dlopen((mtf::library_path() + "/client-modules/mesa.so").c_str(), RTLD_LAZY);
1993 ASSERT_THAT(handle, NotNull());
1994
1995 auto const sym = dlsym(handle, "mir_client_mesa_egl_native_display_is_valid");
1996@@ -36,7 +39,7 @@
1997
1998 TEST(SymbolsRequiredByMesa, are_exported_by_libmirplatformgraphics)
1999 {
2000- auto const handle = dlopen(MIR_PLATFORM_DRIVER_BINARY, RTLD_LAZY);
2001+ auto const handle = dlopen((mtf::library_path() + "/server-modules/graphics-mesa.so").c_str(), RTLD_LAZY);
2002 ASSERT_THAT(handle, NotNull());
2003
2004 auto const sym = dlsym(handle, "mir_server_mesa_egl_native_display_is_valid");
2005
2006=== modified file 'tests/include/mir_test_doubles/mock_android_alloc_device.h'
2007--- tests/include/mir_test_doubles/mock_android_alloc_device.h 2013-06-18 08:00:49 +0000
2008+++ tests/include/mir_test_doubles/mock_android_alloc_device.h 2014-11-27 07:32:44 +0000
2009@@ -19,7 +19,11 @@
2010 #define MIR_TEST_DOUBLES_MOCK_ANDROID_ALLOC_DEVICE_H_
2011
2012 #include <gmock/gmock.h>
2013+#pragma GCC diagnostic push
2014+#pragma GCC diagnostic ignored "-Wpedantic"
2015+#pragma GCC diagnostic ignored "-Wunused-parameter"
2016 #include <hardware/gralloc.h>
2017+#pragma GCC diagnostic pop
2018
2019 namespace mir
2020 {
2021
2022=== modified file 'tests/include/mir_test_doubles/mock_client_context.h'
2023--- tests/include/mir_test_doubles/mock_client_context.h 2013-04-24 05:22:20 +0000
2024+++ tests/include/mir_test_doubles/mock_client_context.h 2014-11-27 07:32:44 +0000
2025@@ -33,18 +33,12 @@
2026 struct MockClientContext : public client::ClientContext
2027 {
2028 MockClientContext()
2029- : connection{reinterpret_cast<MirConnection*>(0xabcdef)}
2030 {
2031 using namespace testing;
2032
2033- ON_CALL(*this, mir_connection()).WillByDefault(Return(connection));
2034- EXPECT_CALL(*this, mir_connection()).Times(AtLeast(0));
2035 EXPECT_CALL(*this, populate(_)).Times(AtLeast(0));
2036 }
2037
2038- MirConnection* connection;
2039-
2040- MOCK_METHOD0(mir_connection, MirConnection*());
2041 MOCK_METHOD1(populate, void(MirPlatformPackage&));
2042 };
2043
2044
2045=== modified file 'tests/include/mir_test_doubles/mock_hwc_composer_device_1.h'
2046--- tests/include/mir_test_doubles/mock_hwc_composer_device_1.h 2014-03-27 06:27:59 +0000
2047+++ tests/include/mir_test_doubles/mock_hwc_composer_device_1.h 2014-11-27 07:32:44 +0000
2048@@ -19,7 +19,12 @@
2049 #ifndef MIR_TEST_DOUBLES_MOCK_HWC_COMPOSER_DEVICE_1_H_
2050 #define MIR_TEST_DOUBLES_MOCK_HWC_COMPOSER_DEVICE_1_H_
2051
2052+#pragma GCC diagnostic push
2053+#pragma GCC diagnostic ignored "-Wpedantic"
2054+#pragma GCC diagnostic ignored "-Wunused-parameter"
2055 #include <hardware/hwcomposer.h>
2056+#pragma GCC diagnostic pop
2057+
2058 #include <gmock/gmock.h>
2059
2060 namespace mir
2061
2062=== added file 'tests/include/mir_test_framework/client_platform_factory.h'
2063--- tests/include/mir_test_framework/client_platform_factory.h 1970-01-01 00:00:00 +0000
2064+++ tests/include/mir_test_framework/client_platform_factory.h 2014-11-27 07:32:44 +0000
2065@@ -0,0 +1,72 @@
2066+/*
2067+ * Copyright © 2014 Canonical Ltd.
2068+ *
2069+ * This program is free software: you can redistribute it and/or modify
2070+ * it under the terms of the GNU General Public License version 3 as
2071+ * published by the Free Software Foundation.
2072+ *
2073+ * This program is distributed in the hope that it will be useful,
2074+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2075+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2076+ * GNU General Public License for more details.
2077+ *
2078+ * You should have received a copy of the GNU General Public License
2079+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2080+ *
2081+ * Authored by: Christopher James Halse Rogers <christopher.halse.rogers@canonical.com>
2082+ */
2083+
2084+#ifndef MIR_TEST_FRAMEWORK_CLIENT_PLATFORM_FACTORY_H_
2085+#define MIR_TEST_FRAMEWORK_CLIENT_PLATFORM_FACTORY_H_
2086+
2087+
2088+#include "mir/shared_library.h"
2089+#include "src/client/client_platform_factory.h"
2090+#include "executable_path.h"
2091+#include "mir_test_doubles/mock_client_context.h"
2092+
2093+namespace mtd = mir::test::doubles;
2094+
2095+namespace mir_test_framework
2096+{
2097+std::shared_ptr<mir::SharedLibrary> platform_library;
2098+
2099+std::shared_ptr<mir::client::ClientPlatform> create_android_client_platform()
2100+{
2101+ using namespace testing;
2102+ mtd::MockClientContext ctx;
2103+ ON_CALL(ctx, populate(_))
2104+ .WillByDefault(Invoke([](MirPlatformPackage& package) { ::memset(&package, 0, sizeof(package)); }));
2105+ platform_library = std::make_shared<mir::SharedLibrary>(library_path() + "/client-modules/android.so");
2106+ auto platform_factory = platform_library->load_function<mir::client::CreateClientPlatform>("create_client_platform");
2107+ return platform_factory(&ctx);
2108+}
2109+
2110+std::shared_ptr<mir::client::ClientPlatform> create_mesa_client_platform()
2111+{
2112+ using namespace testing;
2113+ mtd::MockClientContext ctx;
2114+ ON_CALL(ctx, populate(_))
2115+ .WillByDefault(Invoke([](MirPlatformPackage& package)
2116+ {
2117+ ::memset(&package, 0, sizeof(package));
2118+ package.fd_items = 1;
2119+ }));
2120+ platform_library = std::make_shared<mir::SharedLibrary>(library_path() + "/client-modules/mesa.so");
2121+ auto platform_factory = platform_library->load_function<mir::client::CreateClientPlatform>("create_client_platform");
2122+ return platform_factory(&ctx);
2123+}
2124+
2125+std::shared_ptr<mir::SharedLibrary>
2126+get_platform_library()
2127+{
2128+ if (!platform_library)
2129+ {
2130+ throw std::logic_error{"Must call one of create_*_client_platform() before calling get_platform_library()"};
2131+ }
2132+ return platform_library;
2133+}
2134+
2135+}
2136+
2137+#endif // MIR_TEST_FRAMEWORK_CLIENT_PLATFORM_FACTORY_H_
2138
2139=== added file 'tests/include/mir_test_framework/stub_client_platform_factory.h'
2140--- tests/include/mir_test_framework/stub_client_platform_factory.h 1970-01-01 00:00:00 +0000
2141+++ tests/include/mir_test_framework/stub_client_platform_factory.h 2014-11-27 07:32:44 +0000
2142@@ -0,0 +1,33 @@
2143+/*
2144+ * Copyright © 2014 Canonical Ltd.
2145+ *
2146+ * This program is free software: you can redistribute it and/or modify it
2147+ * under the terms of the GNU General Public License version 3,
2148+ * as published by the Free Software Foundation.
2149+ *
2150+ * This program is distributed in the hope that it will be useful,
2151+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2152+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2153+ * GNU General Public License for more details.
2154+ *
2155+ * You should have received a copy of the GNU General Public License
2156+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2157+ *
2158+ * Authored by: Christopher James Halse Rogers <christopher.halse.rogers@canonical.com>
2159+ */
2160+
2161+#ifndef MIR_TEST_FRAMEWORK_STUB_CLIENT_PLATFORM_FACTORY_
2162+#define MIR_TEST_FRAMEWORK_STUB_CLIENT_PLATFORM_FACTORY_
2163+
2164+#include "src/client/client_platform_factory.h"
2165+
2166+namespace mir_test_framework
2167+{
2168+
2169+struct StubClientPlatformFactory : public mir::client::ClientPlatformFactory
2170+{
2171+ std::shared_ptr<mir::client::ClientPlatform> create_client_platform(mir::client::ClientContext* context) override;
2172+};
2173+
2174+}
2175+#endif /* MIR_TEST_FRAMEWORK_STUB_CLIENT_PLATFORM_ */
2176
2177=== added file 'tests/include/mir_test_framework/stub_server_platform_factory.h'
2178--- tests/include/mir_test_framework/stub_server_platform_factory.h 1970-01-01 00:00:00 +0000
2179+++ tests/include/mir_test_framework/stub_server_platform_factory.h 2014-11-27 07:32:44 +0000
2180@@ -0,0 +1,45 @@
2181+/*
2182+ * Copyright © 2014 Canonical Ltd.
2183+ *
2184+ * This program is free software: you can redistribute it and/or modify it
2185+ * under the terms of the GNU General Public License version 3,
2186+ * as published by the Free Software Foundation.
2187+ *
2188+ * This program is distributed in the hope that it will be useful,
2189+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2190+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2191+ * GNU General Public License for more details.
2192+ *
2193+ * You should have received a copy of the GNU General Public License
2194+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2195+ *
2196+ * Authored by: Christopher James Halse Rogers <christopher.halse.rogers@canonical.com>
2197+ */
2198+
2199+#ifndef MIR_TEST_FRAMEWORK_STUB_SERVER_PLATFORM_FACTORY_
2200+#define MIR_TEST_FRAMEWORK_STUB_SERVER_PLATFORM_FACTORY_
2201+
2202+#include "mir/geometry/rectangle.h"
2203+
2204+#include "mir/graphics/platform.h"
2205+#include <vector>
2206+
2207+namespace geom = mir::geometry;
2208+
2209+namespace mir
2210+{
2211+namespace graphics
2212+{
2213+class Platform;
2214+}
2215+}
2216+
2217+namespace mg = mir::graphics;
2218+
2219+namespace mir_test_framework
2220+{
2221+
2222+std::shared_ptr<mg::Platform> make_stubbed_server_graphics_platform(std::vector<geom::Rectangle> const& display_rects);
2223+
2224+}
2225+#endif /* MIR_TEST_FRAMEWORK_STUB_SERVER_PLATFORM_FACTORY_ */
2226
2227=== modified file 'tests/integration-tests/CMakeLists.txt'
2228--- tests/integration-tests/CMakeLists.txt 2014-11-27 03:48:20 +0000
2229+++ tests/integration-tests/CMakeLists.txt 2014-11-27 07:32:44 +0000
2230@@ -99,6 +99,15 @@
2231 ${GTEST_BOTH_LIBRARIES}
2232 ${GMOCK_LIBRARY}
2233 ${GMOCK_MAIN_LIBRARY}
2234+ # Mesa platform dependencies
2235+ ${DRM_LDFLAGS} ${DRM_LIBRARIES}
2236+ ${GBM_LDFLAGS} ${GBM_LIBRARIES}
2237+ # Android platform dependencies
2238+ ${LIBHARDWARE_LIBRARIES}
2239+ ${ANDROID_PROPERTIES_LIBRARIES}
2240+ # Shared platform dependencies
2241+ ${EGL_LDFLAGS} ${EGL_LIBRARIES}
2242+ ${GLESv2_LDFLAGS} ${GLESv2_LIBRARIES}
2243 ${CMAKE_THREAD_LIBS_INIT} # Link in pthread.
2244 ${DRM_LDFLAGS} ${DRM_LIBRARIES}
2245 ${GBM_LDFLAGS} ${GBM_LIBRARIES}
2246@@ -108,7 +117,7 @@
2247 ${MIR_SERVER_REFERENCES}
2248 )
2249
2250-if (MIR_TEST_PLATFORM STREQUAL "android")
2251+if (MIR_BUILD_PLATFORM_ANDROID)
2252 target_link_libraries(mir_integration_tests
2253 mirsharedandroid
2254 ${ANDROID_PROPERTIES_LDFLAGS}
2255@@ -122,8 +131,18 @@
2256 "MIR_BUILD_INTEGRATION_TESTS"
2257 OFF)
2258
2259+set (MIR_CLIENT_MODULE "client-modules/dummy.so")
2260+
2261+if (MIR_TEST_PLATFORM STREQUAL "android")
2262+ # Android platform integration tests have Android-specific tests
2263+ # requiring a real platform
2264+ set (MIR_CLIENT_MODULE "client-modules/android.so")
2265+endif()
2266+
2267 if (MIR_RUN_INTEGRATION_TESTS)
2268- mir_discover_tests(mir_integration_tests)
2269+ mir_discover_tests(mir_integration_tests
2270+ MIR_CLIENT_PLATFORM_LIB=${LIBRARY_OUTPUT_PATH}/${MIR_CLIENT_MODULE}
2271+ )
2272 endif (MIR_RUN_INTEGRATION_TESTS)
2273
2274 install(
2275
2276=== modified file 'tests/mir_test_doubles/CMakeLists.txt'
2277--- tests/mir_test_doubles/CMakeLists.txt 2014-11-24 02:16:00 +0000
2278+++ tests/mir_test_doubles/CMakeLists.txt 2014-11-27 07:32:44 +0000
2279@@ -30,16 +30,19 @@
2280 ${CMAKE_CURRENT_SOURCE_DIR}/mock_gl.cpp
2281 )
2282
2283-if (MIR_TEST_PLATFORM STREQUAL "mesa")
2284-include_directories(${DRM_INCLUDE_DIRS} ${GBM_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR})
2285-list(APPEND MIR_TEST_DOUBLES_PLATFORM_SRCS
2286- ${CMAKE_CURRENT_SOURCE_DIR}/mock_drm.cpp
2287- ${CMAKE_CURRENT_SOURCE_DIR}/mock_gbm.cpp
2288-)
2289-elseif (MIR_TEST_PLATFORM STREQUAL "android")
2290-list(APPEND MIR_TEST_DOUBLES_PLATFORM_SRCS
2291- ${CMAKE_CURRENT_SOURCE_DIR}/mock_android_hw.cpp
2292-)
2293+if (MIR_BUILD_PLATFORM_MESA)
2294+ include_directories(${DRM_INCLUDE_DIRS} ${GBM_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR})
2295+ list(APPEND MIR_TEST_DOUBLES_PLATFORM_SRCS
2296+ ${CMAKE_CURRENT_SOURCE_DIR}/mock_drm.cpp
2297+ ${CMAKE_CURRENT_SOURCE_DIR}/mock_gbm.cpp
2298+ )
2299+endif()
2300+
2301+if (MIR_BUILD_PLATFORM_ANDROID)
2302+ include_directories(${ANDROID_HEADERS_INCLUDE_DIRS})
2303+ list(APPEND MIR_TEST_DOUBLES_PLATFORM_SRCS
2304+ ${CMAKE_CURRENT_SOURCE_DIR}/mock_android_hw.cpp
2305+ )
2306 endif()
2307
2308 add_library(
2309
2310=== modified file 'tests/mir_test_framework/CMakeLists.txt'
2311--- tests/mir_test_framework/CMakeLists.txt 2014-11-24 02:16:00 +0000
2312+++ tests/mir_test_framework/CMakeLists.txt 2014-11-27 07:32:44 +0000
2313@@ -4,10 +4,11 @@
2314 ${PROJECT_SOURCE_DIR}/src/include/common
2315 ${PROJECT_SOURCE_DIR}/src/include/server
2316 ${PROJECT_SOURCE_DIR}/src/include/client
2317- ${Boost_INCLUDE_DIRS}
2318- ${GLESv2_INCLUDE_DIRS}
2319- ${CMAKE_SOURCE_DIR}
2320- ${UMOCKDEV_INCLUDE_DIRS}
2321+ ${Boost_INCLUDE_DIRS}
2322+ ${GLESv2_INCLUDE_DIRS}
2323+ ${CMAKE_SOURCE_DIR}
2324+ ${UMOCKDEV_INCLUDE_DIRS}
2325+ ${ANDROID_HEADERS_INCLUDE_DIRS}
2326 )
2327
2328 set(
2329@@ -31,6 +32,8 @@
2330 display_server_test_fixture.cpp
2331 process.cpp
2332 using_stub_client_platform.cpp
2333+ stub_client_platform_factory.cpp
2334+ stub_server_platform_factory.cpp
2335 udev_environment.cpp
2336 declarative_placement_strategy.cpp
2337 fake_event_hub_server_configuration.cpp
2338@@ -55,7 +58,6 @@
2339 target_link_libraries(
2340 mir-test-framework
2341
2342- mirplatformstub
2343 3rd_party
2344
2345 ${PROTOBUF_LIBRARIES}
2346@@ -67,6 +69,53 @@
2347 ${CMAKE_THREAD_LIBS_INIT} # Link in pthread.
2348 )
2349
2350+set(symbol_map ${CMAKE_CURRENT_SOURCE_DIR}/symbols-client.map)
2351+
2352+add_library(
2353+ mirclientplatformstub MODULE
2354+
2355+ stub_client_platform_module.cpp
2356+)
2357+
2358+target_link_libraries(
2359+ mirclientplatformstub
2360+
2361+ mir-test-framework
2362+ ${UMOCKDEV_LDFLAGS} ${UMOCKDEV_LIBRARIES}
2363+)
2364+
2365+set_target_properties(
2366+ mirclientplatformstub PROPERTIES;
2367+ LIBRARY_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH}/client-modules
2368+ OUTPUT_NAME dummy
2369+ PREFIX ""
2370+ LINK_FLAGS "-Wl,--version-script,${symbol_map}"
2371+)
2372+install(TARGETS mirclientplatformstub LIBRARY DESTINATION ${MIR_CLIENT_PLATFORM_PATH})
2373+
2374+set(server_symbol_map ${CMAKE_CURRENT_SOURCE_DIR}/symbols-server.map)
2375+add_library(
2376+ mirplatformgraphicsstub MODULE
2377+
2378+ platform_graphics_dummy.cpp
2379+ stubbed_graphics_platform.cpp
2380+)
2381+
2382+target_link_libraries(
2383+ mirplatformgraphicsstub
2384+
2385+ mir-test-framework
2386+)
2387+
2388+set_target_properties(
2389+ mirplatformgraphicsstub PROPERTIES;
2390+ LIBRARY_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH}/server-modules
2391+ OUTPUT_NAME graphics-dummy
2392+ PREFIX ""
2393+ LINK_FLAGS "-Wl,--version-script,${server_symbol_map}"
2394+)
2395+install(TARGETS mirplatformgraphicsstub LIBRARY DESTINATION ${MIR_SERVER_PLATFORM_PLUGIN_PATH})
2396+
2397 add_custom_command(TARGET mir-test-framework POST_BUILD
2398 COMMAND ${CMAKE_COMMAND} -E copy_directory
2399 ${CMAKE_CURRENT_SOURCE_DIR}/udev_recordings ${CMAKE_BINARY_DIR}/bin/udev_recordings
2400@@ -79,19 +128,3 @@
2401 )
2402
2403 string (REPLACE " -Wl,--no-undefined" " " CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS})
2404-
2405-add_library(
2406- mirplatformstub SHARED
2407- stubbed_graphics_platform.cpp
2408-)
2409-
2410-target_link_libraries(mirplatformstub
2411- mir-test-doubles
2412-)
2413-
2414-set_target_properties(mirplatformstub
2415- PROPERTIES
2416- LINK_FLAGS "-Wl,--exclude-libs=ALL"
2417-)
2418-
2419-install(TARGETS mirplatformstub LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
2420
2421=== modified file 'tests/mir_test_framework/headless_test.cpp'
2422--- tests/mir_test_framework/headless_test.cpp 2014-11-25 12:05:51 +0000
2423+++ tests/mir_test_framework/headless_test.cpp 2014-11-27 07:32:44 +0000
2424@@ -25,6 +25,7 @@
2425 #include "mir/geometry/rectangle.h"
2426 #include "mir/options/option.h"
2427 #include "mir_test_doubles/null_logger.h"
2428+#include "mir_test_framework/executable_path.h"
2429
2430 #include <boost/throw_exception.hpp>
2431
2432@@ -35,15 +36,24 @@
2433
2434 namespace
2435 {
2436+<<<<<<< TREE
2437 const char* const mir_server_platform_graphics_lib = "MIR_SERVER_PLATFORM_GRAPHICS_LIB";
2438
2439 std::chrono::seconds const timeout{10};
2440+=======
2441+std::chrono::seconds const timeout{100000};
2442+>>>>>>> MERGE-SOURCE
2443 }
2444
2445 mtf::HeadlessTest::HeadlessTest()
2446 {
2447 configure_from_commandline(server);
2448+<<<<<<< TREE
2449 add_to_environment(mir_server_platform_graphics_lib, "libmirplatformstub.so");
2450+=======
2451+ add_to_environment("MIR_SERVER_PLATFORM_GRAPHICS_LIB", (mtf::library_path() + "/server-modules/graphics-dummy.so").c_str());
2452+ add_to_environment("MIR_CLIENT_PLATFORM_PATH", (mtf::library_path() + "/client-modules/").c_str());
2453+>>>>>>> MERGE-SOURCE
2454 server.add_configuration_option(mtd::logging_opt, mtd::logging_descr, false);
2455 server.override_the_logger([&]()
2456 {
2457
2458=== added file 'tests/mir_test_framework/platform_graphics_dummy.cpp'
2459--- tests/mir_test_framework/platform_graphics_dummy.cpp 1970-01-01 00:00:00 +0000
2460+++ tests/mir_test_framework/platform_graphics_dummy.cpp 2014-11-27 07:32:44 +0000
2461@@ -0,0 +1,33 @@
2462+/*
2463+ * Copyright © 2014 Canonical Ltd.
2464+ *
2465+ * This program is free software: you can redistribute it and/or modify it
2466+ * under the terms of the GNU General Public License version 3,
2467+ * as published by the Free Software Foundation.
2468+ *
2469+ * This program is distributed in the hope that it will be useful,
2470+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2471+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2472+ * GNU General Public License for more details.
2473+ *
2474+ * You should have received a copy of the GNU General Public License
2475+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2476+ *
2477+ * Authored by: Christopher James Halse Rogers <christopher.halse.rogers@canonical.com>>
2478+ */
2479+
2480+#include "mir/graphics/platform.h"
2481+
2482+extern "C" mir::graphics::PlatformPriority probe_platform()
2483+{
2484+ return mir::graphics::supported;
2485+}
2486+
2487+mir::graphics::ModuleProperties const description {
2488+ "dummy"
2489+};
2490+
2491+extern "C" mir::graphics::ModuleProperties const* describe_module()
2492+{
2493+ return &description;
2494+}
2495
2496=== added file 'tests/mir_test_framework/stub_client_platform_factory.cpp'
2497--- tests/mir_test_framework/stub_client_platform_factory.cpp 1970-01-01 00:00:00 +0000
2498+++ tests/mir_test_framework/stub_client_platform_factory.cpp 2014-11-27 07:32:44 +0000
2499@@ -0,0 +1,147 @@
2500+/*
2501+ * Copyright © 2014 Canonical Ltd.
2502+ *
2503+ * This program is free software: you can redistribute it and/or modify it
2504+ * under the terms of the GNU General Public License version 3,
2505+ * as published by the Free Software Foundation.
2506+ *
2507+ * This program is distributed in the hope that it will be useful,
2508+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2509+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2510+ * GNU General Public License for more details.
2511+ *
2512+ * You should have received a copy of the GNU General Public License
2513+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2514+ *
2515+ * Authored by: Christopher James Halse Rogers <christopher.halse.rogers@canonical.com>
2516+ */
2517+
2518+#include "mir_test_framework/stub_client_platform_factory.h"
2519+#include "src/client/client_buffer_factory.h"
2520+#include "src/client/client_buffer.h"
2521+#include "src/client/client_platform.h"
2522+
2523+#include <string.h>
2524+
2525+namespace mcl = mir::client;
2526+namespace geom = mir::geometry;
2527+namespace mtf = mir_test_framework;
2528+
2529+namespace
2530+{
2531+class StubClientBuffer : public mcl::ClientBuffer
2532+{
2533+public:
2534+ StubClientBuffer(std::shared_ptr<MirBufferPackage> const& package)
2535+ {
2536+ static_cast<void>(package);
2537+#ifndef ANDROID
2538+ native = package;
2539+#endif
2540+ }
2541+
2542+ std::shared_ptr<mcl::MemoryRegion> secure_for_cpu_write()
2543+ {
2544+ return nullptr;
2545+ }
2546+
2547+ geom::Size size() const
2548+ {
2549+ return geom::Size{};
2550+ }
2551+
2552+ geom::Stride stride() const
2553+ {
2554+ return geom::Stride{};
2555+ }
2556+
2557+ MirPixelFormat pixel_format() const
2558+ {
2559+ return mir_pixel_format_abgr_8888;
2560+ }
2561+
2562+ uint32_t age() const
2563+ {
2564+ return 0;
2565+ }
2566+ void increment_age()
2567+ {
2568+ }
2569+ void mark_as_submitted()
2570+ {
2571+ }
2572+ std::shared_ptr<mir::graphics::NativeBuffer> native_buffer_handle() const
2573+ {
2574+#ifdef ANDROID
2575+ return nullptr;
2576+#else
2577+ return native;
2578+#endif
2579+ }
2580+ void update_from(MirBufferPackage const& package) override
2581+ {
2582+ static_cast<void>(package);
2583+#ifndef ANDROID
2584+ ::memcpy(native.get(), &package, sizeof(package));
2585+#endif
2586+ }
2587+private:
2588+#ifndef ANDROID
2589+ std::shared_ptr<mir::graphics::NativeBuffer> native;
2590+#endif
2591+
2592+ virtual void fill_update_msg(MirBufferPackage& /*message*/) override
2593+ {
2594+ }
2595+};
2596+
2597+struct StubClientBufferFactory : public mcl::ClientBufferFactory
2598+{
2599+ std::shared_ptr<mcl::ClientBuffer> create_buffer(std::shared_ptr<MirBufferPackage> const& package,
2600+ geom::Size, MirPixelFormat)
2601+ {
2602+ return std::make_shared<StubClientBuffer>(package);
2603+ }
2604+};
2605+
2606+struct StubClientPlatform : public mcl::ClientPlatform
2607+{
2608+ MirPlatformType platform_type() const
2609+ {
2610+ return mir_platform_type_gbm;
2611+ }
2612+
2613+ std::shared_ptr<mcl::ClientBufferFactory> create_buffer_factory()
2614+ {
2615+ return std::make_shared<StubClientBufferFactory>();
2616+ }
2617+
2618+ std::shared_ptr<EGLNativeWindowType> create_egl_native_window(mcl::ClientSurface*)
2619+ {
2620+ auto fake_window = reinterpret_cast<EGLNativeWindowType>(0x12345678lu);
2621+ return std::make_shared<EGLNativeWindowType>(fake_window);
2622+ }
2623+
2624+ std::shared_ptr<EGLNativeDisplayType> create_egl_native_display()
2625+ {
2626+ auto fake_display = reinterpret_cast<EGLNativeDisplayType>(0x12345678lu);
2627+ return std::make_shared<EGLNativeDisplayType>(fake_display);
2628+ }
2629+
2630+ MirNativeBuffer* convert_native_buffer(mir::graphics::NativeBuffer* buf) const
2631+ {
2632+ static_cast<void>(buf);
2633+#ifndef ANDROID
2634+ return buf;
2635+#else
2636+ return nullptr;
2637+#endif
2638+ }
2639+};
2640+}
2641+
2642+std::shared_ptr<mcl::ClientPlatform>
2643+mtf::StubClientPlatformFactory::create_client_platform(mcl::ClientContext*)
2644+{
2645+ return std::make_shared<StubClientPlatform>();
2646+}
2647
2648=== added file 'tests/mir_test_framework/stub_client_platform_module.cpp'
2649--- tests/mir_test_framework/stub_client_platform_module.cpp 1970-01-01 00:00:00 +0000
2650+++ tests/mir_test_framework/stub_client_platform_module.cpp 2014-11-27 07:32:44 +0000
2651@@ -0,0 +1,35 @@
2652+/*
2653+ * Copyright © 2014 Canonical Ltd.
2654+ *
2655+ * This program is free software: you can redistribute it and/or modify it
2656+ * under the terms of the GNU General Public License version 3,
2657+ * as published by the Free Software Foundation.
2658+ *
2659+ * This program is distributed in the hope that it will be useful,
2660+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2661+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2662+ * GNU General Public License for more details.
2663+ *
2664+ * You should have received a copy of the GNU General Public License
2665+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2666+ *
2667+ * Authored by: Christopher James Halse Rogers <christopher.halse.rogers@canonical.com>>
2668+ */
2669+
2670+#include "src/client/client_platform_factory.h"
2671+
2672+#include "mir_test_framework/stub_client_platform_factory.h"
2673+#include <memory>
2674+
2675+namespace mtf = mir_test_framework;
2676+namespace mcl = mir::client;
2677+
2678+extern "C" std::shared_ptr<mcl::ClientPlatform> create_client_platform(mcl::ClientContext* context)
2679+{
2680+ return mtf::StubClientPlatformFactory{}.create_client_platform(context);
2681+}
2682+
2683+extern "C" bool is_appropriate_module(mcl::ClientContext* /*context*/)
2684+{
2685+ return true;
2686+}
2687
2688=== added file 'tests/mir_test_framework/stub_server_platform_factory.cpp'
2689--- tests/mir_test_framework/stub_server_platform_factory.cpp 1970-01-01 00:00:00 +0000
2690+++ tests/mir_test_framework/stub_server_platform_factory.cpp 2014-11-27 07:32:44 +0000
2691@@ -0,0 +1,54 @@
2692+
2693+/*
2694+ * Copyright © 2014 Canonical Ltd.
2695+ *
2696+ * This program is free software: you can redistribute it and/or modify it
2697+ * under the terms of the GNU General Public License version 3,
2698+ * as published by the Free Software Foundation.
2699+ *
2700+ * This program is distributed in the hope that it will be useful,
2701+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2702+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2703+ * GNU General Public License for more details.
2704+ *
2705+ * You should have received a copy of the GNU General Public License
2706+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2707+ *
2708+ * Authored by: Christopher James Halse Rogers <christopher.halse.rogers@canonical.com>
2709+ */
2710+
2711+#include "mir/shared_library.h"
2712+
2713+#include "mir/geometry/rectangle.h"
2714+
2715+#include "mir_test_framework/executable_path.h"
2716+#include "mir_test_framework/stub_server_platform_factory.h"
2717+
2718+#include <vector>
2719+
2720+namespace geom = mir::geometry;
2721+namespace mg = mir::graphics;
2722+namespace mtf = mir_test_framework;
2723+
2724+namespace
2725+{
2726+// NOTE: Raw pointer, deliberately leaked to bypass all the fun
2727+// issues around global destructor ordering.
2728+mir::SharedLibrary* platform_lib{nullptr};
2729+
2730+void ensure_platform_library()
2731+{
2732+ if (!platform_lib)
2733+ {
2734+ platform_lib = new mir::SharedLibrary{mtf::library_path() + "/server-modules/graphics-dummy.so"};
2735+ }
2736+}
2737+}
2738+
2739+std::shared_ptr<mg::Platform> mtf::make_stubbed_server_graphics_platform(std::vector<geom::Rectangle> const& display_rects)
2740+{
2741+ ensure_platform_library();
2742+ auto factory = platform_lib->load_function<std::shared_ptr<mg::Platform>(*)(std::vector<geom::Rectangle> const&)>("create_stub_platform");
2743+
2744+ return factory(display_rects);
2745+}
2746
2747=== modified file 'tests/mir_test_framework/stubbed_graphics_platform.cpp'
2748--- tests/mir_test_framework/stubbed_graphics_platform.cpp 2014-11-25 12:05:51 +0000
2749+++ tests/mir_test_framework/stubbed_graphics_platform.cpp 2014-11-27 07:32:44 +0000
2750@@ -191,16 +191,25 @@
2751 return std::make_shared<NullWriter>();
2752 }
2753
2754+<<<<<<< TREE
2755 namespace
2756 {
2757 std::unique_ptr<std::vector<geom::Rectangle>> chosen_display_rects;
2758 }
2759
2760+=======
2761+extern "C" std::shared_ptr<mg::Platform> create_stub_platform(std::vector<geom::Rectangle> const& display_rects)
2762+{
2763+ return std::make_shared<mtf::StubGraphicPlatform>(display_rects);
2764+}
2765+
2766+>>>>>>> MERGE-SOURCE
2767 extern "C" std::shared_ptr<mg::Platform> create_platform(
2768 std::shared_ptr<mo::Option> const& /*options*/,
2769 std::shared_ptr<mir::EmergencyCleanupRegistry> const& /*emergency_cleanup_registry*/,
2770 std::shared_ptr<mg::DisplayReport> const& /*report*/)
2771 {
2772+<<<<<<< TREE
2773 if (auto const display_rects = std::move(chosen_display_rects))
2774 {
2775 return std::make_shared<mtf::StubGraphicPlatform>(*display_rects);
2776@@ -210,6 +219,10 @@
2777 static std::vector<geom::Rectangle> const default_display_rects{geom::Rectangle{{0,0},{1600,1600}}};
2778 return std::make_shared<mtf::StubGraphicPlatform>(default_display_rects);
2779 }
2780+=======
2781+ static std::vector<geom::Rectangle> const display_rects{geom::Rectangle{{0,0},{1600,1600}}};
2782+ return create_stub_platform(display_rects);
2783+>>>>>>> MERGE-SOURCE
2784 }
2785
2786 extern "C" void add_platform_options(
2787
2788=== modified file 'tests/mir_test_framework/stubbed_server_configuration.cpp'
2789--- tests/mir_test_framework/stubbed_server_configuration.cpp 2014-11-24 02:16:00 +0000
2790+++ tests/mir_test_framework/stubbed_server_configuration.cpp 2014-11-27 07:32:44 +0000
2791@@ -19,7 +19,7 @@
2792 #include "mir_test_framework/stubbed_server_configuration.h"
2793 #include "mir_test_framework/command_line_server_configuration.h"
2794
2795-#include "stubbed_graphics_platform.h"
2796+#include "mir_test_framework/stub_server_platform_factory.h"
2797
2798 #include "mir/options/default_configuration.h"
2799 #include "mir/graphics/cursor.h"
2800@@ -92,7 +92,7 @@
2801 {
2802 if (!graphics_platform)
2803 {
2804- graphics_platform = std::make_shared<StubGraphicPlatform>(display_rects);
2805+ graphics_platform = mtf::make_stubbed_server_graphics_platform(display_rects);
2806 }
2807
2808 return graphics_platform;
2809
2810=== added file 'tests/mir_test_framework/symbols-client.map'
2811--- tests/mir_test_framework/symbols-client.map 1970-01-01 00:00:00 +0000
2812+++ tests/mir_test_framework/symbols-client.map 2014-11-27 07:32:44 +0000
2813@@ -0,0 +1,7 @@
2814+MIR_CLIENT_PLATFORM_2 {
2815+ global:
2816+ create_client_platform;
2817+ is_appropriate_module;
2818+ local:
2819+ *;
2820+};
2821
2822=== added file 'tests/mir_test_framework/symbols-server.map'
2823--- tests/mir_test_framework/symbols-server.map 1970-01-01 00:00:00 +0000
2824+++ tests/mir_test_framework/symbols-server.map 2014-11-27 07:32:44 +0000
2825@@ -0,0 +1,8 @@
2826+MIR_GRAPHICS_PLATFORM_1 {
2827+ global:
2828+ add_platform_options;
2829+ create_platform;
2830+ create_native_platform;
2831+ probe_platform;
2832+ describe_module;
2833+};
2834
2835=== modified file 'tests/mir_test_framework/testing_client_options.cpp'
2836--- tests/mir_test_framework/testing_client_options.cpp 2014-11-27 03:48:20 +0000
2837+++ tests/mir_test_framework/testing_client_options.cpp 2014-11-27 07:32:44 +0000
2838@@ -16,18 +16,17 @@
2839 * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
2840 */
2841
2842-#include "mir_test_framework/testing_client_configuration.h"
2843 #include "mir_test_framework/stub_client_connection_configuration.h"
2844+<<<<<<< TREE
2845 #include "mir_test_doubles/stub_client_buffer_factory.h"
2846 #include "mir/options/program_option.h"
2847+=======
2848+>>>>>>> MERGE-SOURCE
2849 #include "src/client/default_connection_configuration.h"
2850-#include "src/client/client_platform_factory.h"
2851-#include "src/client/client_buffer_factory.h"
2852-#include "src/client/client_buffer.h"
2853-#include "src/client/client_platform.h"
2854-#include "src/client/mir_connection.h"
2855+#include "mir_test_framework/stub_client_platform_factory.h"
2856
2857 namespace mcl = mir::client;
2858+<<<<<<< TREE
2859 namespace mtf=mir_test_framework;
2860 namespace geom = mir::geometry;
2861 namespace mtd = mir::test::doubles;
2862@@ -73,6 +72,9 @@
2863 };
2864
2865 }
2866+=======
2867+namespace mtf = mir_test_framework;
2868+>>>>>>> MERGE-SOURCE
2869
2870 mtf::StubConnectionConfiguration::StubConnectionConfiguration(std::string const& socket_file)
2871 : DefaultConnectionConfiguration(socket_file)
2872
2873=== modified file 'tests/unit-tests/CMakeLists.txt'
2874--- tests/unit-tests/CMakeLists.txt 2014-11-27 03:48:20 +0000
2875+++ tests/unit-tests/CMakeLists.txt 2014-11-27 07:32:44 +0000
2876@@ -1,7 +1,23 @@
2877 include(CMakeDependentOption)
2878
2879+add_definitions(-DTEST_RECORDINGS_DIR="${CMAKE_CURRENT_SOURCE_DIR}/input_recordings/")
2880+
2881+if (MIR_BUILD_PLATFORM_ANDROID)
2882+ add_definitions(-DMIR_BUILD_PLATFORM_ANDROID)
2883+endif()
2884+
2885+if (MIR_BUILD_PLATFORM_MESA)
2886+ add_definitions(-DMIR_BUILD_PLATFORM_MESA)
2887+endif()
2888+
2889 include_directories(
2890 ${CMAKE_SOURCE_DIR}
2891+
2892+ ${ANDROID_HEADERS_INCLUDE_DIRS}
2893+ ${DRM_INCLUDE_DIRS}
2894+ ${GBM_INCLUDE_DIRS}
2895+ ${UMOCKDEV_INCLUDE_DIRS}
2896+
2897 ${PROJECT_SOURCE_DIR}/src/include/platform
2898 ${PROJECT_SOURCE_DIR}/src/include/server
2899 ${PROJECT_SOURCE_DIR}/src/include/client
2900@@ -9,12 +25,6 @@
2901 ${GLIB_INCLUDE_DIRS}
2902 )
2903
2904-add_definitions(
2905- -DTEST_RECORDINGS_DIR="${CMAKE_CURRENT_SOURCE_DIR}/input_recordings/"
2906- -DMIR_CLIENT_DRIVER_BINARY="${MIR_CLIENT_DRIVER_BINARY}"
2907-)
2908-
2909-include_directories(${DRM_INCLUDE_DIRS} ${GBM_INCLUDE_DIRS} ${UMOCKDEV_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR})
2910 # TODO: Aim to remove
2911 include_directories(${MIR_XCURSOR_INCLUDE_DIRECTORIES})
2912
2913@@ -79,9 +89,9 @@
2914 demo-shell
2915
2916 mir-test
2917+ mir-test-framework
2918 mir-test-doubles
2919 mir-test-doubles-platform
2920- mir-test-framework
2921
2922 3rd_party
2923
2924@@ -91,6 +101,15 @@
2925 ${GMOCK_MAIN_LIBRARY}
2926 ${Boost_LIBRARIES}
2927 ${UMOCKDEV_LIBRARIES}
2928+ # Mesa platform dependencies
2929+ ${DRM_LDFLAGS} ${DRM_LIBRARIES}
2930+ ${GBM_LDFLAGS} ${GBM_LIBRARIES}
2931+ # Android platform dependencies
2932+ ${LIBHARDWARE_LIBRARIES}
2933+ ${ANDROID_PROPERTIES_LIBRARIES}
2934+ # Shared platform dependencies
2935+ ${EGL_LDFLAGS} ${EGL_LIBRARIES}
2936+ ${GLESv2_LDFLAGS} ${GLESv2_LIBRARIES}
2937 ${CMAKE_THREAD_LIBS_INIT} # Link in pthread.
2938 ${LIBHARDWARE_LDFLAGS} ${LIBHARDWARE_LIBRARIES}
2939 ${DRM_LDFLAGS} ${DRM_LIBRARIES}
2940@@ -99,7 +118,7 @@
2941 ${MIR_SERVER_REFERENCES}
2942 )
2943
2944-if (MIR_TEST_PLATFORM STREQUAL "android")
2945+if (MIR_BUILD_PLATFORM_ANDROID)
2946 target_link_libraries(mir_unit_tests
2947 mirsharedandroid
2948 ${ANDROID_PROPERTIES_LDFLAGS}
2949@@ -114,7 +133,10 @@
2950 OFF)
2951
2952 if (MIR_RUN_UNIT_TESTS)
2953- mir_discover_tests(mir_unit_tests LD_PRELOAD=libumockdev-preload.so.0 G_SLICE=always-malloc G_DEBUG=gc-friendly)
2954+ mir_discover_tests(mir_unit_tests
2955+ LD_PRELOAD=libumockdev-preload.so.0
2956+ G_SLICE=always-malloc
2957+ G_DEBUG=gc-friendly)
2958 endif (MIR_RUN_UNIT_TESTS)
2959
2960 install(
2961
2962=== modified file 'tests/unit-tests/client/CMakeLists.txt'
2963--- tests/unit-tests/client/CMakeLists.txt 2014-11-24 02:16:00 +0000
2964+++ tests/unit-tests/client/CMakeLists.txt 2014-11-27 07:32:44 +0000
2965@@ -12,6 +12,7 @@
2966 ${CMAKE_CURRENT_SOURCE_DIR}/test_protobuf_rpc_channel.cpp
2967 ${CMAKE_CURRENT_SOURCE_DIR}/test_mir_prompt_session.cpp
2968 ${CMAKE_CURRENT_SOURCE_DIR}/test_event_distributor.cpp
2969+ ${CMAKE_CURRENT_SOURCE_DIR}/test_probing_client_platform_factory.cpp
2970 ${CMAKE_CURRENT_SOURCE_DIR}/test_periodic_perf_report.cpp
2971 )
2972
2973
2974=== modified file 'tests/unit-tests/client/android/test_android_client_platform.cpp'
2975--- tests/unit-tests/client/android/test_android_client_platform.cpp 2014-03-06 06:05:17 +0000
2976+++ tests/unit-tests/client/android/test_android_client_platform.cpp 2014-11-27 07:32:44 +0000
2977@@ -17,9 +17,9 @@
2978 */
2979
2980 #include "src/client/client_platform.h"
2981-#include "src/client/android/client_platform_factory.h"
2982 #include "mir_test_doubles/mock_client_context.h"
2983 #include "mir_test_doubles/mock_client_surface.h"
2984+#include "mir_test_framework/client_platform_factory.h"
2985
2986 #include <EGL/egl.h>
2987
2988@@ -28,13 +28,12 @@
2989 namespace mcl = mir::client;
2990 namespace mt = mir::test;
2991 namespace mtd = mt::doubles;
2992+namespace mtf = mir_test_framework;
2993
2994 TEST(AndroidClientPlatformTest, egl_native_display_is_egl_default_display)
2995 {
2996- mtd::MockClientContext context;
2997- mcl::android::ClientPlatformFactory factory;
2998 mtd::MockClientSurface surface;
2999- auto platform = factory.create_client_platform(&context);
3000+ auto platform = mtf::create_android_client_platform();
3001 auto mock_client_surface = std::make_shared<mtd::MockClientSurface>();
3002 auto native_display = platform->create_egl_native_display();
3003 EXPECT_EQ(EGL_DEFAULT_DISPLAY, *native_display);
3004@@ -42,10 +41,8 @@
3005
3006 TEST(AndroidClientPlatformTest, egl_native_window_is_set)
3007 {
3008- mtd::MockClientContext context;
3009- mcl::android::ClientPlatformFactory factory;
3010 mtd::MockClientSurface surface;
3011- auto platform = factory.create_client_platform(&context);
3012+ auto platform = mtf::create_android_client_platform();
3013 auto mock_client_surface = std::make_shared<mtd::MockClientSurface>();
3014 auto egl_native_window = platform->create_egl_native_window(&surface);
3015 EXPECT_NE(nullptr, egl_native_window);
3016
3017=== modified file 'tests/unit-tests/client/mesa/test_client_platform.cpp'
3018--- tests/unit-tests/client/mesa/test_client_platform.cpp 2014-03-06 06:05:17 +0000
3019+++ tests/unit-tests/client/mesa/test_client_platform.cpp 2014-11-27 07:32:44 +0000
3020@@ -17,9 +17,9 @@
3021 */
3022
3023 #include "src/client/client_platform.h"
3024-#include "src/client/mesa/client_platform_factory.h"
3025+#include "mir/shared_library.h"
3026 #include "src/client/mesa/mesa_native_display_container.h"
3027-#include "mir_test_doubles/mock_client_context.h"
3028+#include "mir_test_framework/client_platform_factory.h"
3029 #include "mir_test_doubles/mock_client_surface.h"
3030
3031 #include "mir_toolkit/mesa/native_display.h"
3032@@ -30,19 +30,20 @@
3033 namespace mclm = mir::client::mesa;
3034 namespace mt = mir::test;
3035 namespace mtd = mir::test::doubles;
3036+namespace mtf = mir_test_framework;
3037
3038 TEST(MesaClientPlatformTest, egl_native_display_is_valid_until_released)
3039 {
3040- mtd::MockClientContext context;
3041- mclm::ClientPlatformFactory factory;
3042- auto platform = factory.create_client_platform(&context);
3043+ auto platform = mtf::create_mesa_client_platform();
3044+ auto platform_lib = mtf::get_platform_library();
3045
3046 MirMesaEGLNativeDisplay* nd;
3047 {
3048 std::shared_ptr<EGLNativeDisplayType> native_display = platform->create_egl_native_display();
3049
3050 nd = reinterpret_cast<MirMesaEGLNativeDisplay*>(*native_display);
3051- EXPECT_EQ(MIR_MESA_TRUE, mclm::mir_client_mesa_egl_native_display_is_valid(nd));
3052+ auto validate = platform_lib->load_function<MirBool(*)(MirMesaEGLNativeDisplay*)>("mir_client_mesa_egl_native_display_is_valid");
3053+ EXPECT_EQ(MIR_MESA_TRUE, validate(nd));
3054 }
3055 EXPECT_EQ(MIR_MESA_FALSE, mclm::mir_client_mesa_egl_native_display_is_valid(nd));
3056 }
3057
3058=== modified file 'tests/unit-tests/client/mesa/test_mesa_native_display_container.cpp'
3059--- tests/unit-tests/client/mesa/test_mesa_native_display_container.cpp 2014-03-06 06:05:17 +0000
3060+++ tests/unit-tests/client/mesa/test_mesa_native_display_container.cpp 2014-11-27 07:32:44 +0000
3061@@ -40,7 +40,7 @@
3062 }
3063
3064 std::shared_ptr<mclg::MesaNativeDisplayContainer> const container;
3065- MirConnection* connection;
3066+ mir::client::ClientContext* connection;
3067 };
3068
3069 }
3070
3071=== modified file 'tests/unit-tests/client/test_client_platform.cpp'
3072--- tests/unit-tests/client/test_client_platform.cpp 2014-03-06 06:05:17 +0000
3073+++ tests/unit-tests/client/test_client_platform.cpp 2014-11-27 07:32:44 +0000
3074@@ -20,60 +20,140 @@
3075 #include "src/client/mir_client_surface.h"
3076 #include "mir_test_doubles/mock_client_context.h"
3077 #include "mir_test_doubles/mock_client_surface.h"
3078+#include "mir_test_framework/executable_path.h"
3079
3080-#ifdef ANDROID
3081+#ifdef MIR_BUILD_PLATFORM_ANDROID
3082 #include "mir_test_doubles/mock_android_hw.h"
3083-#include "src/client/android/client_platform_factory.h"
3084-#else
3085-#include "src/client/mesa/client_platform_factory.h"
3086 #endif
3087
3088+#include "src/client/client_platform_factory.h"
3089+
3090+#include "mir/shared_library.h"
3091+
3092 #include <gmock/gmock.h>
3093 #include <gtest/gtest.h>
3094
3095 namespace mcl=mir::client;
3096 namespace mtd = mir::test::doubles;
3097-
3098-struct ClientPlatformTest : public ::testing::Test
3099-{
3100+namespace mtf = mir_test_framework;
3101+
3102+namespace
3103+{
3104+struct ClientPlatformTraits
3105+{
3106+ ClientPlatformTraits(std::string const& library,
3107+ std::function<void(MirPlatformPackage&)> populator,
3108+ MirPlatformType type)
3109+ : platform_library_name{library},
3110+ populate_package_for{populator},
3111+ platform_type{type}
3112+ {
3113+ }
3114+
3115+ std::string const platform_library_name;
3116+ std::function<void(MirPlatformPackage&)> const populate_package_for;
3117+ MirPlatformType const platform_type;
3118+};
3119+
3120+struct ClientPlatformTest : public ::testing::TestWithParam<ClientPlatformTraits const*>
3121+{
3122+ ClientPlatformTest()
3123+ : platform_library{mtf::library_path() + "/" + GetParam()->platform_library_name},
3124+ create_client_platform{platform_library.load_function<mcl::CreateClientPlatform>("create_client_platform")},
3125+ probe{platform_library.load_function<mcl::ClientPlatformProbe>("is_appropriate_module")}
3126+ {
3127+ using namespace testing;
3128+ ON_CALL(context, populate(_))
3129+ .WillByDefault(Invoke(GetParam()->populate_package_for));
3130+ }
3131+
3132 mtd::MockClientContext context;
3133-#ifdef ANDROID
3134+#ifdef MIR_BUILD_PLATFORM_ANDROID
3135 testing::NiceMock<mtd::HardwareAccessMock> hw_access_mock;
3136- mcl::android::ClientPlatformFactory factory;
3137-#else
3138- mcl::mesa::ClientPlatformFactory factory;
3139 #endif
3140+ mir::SharedLibrary platform_library;
3141+ mcl::CreateClientPlatform const create_client_platform;
3142+ mcl::ClientPlatformProbe const probe;
3143 };
3144
3145-TEST_F(ClientPlatformTest, platform_name)
3146-{
3147- auto platform = factory.create_client_platform(&context);
3148-#ifdef ANDROID
3149- auto type = mir_platform_type_android;
3150-#else
3151- auto type = mir_platform_type_gbm;
3152-#endif
3153- EXPECT_EQ(type, platform->platform_type());
3154-}
3155-
3156-TEST_F(ClientPlatformTest, platform_creates)
3157-{
3158- auto platform = factory.create_client_platform(&context);
3159+#ifdef MIR_BUILD_PLATFORM_ANDROID
3160+ClientPlatformTraits const android_platform{"/client-modules/android.so",
3161+ [](MirPlatformPackage& pkg)
3162+ {
3163+ ::memset(&pkg, 0, sizeof(pkg));
3164+ },
3165+ mir_platform_type_android
3166+ };
3167+
3168+INSTANTIATE_TEST_CASE_P(Android,
3169+ ClientPlatformTest,
3170+ ::testing::Values(&android_platform));
3171+
3172+#endif
3173+
3174+#ifdef MIR_BUILD_PLATFORM_MESA
3175+ClientPlatformTraits const mesa_platform{"/client-modules/mesa.so",
3176+ [](MirPlatformPackage& pkg)
3177+ {
3178+ ::memset(&pkg, 0, sizeof(pkg));
3179+ pkg.fd_items = 1;
3180+ },
3181+ mir_platform_type_gbm
3182+ };
3183+
3184+INSTANTIATE_TEST_CASE_P(Mesa,
3185+ ClientPlatformTest,
3186+ ::testing::Values(&mesa_platform));
3187+
3188+#endif
3189+}
3190+
3191+TEST_P(ClientPlatformTest, platform_name)
3192+{
3193+ auto platform = create_client_platform(&context);
3194+
3195+ EXPECT_EQ(GetParam()->platform_type, platform->platform_type());
3196+}
3197+
3198+TEST_P(ClientPlatformTest, platform_creates)
3199+{
3200+ auto platform = create_client_platform(&context);
3201 auto buffer_factory = platform->create_buffer_factory();
3202 EXPECT_NE(buffer_factory.get(), (mcl::ClientBufferFactory*) NULL);
3203 }
3204
3205-TEST_F(ClientPlatformTest, platform_creates_native_window)
3206+TEST_P(ClientPlatformTest, platform_creates_native_window)
3207 {
3208- auto platform = factory.create_client_platform(&context);
3209+ auto platform = create_client_platform(&context);
3210 auto mock_client_surface = std::make_shared<mtd::MockClientSurface>();
3211 auto native_window = platform->create_egl_native_window(mock_client_surface.get());
3212 EXPECT_NE(*native_window, (EGLNativeWindowType) NULL);
3213 }
3214
3215-TEST_F(ClientPlatformTest, platform_creates_egl_native_display)
3216+TEST_P(ClientPlatformTest, platform_creates_egl_native_display)
3217 {
3218- auto platform = factory.create_client_platform(&context);
3219+ auto platform = create_client_platform(&context);
3220 auto native_display = platform->create_egl_native_display();
3221 EXPECT_NE(nullptr, native_display.get());
3222 }
3223+
3224+TEST_P(ClientPlatformTest, platform_probe_returns_success_when_matching)
3225+{
3226+ EXPECT_TRUE(probe(&context));
3227+}
3228+
3229+TEST_P(ClientPlatformTest, platform_probe_returns_false_when_not_matching)
3230+{
3231+ using namespace testing;
3232+ ON_CALL(context, populate(_))
3233+ .WillByDefault(Invoke([](MirPlatformPackage& pkg)
3234+ {
3235+ //Mock up something that hopefully looks nothing like
3236+ //what the platform is expecting...
3237+ ::memset(&pkg, 0, sizeof(pkg));
3238+ pkg.data_items = 0xdeadbeef;
3239+ pkg.fd_items = -23;
3240+ }));
3241+
3242+ EXPECT_FALSE(probe(&context));
3243+}
3244
3245=== added file 'tests/unit-tests/client/test_probing_client_platform_factory.cpp'
3246--- tests/unit-tests/client/test_probing_client_platform_factory.cpp 1970-01-01 00:00:00 +0000
3247+++ tests/unit-tests/client/test_probing_client_platform_factory.cpp 2014-11-27 07:32:44 +0000
3248@@ -0,0 +1,141 @@
3249+/*
3250+ * Copyright © 2014 Canonical Ltd.
3251+ *
3252+ * This program is free software: you can redistribute it and/or modify
3253+ * it under the terms of the GNU General Public License version 3 as
3254+ * published by the Free Software Foundation.
3255+ *
3256+ * This program is distributed in the hope that it will be useful,
3257+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3258+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3259+ * GNU General Public License for more details.
3260+ *
3261+ * You should have received a copy of the GNU General Public License
3262+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3263+ *
3264+ * Authored by: Christopher James Halse Rogers <christopher.halse.rogers@canonical.com>
3265+ */
3266+
3267+#include "src/client/client_platform.h"
3268+#include "src/client/probing_client_platform_factory.h"
3269+
3270+#include "mir_test_doubles/mock_client_context.h"
3271+#include "mir_test_framework/executable_path.h"
3272+
3273+#include <gmock/gmock.h>
3274+#include <gtest/gtest.h>
3275+
3276+namespace mtf = mir_test_framework;
3277+namespace mtd = mir::test::doubles;
3278+
3279+namespace
3280+{
3281+std::vector<std::shared_ptr<mir::SharedLibrary>>
3282+all_available_modules()
3283+{
3284+ std::vector<std::shared_ptr<mir::SharedLibrary>> modules;
3285+#ifdef MIR_BUILD_PLATFORM_MESA
3286+ modules.push_back(std::make_shared<mir::SharedLibrary>(mtf::library_path() + "/client-modules/mesa.so"));
3287+#endif
3288+#ifdef MIR_BUILD_PLATFORM_ANDROID
3289+ modules.push_back(std::make_shared<mir::SharedLibrary>(mtf::library_path() + "/client-modules/android.so"));
3290+#endif
3291+ return modules;
3292+}
3293+}
3294+
3295+TEST(ProbingClientPlatformFactory, ThrowsErrorWhenConstructedWithNoPlatforms)
3296+{
3297+ std::vector<std::shared_ptr<mir::SharedLibrary>> empty_modules;
3298+ EXPECT_THROW(mir::client::ProbingClientPlatformFactory{empty_modules},
3299+ std::runtime_error);
3300+}
3301+
3302+TEST(ProbingClientPlatformFactory, ThrowsErrorWhenNoPlatformPluginProbesSuccessfully)
3303+{
3304+ using namespace testing;
3305+
3306+ mir::client::ProbingClientPlatformFactory factory{all_available_modules()};
3307+
3308+ mtd::MockClientContext context;
3309+ ON_CALL(context, populate(_))
3310+ .WillByDefault(Invoke([](MirPlatformPackage& pkg)
3311+ {
3312+ ::memset(&pkg, 0, sizeof(MirPlatformPackage));
3313+ // Mock up a platform package that looks nothing like
3314+ // either an Android or Mesa package
3315+ pkg.fd_items = 0xdeadbeef;
3316+ pkg.data_items = -23;
3317+ }));
3318+
3319+ EXPECT_THROW(factory.create_client_platform(&context),
3320+ std::runtime_error);
3321+}
3322+
3323+#ifdef MIR_BUILD_PLATFORM_MESA
3324+TEST(ProbingClientPlatformFactory, CreatesMesaPlatformWhenAppropriate)
3325+{
3326+ using namespace testing;
3327+
3328+ mir::client::ProbingClientPlatformFactory factory{all_available_modules()};
3329+
3330+ mtd::MockClientContext context;
3331+ ON_CALL(context, populate(_))
3332+ .WillByDefault(Invoke([](MirPlatformPackage& pkg)
3333+ {
3334+ ::memset(&pkg, 0, sizeof(MirPlatformPackage));
3335+ // Mock up something that looks like a GBM platform package,
3336+ // until we send the actual platform type over the wire!
3337+ pkg.fd_items = 1;
3338+ pkg.fd[0] = 23;
3339+ }));
3340+ auto platform = factory.create_client_platform(&context);
3341+ EXPECT_EQ(mir_platform_type_gbm, platform->platform_type());
3342+}
3343+#endif
3344+
3345+#ifdef MIR_BUILD_PLATFORM_ANDROID
3346+TEST(ProbingClientPlatformFactory, CreatesAndroidPlatformWhenAppropriate)
3347+{
3348+ using namespace testing;
3349+
3350+ mir::client::ProbingClientPlatformFactory factory{all_available_modules()};
3351+
3352+ mtd::MockClientContext context;
3353+ ON_CALL(context, populate(_))
3354+ .WillByDefault(Invoke([](MirPlatformPackage& pkg)
3355+ {
3356+ // Mock up something that looks like a Android platform package,
3357+ // until we send the actual platform type over the wire!
3358+ ::memset(&pkg, 0, sizeof(MirPlatformPackage));
3359+ }));
3360+
3361+ auto platform = factory.create_client_platform(&context);
3362+ EXPECT_EQ(mir_platform_type_android, platform->platform_type());
3363+}
3364+#endif
3365+
3366+TEST(ProbingClientPlatformFactory, IgnoresNonClientPlatformModules)
3367+{
3368+ using namespace testing;
3369+
3370+ auto modules = all_available_modules();
3371+ // NOTE: For minimum fuss, load something that has minimal side-effects...
3372+ modules.push_back(std::make_shared<mir::SharedLibrary>(mtf::library_path() + "/server-modules/graphics-dummy.so"));
3373+ modules.push_back(std::make_shared<mir::SharedLibrary>(mtf::library_path() + "/client-modules/dummy.so"));
3374+
3375+ mir::client::ProbingClientPlatformFactory factory{modules};
3376+
3377+ mtd::MockClientContext context;
3378+ ON_CALL(context, populate(_))
3379+ .WillByDefault(Invoke([](MirPlatformPackage& pkg)
3380+ {
3381+ // Mock up something that looks like a Dummy platform package,
3382+ // until we send the actual platform type over the wire!
3383+ ::memset(&pkg, 0, sizeof(MirPlatformPackage));
3384+ pkg.data_items = 20;
3385+ strcpy(reinterpret_cast<char*>(pkg.data), "Dummy platform");
3386+ }));
3387+
3388+ auto platform = factory.create_client_platform(&context);
3389+}
3390
3391=== modified file 'tests/unit-tests/graphics/CMakeLists.txt'
3392--- tests/unit-tests/graphics/CMakeLists.txt 2014-11-24 02:16:00 +0000
3393+++ tests/unit-tests/graphics/CMakeLists.txt 2014-11-27 07:32:44 +0000
3394@@ -10,6 +10,7 @@
3395 ${CMAKE_CURRENT_SOURCE_DIR}/test_surfaceless_egl_context.cpp
3396 ${CMAKE_CURRENT_SOURCE_DIR}/test_overlapping_output_grouping.cpp
3397 ${CMAKE_CURRENT_SOURCE_DIR}/test_program_factory.cpp
3398+ ${CMAKE_CURRENT_SOURCE_DIR}/test_platform_prober.cpp
3399 )
3400
3401 add_subdirectory(nested/)
3402
3403=== modified file 'tests/unit-tests/graphics/android/test_platform.cpp'
3404--- tests/unit-tests/graphics/android/test_platform.cpp 2014-11-24 02:16:00 +0000
3405+++ tests/unit-tests/graphics/android/test_platform.cpp 2014-11-27 07:32:44 +0000
3406@@ -29,6 +29,8 @@
3407 #include "mir_test_doubles/fd_matcher.h"
3408 #include "mir_test/fake_shared.h"
3409 #include "mir_test_doubles/mock_android_native_buffer.h"
3410+#include "mir_test_framework/executable_path.h"
3411+#include "mir/shared_library.h"
3412 #include <system/window.h>
3413 #include <gtest/gtest.h>
3414
3415@@ -39,6 +41,7 @@
3416 namespace mr=mir::report;
3417 namespace geom=mir::geometry;
3418 namespace mo=mir::options;
3419+namespace mtf=mir_test_framework;
3420
3421 class PlatformBufferIPCPackaging : public ::testing::Test
3422 {
3423@@ -228,6 +231,27 @@
3424 EXPECT_EQ(EGL_DEFAULT_DISPLAY, platform.egl_native_display());
3425 }
3426
3427+TEST(AndroidGraphicsPlatform, probe_returns_unsupported_when_no_hwaccess)
3428+{
3429+ using namespace testing;
3430+ NiceMock<mtd::HardwareAccessMock> hwaccess;
3431+
3432+ ON_CALL(hwaccess, hw_get_module(_,_)).WillByDefault(Return(-1));
3433+
3434+ mir::SharedLibrary platform_lib{mtf::library_path() + "/server-modules/graphics-android.so"};
3435+ auto probe = platform_lib.load_function<mg::PlatformProbe>("probe_platform");
3436+ EXPECT_EQ(mg::PlatformPriority::unsupported, probe());
3437+}
3438+
3439+TEST(AndroidGraphicsPlatform, probe_returns_best_when_hwaccess_succeeds)
3440+{
3441+ testing::NiceMock<mtd::HardwareAccessMock> hwaccess;
3442+
3443+ mir::SharedLibrary platform_lib{mtf::library_path() + "/server-modules/graphics-android.so"};
3444+ auto probe = platform_lib.load_function<mg::PlatformProbe>("probe_platform");
3445+ EXPECT_EQ(mg::PlatformPriority::best, probe());
3446+}
3447+
3448 TEST(NestedPlatformCreation, doesnt_access_display_hardware)
3449 {
3450 using namespace testing;
3451
3452=== modified file 'tests/unit-tests/graphics/mesa/test_platform.cpp'
3453--- tests/unit-tests/graphics/mesa/test_platform.cpp 2014-11-24 02:16:00 +0000
3454+++ tests/unit-tests/graphics/mesa/test_platform.cpp 2014-11-27 07:32:44 +0000
3455@@ -22,6 +22,7 @@
3456 #include "src/platform/graphics/mesa/platform.h"
3457 #include "src/server/report/null_report_factory.h"
3458 #include "mir/emergency_cleanup_registry.h"
3459+#include "mir/shared_library.h"
3460
3461 #include "mir_test_doubles/mock_buffer.h"
3462 #include "mir_test_doubles/mock_buffer_ipc_message.h"
3463@@ -32,6 +33,7 @@
3464 #include <gtest/gtest.h>
3465
3466 #include "mir_test_framework/udev_environment.h"
3467+#include "mir_test_framework/executable_path.h"
3468 #include "mir_test/pipe.h"
3469
3470 #include "mir_test_doubles/mock_drm.h"
3471@@ -332,3 +334,23 @@
3472
3473 Mock::VerifyAndClearExpectations(&mock_drm);
3474 }
3475+
3476+TEST_F(MesaGraphicsPlatform, probe_returns_unsupported_when_no_drm_udev_devices)
3477+{
3478+ mtf::UdevEnvironment udev_environment;
3479+
3480+ mir::SharedLibrary platform_lib{mtf::library_path() + "/server-modules/graphics-mesa.so"};
3481+ auto probe = platform_lib.load_function<mg::PlatformProbe>("probe_platform");
3482+ EXPECT_EQ(mg::PlatformPriority::unsupported, probe());
3483+}
3484+
3485+TEST_F(MesaGraphicsPlatform, probe_returns_best_when_drm_devices_exist)
3486+{
3487+ mtf::UdevEnvironment udev_environment;
3488+
3489+ udev_environment.add_standard_device("standard-drm-devices");
3490+
3491+ mir::SharedLibrary platform_lib{mtf::library_path() + "/server-modules/graphics-mesa.so"};
3492+ auto probe = platform_lib.load_function<mg::PlatformProbe>("probe_platform");
3493+ EXPECT_EQ(mg::PlatformPriority::best, probe());
3494+}
3495
3496=== added file 'tests/unit-tests/graphics/test_platform_prober.cpp'
3497--- tests/unit-tests/graphics/test_platform_prober.cpp 1970-01-01 00:00:00 +0000
3498+++ tests/unit-tests/graphics/test_platform_prober.cpp 2014-11-27 07:32:44 +0000
3499@@ -0,0 +1,214 @@
3500+/*
3501+ * Copyright © 2014 Canonical Ltd.
3502+ *
3503+ * This program is free software: you can redistribute it and/or modify
3504+ * it under the terms of the GNU General Public License version 3 as
3505+ * published by the Free Software Foundation.
3506+ *
3507+ * This program is distributed in the hope that it will be useful,
3508+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3509+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3510+ * GNU General Public License for more details.
3511+ *
3512+ * You should have received a copy of the GNU General Public License
3513+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3514+ *
3515+ * Authored by: Christopher James Halse Rogers <christopher.halse.rogers@canonical.com>
3516+ */
3517+
3518+#include <gtest/gtest.h>
3519+
3520+#include "src/platform/graphics/platform_probe.h"
3521+#include "mir/graphics/platform.h"
3522+
3523+#include "mir/raii.h"
3524+
3525+#ifdef MIR_BUILD_PLATFORM_MESA
3526+#include "mir_test_doubles/mock_drm.h"
3527+#include "mir_test_doubles/mock_gbm.h"
3528+#endif
3529+
3530+#ifdef MIR_BUILD_PLATFORM_ANDROID
3531+#include "mir_test_doubles/mock_android_hw.h"
3532+#endif
3533+
3534+#include "mir_test_framework/udev_environment.h"
3535+#include "mir_test_framework/executable_path.h"
3536+
3537+namespace mtf = mir_test_framework;
3538+namespace mtd = mir::test::doubles;
3539+
3540+namespace
3541+{
3542+std::vector<std::shared_ptr<mir::SharedLibrary>> available_platforms()
3543+{
3544+ std::vector<std::shared_ptr<mir::SharedLibrary>> modules;
3545+
3546+#ifdef MIR_BUILD_PLATFORM_MESA
3547+ modules.push_back(std::make_shared<mir::SharedLibrary>(mtf::library_path() + "/server-modules/graphics-mesa.so"));
3548+#endif
3549+#ifdef MIR_BUILD_PLATFORM_ANDROID
3550+ modules.push_back(std::make_shared<mir::SharedLibrary>(mtf::library_path() + "/server-modules/graphics-android.so"));
3551+#endif
3552+ return modules;
3553+}
3554+
3555+void add_dummy_platform(std::vector<std::shared_ptr<mir::SharedLibrary>>& modules)
3556+{
3557+ modules.insert(modules.begin(), std::make_shared<mir::SharedLibrary>(mtf::library_path() + "/server-modules/graphics-dummy.so"));
3558+}
3559+
3560+std::shared_ptr<void> ensure_android_probing_fails()
3561+{
3562+#ifdef MIR_BUILD_PLATFORM_ANDROID
3563+ using namespace testing;
3564+ auto mock_android = std::make_shared<NiceMock<mtd::HardwareAccessMock>>();
3565+ ON_CALL(*mock_android, hw_get_module(_, _))
3566+ .WillByDefault(Return(-1));
3567+ return mock_android;
3568+#else
3569+ return std::shared_ptr<void>{};
3570+#endif
3571+}
3572+
3573+std::shared_ptr<void> ensure_mesa_probing_fails()
3574+{
3575+ return std::make_shared<mtf::UdevEnvironment>();
3576+}
3577+
3578+std::shared_ptr<void> ensure_mesa_probing_succeeds()
3579+{
3580+ auto udev = std::make_shared<mtf::UdevEnvironment>();
3581+
3582+ udev->add_standard_device("standard-drm-devices");
3583+
3584+ return udev;
3585+}
3586+
3587+std::shared_ptr<void> ensure_android_probing_succeeds()
3588+{
3589+#ifdef MIR_BUILD_PLATFORM_ANDROID
3590+ using namespace testing;
3591+ auto mock_android = std::make_shared<NiceMock<mtd::HardwareAccessMock>>();
3592+ ON_CALL(*mock_android, hw_get_module(_, _))
3593+ .WillByDefault(Return(0));
3594+ return mock_android;
3595+#else
3596+ return std::shared_ptr<void>{};
3597+#endif
3598+}
3599+}
3600+
3601+TEST(ServerPlatformProbe, ConstructingWithNoModulesIsAnError)
3602+{
3603+ std::vector<std::shared_ptr<mir::SharedLibrary>> empty_modules;
3604+ EXPECT_THROW(mir::graphics::module_for_device(empty_modules),
3605+ std::runtime_error);
3606+}
3607+
3608+#ifdef MIR_BUILD_PLATFORM_MESA
3609+TEST(ServerPlatformProbe, LoadsMesaPlatformWhenDrmDevicePresent)
3610+{
3611+ using namespace testing;
3612+ auto block_android = ensure_android_probing_fails();
3613+ auto fake_mesa = ensure_mesa_probing_succeeds();
3614+
3615+ auto modules = available_platforms();
3616+
3617+ auto module = mir::graphics::module_for_device(modules);
3618+ ASSERT_NE(nullptr, module);
3619+
3620+ auto descriptor = module->load_function<mir::graphics::DescribeModule>("describe_module");
3621+ auto description = descriptor();
3622+
3623+ EXPECT_THAT(description->name, HasSubstr("mesa"));
3624+}
3625+#endif
3626+
3627+#ifdef MIR_BUILD_PLATFORM_ANDROID
3628+TEST(ServerPlatformProbe, LoadsAndroidPlatformWhenHwaccessSucceeds)
3629+{
3630+ using namespace testing;
3631+
3632+ auto block_mesa = ensure_mesa_probing_fails();
3633+ auto fake_android = ensure_android_probing_succeeds();
3634+
3635+ auto modules = available_platforms();
3636+
3637+ auto module = mir::graphics::module_for_device(modules);
3638+ ASSERT_NE(nullptr, module);
3639+
3640+ auto descriptor = module->load_function<mir::graphics::DescribeModule>("describe_module");
3641+ auto description = descriptor();
3642+
3643+ EXPECT_THAT(description->name, HasSubstr("android"));
3644+}
3645+#endif
3646+
3647+TEST(ServerPlatformProbe, ThrowsExceptionWhenNothingProbesSuccessfully)
3648+{
3649+ using namespace testing;
3650+ auto block_android = ensure_android_probing_fails();
3651+ auto block_mesa = ensure_mesa_probing_fails();
3652+
3653+
3654+ EXPECT_THROW(mir::graphics::module_for_device(available_platforms()),
3655+ std::runtime_error);
3656+}
3657+
3658+TEST(ServerPlatformProbe, LoadsSupportedModuleWhenNoBestModule)
3659+{
3660+ using namespace testing;
3661+ auto block_android = ensure_android_probing_fails();
3662+ auto block_mesa = ensure_mesa_probing_fails();
3663+
3664+ auto modules = available_platforms();
3665+ add_dummy_platform(modules);
3666+
3667+ auto module = mir::graphics::module_for_device(modules);
3668+ ASSERT_NE(nullptr, module);
3669+
3670+ auto descriptor = module->load_function<mir::graphics::DescribeModule>("describe_module");
3671+ auto description = descriptor();
3672+
3673+ EXPECT_THAT(description->name, HasSubstr("dummy"));
3674+}
3675+
3676+TEST(ServerPlatformProbe, LoadsMesaOrAndroidInPreferenceToDummy)
3677+{
3678+ using namespace testing;
3679+
3680+ auto ensure_mesa = ensure_mesa_probing_succeeds();
3681+ auto ensure_android = ensure_android_probing_succeeds();
3682+
3683+ auto modules = available_platforms();
3684+ add_dummy_platform(modules);
3685+
3686+ auto module = mir::graphics::module_for_device(modules);
3687+ ASSERT_NE(nullptr, module);
3688+
3689+ auto descriptor = module->load_function<mir::graphics::DescribeModule>("describe_module");
3690+ auto description = descriptor();
3691+
3692+ EXPECT_THAT(description->name, Not(HasSubstr("dummy")));
3693+}
3694+
3695+TEST(ServerPlatformProbe, IgnoresNonPlatformModules)
3696+{
3697+ using namespace testing;
3698+
3699+ auto ensure_mesa = ensure_mesa_probing_succeeds();
3700+ auto ensure_android = ensure_android_probing_succeeds();
3701+
3702+ auto modules = available_platforms();
3703+ add_dummy_platform(modules);
3704+
3705+ // NOTE: We want to load something that doesn't link with libmirplatform,
3706+ // due to protobuf throwing a screaming hissy fit if it gets loaded twice.
3707+ modules.push_back(std::make_shared<mir::SharedLibrary>(mtf::library_path() +
3708+ "/client-modules/dummy.so"));
3709+
3710+
3711+ auto module = mir::graphics::module_for_device(modules);
3712+ EXPECT_NE(nullptr, module);
3713+}
3714
3715=== modified file 'tests/unit-tests/shared_library_test.cpp'
3716--- tests/unit-tests/shared_library_test.cpp 2014-11-24 02:16:00 +0000
3717+++ tests/unit-tests/shared_library_test.cpp 2014-11-27 07:32:44 +0000
3718@@ -59,10 +59,10 @@
3719 public:
3720 SharedLibrary()
3721 : nonexistent_library{"imma_totally_not_a_library"},
3722- existing_library{mtf::library_path() + "/" MIR_CLIENT_DRIVER_BINARY},
3723+ existing_library{mtf::library_path() + "/client-modules/mesa.so"},
3724 nonexistent_function{"yo_dawg"},
3725- existing_function{"create_client_platform_factory"},
3726- existent_version{"MIR_CLIENTPLATFORM_1"},
3727+ existing_function{"create_client_platform"},
3728+ existent_version{"MIR_CLIENT_PLATFORM_2"},
3729 nonexistent_version{"GOATS_ON_THE_GREEN"}
3730 {
3731 }
3732
3733=== modified file 'tests/unit-tests/test_shared_library_prober.cpp'
3734--- tests/unit-tests/test_shared_library_prober.cpp 2014-11-24 02:16:00 +0000
3735+++ tests/unit-tests/test_shared_library_prober.cpp 2014-11-27 07:32:44 +0000
3736@@ -26,6 +26,7 @@
3737 #include <cstring>
3738
3739 #include <system_error>
3740+
3741 #include <gtest/gtest.h>
3742 #include <gmock/gmock.h>
3743
3744
3745=== modified file 'tools/install_on_android.sh'
3746--- tools/install_on_android.sh 2014-11-24 02:16:00 +0000
3747+++ tools/install_on_android.sh 2014-11-27 07:32:44 +0000
3748@@ -32,11 +32,12 @@
3749 lib/libmirclient.so.* \
3750 lib/libmircommon.so.* \
3751 lib/libmirplatform.so.* \
3752- lib/libmirplatform*driver.so \
3753- lib/libmirclient*driver.so \
3754+ lib/platform-graphics-dummy.so \
3755+ lib/client-platform-dummy.so \
3756+ lib/client-modules/* \
3757+ lib/server-modules/* \
3758 lib/libmirprotobuf.so.* \
3759 lib/libmirclient-debug-extension.so.* \
3760- lib/libmirplatformstub.so \
3761 lib/libmirserver.so.*
3762 do
3763 adb push $x ${RUN_DIR}
3764
3765=== modified file 'tools/valgrind_suppressions_armhf'
3766--- tools/valgrind_suppressions_armhf 2014-11-24 02:16:00 +0000
3767+++ tools/valgrind_suppressions_armhf 2014-11-27 07:32:44 +0000
3768@@ -127,6 +127,15 @@
3769 # memory errors.
3770
3771 {
3772+ spurious_strlen_addr4
3773+ Memcheck:Addr4
3774+ ...
3775+ fun:dlsym
3776+ ...
3777+ fun:_ZN50SharedLibrary_load_nonexistent_function_fails_Test8TestBodyEv
3778+}
3779+
3780+{
3781 mir_sharedlibrary_cond
3782 Memcheck:Cond
3783 fun:_ZN3mir13SharedLibraryC1EPKc

Subscribers

People subscribed via source and target branches