Mir

Merge lp:~raof/mir/probe-client-drivers into lp:mir

Proposed by Chris Halse Rogers
Status: Superseded
Proposed branch: lp:~raof/mir/probe-client-drivers
Merge into: lp:mir
Diff against target: 2452 lines (+967/-316)
67 files modified
benchmarks/frame-uniformity/main.cpp (+7/-0)
benchmarks/frame-uniformity/touch_measuring_client.cpp (+11/-2)
benchmarks/frame-uniformity/vsync_simulating_graphics_platform.cpp (+8/-3)
cmake/FindGtest.cmake (+2/-3)
cmake/MirCommon.cmake (+23/-0)
cmake/src/wrapper.c (+16/-0)
debian/control (+5/-5)
debian/create_postinst_prerm_scripts.sh (+1/-1)
debian/mir-client-platform-android.install (+1/-1)
debian/mir-client-platform-mesa.install (+1/-1)
debian/mir-test-tools.install (+1/-0)
debian/rules (+3/-6)
examples/CMakeLists.txt (+19/-48)
playground/demo-shell/CMakeLists.txt (+1/-3)
src/CMakeLists.txt (+1/-0)
src/client/CMakeLists.txt (+18/-16)
src/client/android/CMakeLists.txt (+7/-22)
src/client/android/android_native_display_container.cpp (+12/-4)
src/client/android/android_native_display_container.h (+10/-3)
src/client/android/client_platform_factory.cpp (+22/-5)
src/client/android/client_platform_factory.h (+2/-5)
src/client/android/symbols.map (+5/-4)
src/client/client_context.h (+2/-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 (+20/-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/mir_surface_api.cpp (+4/-2)
src/client/probing_client_platform_factory.cpp (+38/-0)
src/client/probing_client_platform_factory.h (+27/-0)
src/common/symbols.map (+7/-8)
tests/CMakeLists.txt (+9/-1)
tests/acceptance-tests/CMakeLists.txt (+2/-8)
tests/acceptance-tests/test_client_library.cpp (+5/-4)
tests/acceptance-tests/test_client_library_drm.cpp (+9/-4)
tests/acceptance-tests/test_symbols_required_by_mesa.cpp (+5/-2)
tests/include/mir_test_doubles/mock_client_context.h (+0/-6)
tests/include/mir_test_doubles/stub_client_buffer.h (+4/-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_platform_helpers.h (+53/-0)
tests/integration-tests/CMakeLists.txt (+1/-6)
tests/mir_test_doubles/CMakeLists.txt (+3/-2)
tests/mir_test_framework/CMakeLists.txt (+30/-4)
tests/mir_test_framework/stub_client_platform_factory.cpp (+74/-0)
tests/mir_test_framework/stub_client_platform_module.cpp (+41/-0)
tests/mir_test_framework/stubbed_graphics_platform.cpp (+5/-1)
tests/mir_test_framework/symbols-client.map (+7/-0)
tests/unit-tests/CMakeLists.txt (+1/-6)
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 (+122/-29)
tests/unit-tests/client/test_probing_client_platform_factory.cpp (+142/-0)
tests/unit-tests/shared_library_test.cpp (+3/-3)
To merge this branch: bzr merge lp:~raof/mir/probe-client-drivers
Reviewer Review Type Date Requested Status
Robert Carr (community) Approve
Alexandros Frantzis (community) Abstain
PS Jenkins bot (community) continuous-integration Needs Fixing
Daniel van Vugt Abstain
Alan Griffiths Needs Fixing
Andreas Pokorny (community) Approve
Cemil Azizoglu (community) Approve
Review via email: mp+243103@code.launchpad.net

This proposal has been superseded by a proposal from 2014-12-12.

Commit message

Add probing for client platform modules.

The client library now looks in MIR_CLIENT_PLATFORM_PATH (usually /usr/lib/*/mir/client-platform) and loads all the modules it finds in there. At connection time each of those modules are checked whether the MirPlatformPackage matches what they expect; the first one that matches is used.

Description of the change

The smallest individually landable piece of proper driver probing; the client library side of it.

To post a comment you must log in.
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

(1) Orphaned comment now needs removing:
16 # Why does this have to come after mir-test-framework here but not in tests/acceptance-tests/
17 # /CMakeLists.txt? ~racarr
18 - mirplatform

(2) Unnecessary (and undesirable) formatting changes:
221 -target_link_libraries(mirclient
222 +target_link_libraries(
223 + mirclient
224 +
because the first parameter is special and independent of those that follow it.

(3) Remind me why we wanted a C calling convention for C++ code?
372 +extern "C" std::shared_ptr<mcl::ClientPlatform>

(4) Minor optimization: You can avoid a template instantiation using std::atomic_bool for
898 + std::atomic<bool> connect_done;

(5) Fatal: Clients don't start any more:
$ bin/mir_demo_client_egltriangle
Can't get connection
$ bin/mir_demo_client_flicker
Starting
mir_demo_client_flicker: /home/dan/bzr/mir/tmp.pcd/examples/flicker.c:134: main: Assertion `mir_connection_is_valid(connection)' failed.

(6) ProbingClientPlatformFactory sounds a bit awkward. Although I haven't stopped to understand the code enough to suggest anything better yet.

(7) New (old) function exposed without a new stanza. Should be MIR_COMMON_3.1 (?)
980 +++ src/common/symbols.map 2014-11-28 05:44:33 +0000
981 @@ -150,6 +150,7 @@
982 # but they are used by libmirplatform, libmirclient or libmirserver
983 mir::default_server_socket;
984 mir::input::android::Lexicon::translate*;
985 + mir::libraries_for_path*;

review: Needs Fixing
Revision history for this message
Chris Halse Rogers (raof) wrote :

(3) We need C calling convention because I'm not going to write load_symbol("_Zsharedptr23mirZclientZ23PIZZA22112stinkybobo888zzz") :)

(5) PEBCAK - You're trying to run those uninstalled; the client library is (probably) looking for platform modules in /usr/local/mir/client-platform/, and not finding them. If our examples actually called mir_connection_get_error() then you'd see that error :).

Set MIR_CLIENT_PLATFORM_PATH=$(pwd)/lib/client-modules and it'll work uninstalled.

I'll fix the rest.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

> Set MIR_CLIENT_PLATFORM_PATH=$(pwd)/lib/client-modules and it'll work uninstalled.

Note that it's not just the examples but also the tests that need this.

This is bad in two ways:

1. It's more complicated to run executables from inside the build dir.
2. Forgetting to set the proper path may lead to platform libraries from the system being used inadvertently, instead of the expected ones from inside the build dir.

Until now, executing anything from inside the build dir was guaranteed to prefer code from that directory (due to cmake setting RPATH). This setup has served us well and I think we should keep it, even if doing so involves some hackery.

One way would be to search for platform libs in all the places the dynamic linker would look for, but unfortunately there doesn't seem to be a way to access the shared library search paths directly.

Another way would be to take advantage of the RPATH setting, for example:

1. Create a mir/libmirtestconfig.so which exports symbols/functions to get the test platform search path
2. Build it in build/lib/, but don't install it.
3. When figuring out where to search for the platform libs ([1]), try to load the mir/libmirtestconfig.so library and get the test path.
  3.1. In case of an executable/library from the build dir, mir/libmirtestconfig.so will be found (due to RPATH) and the test values will be used.
  3.2. In case of an installed executable/library no RPATH is present and mir/libmirtestconfig.so will not be found.

[1] In mcl::DefaultConnectionConfiguration::the_client_platform_factory()

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

> (5) PEBCAK - You're trying to run those uninstalled; the client library is
> (probably) looking for platform modules in /usr/local/mir/client-platform/,
> and not finding them. If our examples actually called
> mir_connection_get_error() then you'd see that error :).
>
> Set MIR_CLIENT_PLATFORM_PATH=$(pwd)/lib/client-modules and it'll work
> uninstalled.

That doesn't seem like an adequate answer:

We've always been able to run the built binaries from within the build tree (cmake does rpath magic).

This makes it far too easy to accidentally load the wrong (installed) binaries. Could we e.g. look relative to the current library?

review: Needs Fixing
Revision history for this message
Robert Carr (robertcarr) wrote :

Seems ok but yeah it would be nice to load from the build dir. One trick ive seen is to use wrapper scripts for the binaries in the build-dir (not installed of course) which exports the appropriate var.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

I like the idea of taking advantage of RPATH. One of the best (and worst) things about CMake is its RPATH behaviour. And it's designed that way precisely so you can run things in-situ within the source tree. Haven't assessed alf's plan in detail though.

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

There's a hint in the dlopen docs about how it might be achieved:

   dlopen()
       ...
       o (ELF only) If the executable file for the calling program contains
           a DT_RPATH tag, and does not contain a DT_RUNPATH tag, then the
           directories listed in the DT_RPATH tag are searched.

Revision history for this message
Chris Halse Rogers (raof) wrote :

Yeah, dlopen("libmirtestconfig.so") would work.

I'm doing the CMakery required to provide wrapper scripts, though. I
strongly prefer that the release build not contain code required only
to set up the test environment.

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

> I'm doing the CMakery required to provide wrapper scripts, though

Please make sure that it's still easy to run the examples and tests with gdb/valgrind/other tools.

Revision history for this message
Cemil Azizoglu (cemil-azizoglu) wrote :

Needs information:

Has this been tested under chroot/sbuild? (We don't wanna have last minute packaging issues during release.)

Nits/Comments:
719 + // TODO: Actually check what platform we're using, rather than blindly

Perhaps MirPlatformPackage should include a "platform signature". Something like "MESA", "ANDR", "STUB".
-----------------------
android.so, mesa.so, dummy.so are too generic. client-platform-{android|mesa|dummy}.so perhaps?

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

@Cemil - tested, and passed, under sbuild.

I think I'd like to handle platform discovery a slightly different way; at the moment, MirPlatformPackage contains enough data to be a unique signature in itself.

The drivers are android.so, mesa.so, etc because they're in the client-platform/ directory. Their full name looks like client-platform/mesa.so, client-platform/android.so, etc.

I think client-platform/client-platform-mesa.so, etc look a bit silly :)

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

$MIR_CLIENT_PLATFORM_PATH and the executable_path() hack looks fragile.

We could write DefaultConnectionConfiguration::the_client_platform_factory() to use dladdr() to locate libmirclient.so and locate the client-modules directory relative to that? (which should be the same in tree and installed.)

review: Needs Fixing
Revision history for this message
Chris Halse Rogers (raof) wrote :

I'm not entirely sure what you think is fragile about executable_path()? We're already using it elsewhere in the tests.

If you're concerned about the ../lib/ relative path, then; whoops! Now uses mtf::library_path().

I much prefer the current solution to using dladdr() in the release code. Using dladdr() we make some assumptions about the code that the compiler emits and if those assumptions fail then our release code fails. If the assumptions we set MIR_CLIENT_PLATFORM_PATH based on fail then at worst our test suite fails.

Regardless of how we find the platform libraries by default we'll want a MIR_CLIENT_PLATFORM_PATH option for roughly the same reasons that we have a MIR_CLIENT_PLATFORM_LIB option.

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

There already is a stub_client_buffer{_factory}.h do we need a different one?

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

> I'm not entirely sure what you think is fragile about executable_path()? We're
> already using it elsewhere in the tests.

Having looked again I think I misunderstood how this solution works. It isn't as bad as I thought.

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

183 === added file 'cmake/wrapper-script'
184 --- cmake/wrapper-script 1970-01-01 00:00:00 +0000
185 +++ cmake/wrapper-script 2014-12-03 22:58:17 +0000
186 @@ -0,0 +1,5 @@
187 +#!/bin/sh
188 +
189 +export MIR_CLIENT_PLATFORM_PATH=@BUILD_PREFIX@/lib/client-modules
190 +
191 +exec @BUILD_PREFIX@/bin/@EXECUTABLE@ $@

Isn't this obsolete?

review: Needs Fixing
Revision history for this message
Cemil Azizoglu (cemil-azizoglu) wrote :

> @Cemil - tested, and passed, under sbuild.

Great. How about testing downstreams by installing the generated packages?

review: Needs Information
Revision history for this message
Chris Halse Rogers (raof) wrote :

@Cemil - downstreams built and happy.

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

62 +#include <error.h>
...
73 + error(1, 0, "Surface creation failed: %s\n", mir_surface_get_error_message(surface));

I think this is our first use of this GNU extension. I'm not opposed, but think it needs discussion before adding this dependency.

~~~~

671 + auto it = valid_displays.find(display);
672 + if (it == valid_displays.end())
673 + return;
674 +
675 + valid_displays.erase(it);

AFICS this is a verbose and inefficient

    valid_displays.erase(display);

But I wouldn't block on it as it isn't a critical path.

~~~~

741 + throw new std::runtime_error{"Attempted to create Android client platform on non-Android server"};

1. Don't throw pointers
2. Use BOOST_THROW_EXCEPTION

~~~~

1067 + throw std::runtime_error{"Attempted to create Mesa client platform on non-Mesa server"};
...
1602 + throw std::logic_error{"Must call one of create_*_client_platform() before calling get_platform_library()"};

Use BOOST_THROW_EXCEPTION

review: Needs Fixing
Revision history for this message
Cemil Azizoglu (cemil-azizoglu) wrote :

Assuming downstreams not just build, but also run happily, I have no more to add.

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

Diff against target: 2448 lines (+975/-294) 68 files modified (has conflicts)

Text conflict in examples/CMakeLists.txt

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

(2) Unnecessary (and undesirable) formatting changes:
575 -target_link_libraries(mirclient
576 +target_link_libraries(
577 + mirclient
578 +
because the first parameter is special and independent of those that follow it.

(4) Minor optimization: You can avoid a template instantiation using std::atomic_bool for
1250 + std::atomic<bool> connect_done;

(8) The library re-ordering appears to be pointless, or is there a reason?...
benchmarks/frame-uniformity/CMakeLists.txt
Can we revert all changes to that file?

(9) Clients now start, but the wrapper that makes it possible feels inelegant...
$ ls -a bin/
mir_acceptance_tests
.mir_acceptance_tests-uninstalled
mir_demo_client_basic
.mir_demo_client_basic-uninstalled
mir_demo_client_cursors
.mir_demo_client_cursors-uninstalled
mir_demo_client_display_config
.mir_demo_client_display_config-uninstalled
mir_demo_client_eglcounter
.mir_demo_client_eglcounter-uninstalled
...
I suspect we can do better without needing a wrapper. But if we do use this then please don't hide binaries from developers: ".foo-uninstalled" should be "foo.bin"

(10) wrapper.c compiles to 10KB, but could be replaced with a trivial shell script instead.

(11) This is new on the end. What's it do?
1343 +} MIR_COMMON_3;

review: Needs Fixing
Revision history for this message
Chris Halse Rogers (raof) wrote :

On Wed, Dec 10, 2014 at 2:44 PM, Daniel van Vugt
<email address hidden> wrote:
> Review: Needs Fixing
>
> (2) Unnecessary (and undesirable) formatting changes:
> 575 -target_link_libraries(mirclient
> 576 +target_link_libraries(
> 577 + mirclient
> 578 +
> because the first parameter is special and independent of those that
> follow it.
>
> (4) Minor optimization: You can avoid a template instantiation using
> std::atomic_bool for
> 1250 + std::atomic<bool> connect_done;
>
> (8) The library re-ordering appears to be pointless, or is there a
> reason?...
> benchmarks/frame-uniformity/CMakeLists.txt
> Can we revert all changes to that file?
>
> (9) Clients now start, but the wrapper that makes it possible feels
> inelegant...
> $ ls -a bin/
> mir_acceptance_tests
> .mir_acceptance_tests-uninstalled
> mir_demo_client_basic
> .mir_demo_client_basic-uninstalled
> mir_demo_client_cursors
> .mir_demo_client_cursors-uninstalled
> mir_demo_client_display_config
> .mir_demo_client_display_config-uninstalled
> mir_demo_client_eglcounter
> .mir_demo_client_eglcounter-uninstalled
> ...
> I suspect we can do better without needing a wrapper. But if we do
> use this then please don't hide binaries from developers:
> ".foo-uninstalled" should be "foo.bin"

I think we need one of (a) a wrapper, or (b) code in the libraries we
release solely there to negate the need for a trivial wrapper.

Choosing (b) introduces the possibility of otherwise-unnecessary code
having user-visible bugs, so I chose (a).

I hid the real binaries in the time-honoured tradition of libtool
(which uses wrapper scripts, and hides everything in a .libs/
directory). You've got a choice between developers going “why are
there all these *.bin that don't work when I try to run them lying
around in my build tree” and “why are there all these hidden
binaries lying around in my build tree”.

I think hidden files are less confusing. The (normal) directory listing
lists everything you should be running.

> (10) wrapper.c compiles to 10KB, but could be replaced with a trivial
> shell script instead.

Said shell script makes it more difficult to run gdb which is why I
switched to wrapper.c.

>
> (11) This is new on the end. What's it do?
> 1343 +} MIR_COMMON_3;

“MIR_COMMON_3.1 depends on MIR_COMMON_3”

Revision history for this message
Chris Halse Rogers (raof) wrote :

> (4) Minor optimization: You can avoid a template instantiation using
> std::atomic_bool for
> 1250 + std::atomic<bool> connect_done;

We already use std::atomic<bool> elsewhere, so this saves no template instatiations.

Also, std::atomic_bool is not the same as std::atomic<bool>. It's a vestigial attempt to match possibly C1y threading support.

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

looks good to me.

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

I'm not keen on the wrapper trick, but won't block when I don't have a better idea.

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

Text conflict in benchmarks/frame-uniformity/vsync_simulating_graphics_platform.cpp
1 conflicts encountered.

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

I still believe we could bend rpath* to our will and avoid wrappers. Although it's not impossible to figure that part out later and then drop the wrapper.

As for the minor cleanups, I still recommend resolving them. But I haven't revised this branch in detail. The end goal is rather important even if parts of the solution feel a bit ugly. I don't want to block it either.

review: Abstain
Revision history for this message
Chris Halse Rogers (raof) wrote :

I think I *have* resolved all your minor cleanups, with the exception
of replacing std::atomic<bool> with the non-equivalent std::atomic_bool.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Alexandros Frantzis (afrantzis) :
review: Abstain
Revision history for this message
Robert Carr (robertcarr) wrote :

LGTM. Happy we can still run gdb on the wrappers.

Surprised by the gtest matcher used outside of expectation setting at l1901

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'benchmarks/frame-uniformity/main.cpp'
--- benchmarks/frame-uniformity/main.cpp 2014-10-26 02:13:36 +0000
+++ benchmarks/frame-uniformity/main.cpp 2014-12-12 01:38:38 +0000
@@ -17,6 +17,7 @@
17 */17 */
1818
19#include "frame_uniformity_test.h"19#include "frame_uniformity_test.h"
20#include "mir_test_framework/executable_path.h"
2021
21#include <assert.h>22#include <assert.h>
22#include <cmath>23#include <cmath>
@@ -27,6 +28,7 @@
27#include <gtest/gtest.h>28#include <gtest/gtest.h>
2829
29namespace geom = mir::geometry;30namespace geom = mir::geometry;
31namespace mtf = mir_test_framework;
3032
31namespace33namespace
32{34{
@@ -116,6 +118,11 @@
116 int const run_count = 1;118 int const run_count = 1;
117 double average_lag = 0, average_uniformity = 0;119 double average_lag = 0, average_uniformity = 0;
118120
121 // Ensure we load the correct platform libraries
122 setenv("MIR_CLIENT_PLATFORM_PATH",
123 (mtf::library_path() + "/client-modules").c_str(),
124 true);
125
119 for (int i = 0; i < run_count; i++)126 for (int i = 0; i < run_count; i++)
120 {127 {
121 FrameUniformityTest t({screen_size, touch_start_point, touch_end_point, touch_duration});128 FrameUniformityTest t({screen_size, touch_start_point, touch_end_point, touch_duration});
122129
=== modified file 'benchmarks/frame-uniformity/touch_measuring_client.cpp'
--- benchmarks/frame-uniformity/touch_measuring_client.cpp 2014-10-26 02:13:36 +0000
+++ benchmarks/frame-uniformity/touch_measuring_client.cpp 2014-12-12 01:38:38 +0000
@@ -26,6 +26,7 @@
26#include <memory>26#include <memory>
27#include <vector>27#include <vector>
2828
29#include <iostream>
29#include <assert.h>30#include <assert.h>
3031
31namespace mt = mir::test;32namespace mt = mir::test;
@@ -45,7 +46,11 @@
45 mir_display_output_id_invalid};46 mir_display_output_id_invalid};
46 47
47 auto surface = mir_connection_create_surface_sync(connection, &surface_params);48 auto surface = mir_connection_create_surface_sync(connection, &surface_params);
48 assert(mir_surface_is_valid(surface));49 if (!mir_surface_is_valid(surface))
50 {
51 std::cerr << "Surface creation failed: " << mir_surface_get_error_message(surface) << std::endl;
52 exit(1);
53 }
4954
50 return surface;55 return surface;
51}56}
@@ -93,7 +98,11 @@
93void TouchMeasuringClient::run(std::string const& connect_string)98void TouchMeasuringClient::run(std::string const& connect_string)
94{99{
95 auto connection = mir_connect_sync(connect_string.c_str(), "frame-uniformity-test");100 auto connection = mir_connect_sync(connect_string.c_str(), "frame-uniformity-test");
96 assert(mir_connection_is_valid(connection));101 if (!mir_connection_is_valid(connection))
102 {
103 std::cerr << "Connection to Mir failed: " << mir_connection_get_error_message(connection) << std::endl;
104 exit(1);
105 }
97 106
98 /*107 /*
99 * Set a null callback to avoid killing the process108 * Set a null callback to avoid killing the process
100109
=== modified file 'benchmarks/frame-uniformity/vsync_simulating_graphics_platform.cpp'
--- benchmarks/frame-uniformity/vsync_simulating_graphics_platform.cpp 2014-12-10 06:31:45 +0000
+++ benchmarks/frame-uniformity/vsync_simulating_graphics_platform.cpp 2014-12-12 01:38:38 +0000
@@ -24,9 +24,11 @@
2424
25#include "mir_test_doubles/stub_buffer_allocator.h"25#include "mir_test_doubles/stub_buffer_allocator.h"
26#include "mir_test_doubles/stub_display.h"26#include "mir_test_doubles/stub_display.h"
27#include "mir_test_framework/stub_platform_helpers.h"
2728
28#include <chrono>29#include <chrono>
29#include <functional>30#include <functional>
31#include <boost/throw_exception.hpp>
3032
31namespace mg = mir::graphics;33namespace mg = mir::graphics;
32namespace geom = mir::geometry;34namespace geom = mir::geometry;
@@ -59,12 +61,15 @@
5961
60 std::shared_ptr<mg::PlatformIPCPackage> connection_ipc_package() override62 std::shared_ptr<mg::PlatformIPCPackage> connection_ipc_package() override
61 {63 {
62 return std::make_shared<mg::PlatformIPCPackage>();64 auto package = std::make_shared<mg::PlatformIPCPackage>();
65 mir_test_framework::pack_stub_ipc_package(*package);
66 return package;
63 }67 }
6468
65 mg::PlatformIPCPackage platform_operation(unsigned int const, mg::PlatformIPCPackage const&) override69 mg::PlatformIPCPackage platform_operation(const unsigned int,
70 mg::PlatformIPCPackage const&) override
66 {71 {
67 return mg::PlatformIPCPackage();72 BOOST_THROW_EXCEPTION((std::runtime_error{"Stub platform has no operations"}));
68 }73 }
69};74};
7075
7176
=== modified file 'cmake/FindGtest.cmake'
--- cmake/FindGtest.cmake 2014-11-24 03:09:00 +0000
+++ cmake/FindGtest.cmake 2014-12-12 01:38:38 +0000
@@ -20,10 +20,9 @@
20set(GMOCK_BINARY_DIR ${CMAKE_BINARY_DIR}/${GMOCK_PREFIX}/libs)20set(GMOCK_BINARY_DIR ${CMAKE_BINARY_DIR}/${GMOCK_PREFIX}/libs)
21set(GTEST_BINARY_DIR ${GMOCK_BINARY_DIR}/gtest)21set(GTEST_BINARY_DIR ${GMOCK_BINARY_DIR}/gtest)
2222
23set(GTEST_CMAKE_ARGS "")23set(GTEST_CMAKE_ARGS "-DCMAKE_CXX_FLAGS=-fPIC")
24if (${CMAKE_CROSSCOMPILING})24if (${CMAKE_CROSSCOMPILING})
25 set(GTEST_CMAKE_ARGS25 list(APPEND GTEST_CMAKE_ARGS -DCMAKE_TOOLCHAIN_FILE=${CMAKE_MODULE_PATH}/LinuxCrossCompile.cmake)
26 -DCMAKE_TOOLCHAIN_FILE=${CMAKE_MODULE_PATH}/LinuxCrossCompile.cmake)
27endif()26endif()
2827
29ExternalProject_Add(28ExternalProject_Add(
3029
=== modified file 'cmake/MirCommon.cmake'
--- cmake/MirCommon.cmake 2014-12-08 04:03:47 +0000
+++ cmake/MirCommon.cmake 2014-12-12 01:38:38 +0000
@@ -168,3 +168,26 @@
168 add_dependencies(${TARGET} ${TARGET}_pch)168 add_dependencies(${TARGET} ${TARGET}_pch)
169 endif()169 endif()
170endfunction()170endfunction()
171
172function (mir_add_wrapped_executable TARGET)
173 set(REAL_EXECUTABLE .${TARGET}-uninstalled)
174 add_executable(${TARGET} ${ARGN})
175 set_target_properties(${TARGET} PROPERTIES OUTPUT_NAME ${REAL_EXECUTABLE})
176
177 add_executable(${TARGET}-wrapper ${PROJECT_SOURCE_DIR}/cmake/src/wrapper.c)
178 set_property(TARGET ${TARGET}-wrapper
179 APPEND_STRING PROPERTY COMPILE_FLAGS " -DEXECUTABLE=\\\"${REAL_EXECUTABLE}\\\"")
180 set_property(TARGET ${TARGET}-wrapper
181 APPEND_STRING PROPERTY COMPILE_FLAGS " -DBUILD_PREFIX=\\\"${CMAKE_BINARY_DIR}\\\"")
182 set_property(TARGET ${TARGET}-wrapper
183 APPEND_STRING PROPERTY COMPILE_FLAGS " -D_BSD_SOURCE")
184 set_property(TARGET ${TARGET}-wrapper
185 PROPERTY OUTPUT_NAME ${TARGET})
186
187 add_dependencies(${TARGET} ${TARGET}-wrapper)
188
189 install(PROGRAMS ${CMAKE_BINARY_DIR}/bin/${REAL_EXECUTABLE}
190 DESTINATION ${CMAKE_INSTALL_BINDIR}
191 RENAME ${TARGET}
192 )
193endfunction()
171194
=== added file 'cmake/src/wrapper.c'
--- cmake/src/wrapper.c 1970-01-01 00:00:00 +0000
+++ cmake/src/wrapper.c 2014-12-12 01:38:38 +0000
@@ -0,0 +1,16 @@
1#include <stdlib.h>
2#include <stdio.h>
3#include <unistd.h>
4#include <assert.h>
5
6int main(int argc, char** argv)
7{
8 assert(argc > 0);
9 setenv("MIR_CLIENT_PLATFORM_PATH", BUILD_PREFIX "/lib/client-modules/", 1);
10
11 argv[0] = BUILD_PREFIX "/bin/" EXECUTABLE;
12 execv(argv[0], argv);
13
14 perror("Failed to execute real binary " EXECUTABLE);
15 return 1;
16}
017
=== modified file 'debian/control'
--- debian/control 2014-12-08 04:03:47 +0000
+++ debian/control 2014-12-12 01:38:38 +0000
@@ -143,7 +143,7 @@
143Pre-Depends: ${misc:Pre-Depends}143Pre-Depends: ${misc:Pre-Depends}
144Depends: ${misc:Depends},144Depends: ${misc:Depends},
145 ${shlibs:Depends},145 ${shlibs:Depends},
146 libmir${client-driver}-mesa | libmir${client-driver}-android,146 mir-client-platform-mesa | mir-client-platform-android,
147Description: Display server for Ubuntu - client library147Description: Display server for Ubuntu - client library
148 Mir is a display server running on linux systems, with a focus on efficiency,148 Mir is a display server running on linux systems, with a focus on efficiency,
149 robust operation and a well-defined driver model.149 robust operation and a well-defined driver model.
@@ -265,7 +265,7 @@
265 Contains the shared libraries required for the Mir server and client.265 Contains the shared libraries required for the Mir server and client.
266266
267# Longer-term these drivers should move out-of-tree267# Longer-term these drivers should move out-of-tree
268Package: libmirclient8driver-mesa268Package: mir-client-platform-mesa
269Section: libs269Section: libs
270Architecture: i386 amd64 armhf arm64270Architecture: i386 amd64 armhf arm64
271Multi-Arch: same271Multi-Arch: same
@@ -279,7 +279,7 @@
279 Contains the shared libraries required for the Mir clients to interact with279 Contains the shared libraries required for the Mir clients to interact with
280 the underlying hardware platform using the Mesa drivers.280 the underlying hardware platform using the Mesa drivers.
281281
282Package: libmirclient8driver-android282Package: mir-client-platform-android
283Section: libs283Section: libs
284Architecture: i386 amd64 armhf284Architecture: i386 amd64 armhf
285Multi-Arch: same285Multi-Arch: same
@@ -328,7 +328,7 @@
328Pre-Depends: ${misc:Pre-Depends}328Pre-Depends: ${misc:Pre-Depends}
329Depends: ${misc:Depends},329Depends: ${misc:Depends},
330 libmir${platform-driver}-mesa,330 libmir${platform-driver}-mesa,
331 libmir${client-driver}-mesa331 mir-client-platform-mesa
332Description: Display server for Ubuntu - desktop driver metapackage332Description: Display server for Ubuntu - desktop driver metapackage
333 Mir is a display server running on linux systems, with a focus on efficiency,333 Mir is a display server running on linux systems, with a focus on efficiency,
334 robust operation and a well-defined driver model.334 robust operation and a well-defined driver model.
@@ -343,7 +343,7 @@
343Pre-Depends: ${misc:Pre-Depends}343Pre-Depends: ${misc:Pre-Depends}
344Depends: ${misc:Depends},344Depends: ${misc:Depends},
345 libmir${platform-driver}-android,345 libmir${platform-driver}-android,
346 libmir${client-driver}-android346 mir-client-platform-android
347Description: Display server for Ubuntu - android driver metapackage347Description: Display server for Ubuntu - android driver metapackage
348 Mir is a display server running on linux systems, with a focus on efficiency,348 Mir is a display server running on linux systems, with a focus on efficiency,
349 robust operation and a well-defined driver model.349 robust operation and a well-defined driver model.
350350
=== modified file 'debian/create_postinst_prerm_scripts.sh'
--- debian/create_postinst_prerm_scripts.sh 2014-12-08 04:03:47 +0000
+++ debian/create_postinst_prerm_scripts.sh 2014-12-12 01:38:38 +0000
@@ -6,7 +6,7 @@
6deb_host_arch=$16deb_host_arch=$1
7deb_host_multiarch=$27deb_host_multiarch=$2
88
9mir_platform_types="${PLATFORM_DRIVER} ${CLIENT_DRIVER}"9mir_platform_types="${PLATFORM_DRIVER}"
10case $deb_host_arch in10case $deb_host_arch in
11 arm64)11 arm64)
12 mir_platforms="mesa"12 mir_platforms="mesa"
1313
=== renamed file 'debian/libmirclient8driver-android.install' => 'debian/mir-client-platform-android.install'
--- debian/libmirclient8driver-android.install 2014-12-08 04:03:47 +0000
+++ debian/mir-client-platform-android.install 2014-12-12 01:38:38 +0000
@@ -1,1 +1,1 @@
1usr/lib/*/mir/client*driver/android/*1usr/lib/*/mir/client-platform/android.so
22
=== renamed file 'debian/libmirclient8driver-mesa.install' => 'debian/mir-client-platform-mesa.install'
--- debian/libmirclient8driver-mesa.install 2014-12-08 04:03:47 +0000
+++ debian/mir-client-platform-mesa.install 2014-12-12 01:38:38 +0000
@@ -1,1 +1,1 @@
1usr/lib/*/mir/client*driver/mesa/*1usr/lib/*/mir/client-platform/mesa.so
22
=== modified file 'debian/mir-test-tools.install'
--- debian/mir-test-tools.install 2014-12-08 04:03:47 +0000
+++ debian/mir-test-tools.install 2014-12-12 01:38:38 +0000
@@ -6,3 +6,4 @@
6usr/lib/*/mir/tools/libmirclientlttng.so6usr/lib/*/mir/tools/libmirclientlttng.so
7usr/lib/*/mir/tools/libmirserverlttng.so7usr/lib/*/mir/tools/libmirserverlttng.so
8usr/lib/*/libmirplatformstub.so8usr/lib/*/libmirplatformstub.so
9usr/lib/*/mir/client-platform/dummy.so
910
=== modified file 'debian/rules'
--- debian/rules 2014-12-08 04:03:47 +0000
+++ debian/rules 2014-12-12 01:38:38 +0000
@@ -14,7 +14,6 @@
14export CXX=$(DEB_HOST_GNU_TYPE)-g++-4.914export CXX=$(DEB_HOST_GNU_TYPE)-g++-4.9
1515
16export PLATFORM_DRIVER = platform5driver16export PLATFORM_DRIVER = platform5driver
17export CLIENT_DRIVER = client8driver
1817
19%:18%:
20 dh $@ --parallel --fail-missing19 dh $@ --parallel --fail-missing
@@ -57,10 +56,9 @@
57# Nothing outside Mir should link to libmirprotobuf directly.56# Nothing outside Mir should link to libmirprotobuf directly.
58# Delete the symlink so that --fail-missing doesn't think we've missed it57# Delete the symlink so that --fail-missing doesn't think we've missed it
59# accidentally.58# accidentally.
60 rm debian/tmp/usr/lib/*/libmirprotobuf.so59 -rm debian/tmp/usr/lib/*/libmirprotobuf.so
61 dh_install --fail-missing \60 dh_install --fail-missing \
62 -Xusr/lib/$(DEB_HOST_MULTIARCH)/libmir$(PLATFORM_DRIVER).so \61 -Xusr/lib/$(DEB_HOST_MULTIARCH)/libmir$(PLATFORM_DRIVER).so
63 -Xusr/lib/$(DEB_HOST_MULTIARCH)/libmir$(CLIENT_DRIVER).so
64 sh debian/install_ld_so_conf.sh $(DEB_HOST_ARCH) $(DEB_HOST_MULTIARCH)62 sh debian/install_ld_so_conf.sh $(DEB_HOST_ARCH) $(DEB_HOST_MULTIARCH)
6563
66override_dh_installdeb:64override_dh_installdeb:
@@ -70,5 +68,4 @@
7068
71override_dh_gencontrol:69override_dh_gencontrol:
72 dh_gencontrol -- \70 dh_gencontrol -- \
73 -Vplatform-driver=$(PLATFORM_DRIVER) \71 -Vplatform-driver=$(PLATFORM_DRIVER)
74 -Vclient-driver=$(CLIENT_DRIVER)
7572
=== modified file 'examples/CMakeLists.txt'
--- examples/CMakeLists.txt 2014-12-11 03:56:10 +0000
+++ examples/CMakeLists.txt 2014-12-12 01:38:38 +0000
@@ -31,38 +31,38 @@
31 ${EGL_LIBRARIES}31 ${EGL_LIBRARIES}
32 ${GLESv2_LIBRARIES}32 ${GLESv2_LIBRARIES}
33)33)
34add_executable(mir_demo_client_eglflash34mir_add_wrapped_executable(mir_demo_client_eglflash
35 eglflash.c35 eglflash.c
36)36)
37target_link_libraries(mir_demo_client_eglflash37target_link_libraries(mir_demo_client_eglflash
38 eglapp38 eglapp
39)39)
40add_executable(mir_demo_client_egltriangle40mir_add_wrapped_executable(mir_demo_client_egltriangle
41 egltriangle.c41 egltriangle.c
42)42)
43target_link_libraries(mir_demo_client_egltriangle43target_link_libraries(mir_demo_client_egltriangle
44 eglapp44 eglapp
45)45)
46add_executable(mir_demo_client_eglcounter46mir_add_wrapped_executable(mir_demo_client_eglcounter
47 eglcounter.cpp47 eglcounter.cpp
48)48)
49target_link_libraries(mir_demo_client_eglcounter49target_link_libraries(mir_demo_client_eglcounter
50 eglapp50 eglapp
51)51)
52add_executable(mir_demo_client_eglplasma52mir_add_wrapped_executable(mir_demo_client_eglplasma
53 eglplasma.c53 eglplasma.c
54)54)
55target_link_libraries(mir_demo_client_eglplasma55target_link_libraries(mir_demo_client_eglplasma
56 eglapp56 eglapp
57)57)
58add_executable(mir_demo_client_cursors58mir_add_wrapped_executable(mir_demo_client_cursors
59 cursors_demo_client.c59 cursors_demo_client.c
60)60)
61target_link_libraries(mir_demo_client_cursors61target_link_libraries(mir_demo_client_cursors
62 eglapp62 eglapp
63)63)
6464
65add_executable(mir_demo_client_basic65mir_add_wrapped_executable(mir_demo_client_basic
66 basic.c66 basic.c
67)67)
6868
@@ -74,22 +74,22 @@
74 ${CMAKE_THREAD_LIBS_INIT}74 ${CMAKE_THREAD_LIBS_INIT}
75)75)
7676
77add_executable(mir_test_client_release_at_exit release_at_exit.c)77mir_add_wrapped_executable(mir_demo_client_release_at_exit release_at_exit.c)
78target_link_libraries(mir_test_client_release_at_exit mirclient)78target_link_libraries(mir_demo_client_release_at_exit mirclient)
7979
80add_executable(mir_demo_client_multiwin multiwin.c)80mir_add_wrapped_executable(mir_demo_client_multiwin multiwin.c)
81target_link_libraries(mir_demo_client_multiwin mirclient)81target_link_libraries(mir_demo_client_multiwin mirclient)
8282
83add_executable(mir_demo_client_fingerpaint fingerpaint.c)83mir_add_wrapped_executable(mir_demo_client_fingerpaint fingerpaint.c)
84target_link_libraries(mir_demo_client_fingerpaint mirclient)84target_link_libraries(mir_demo_client_fingerpaint mirclient)
8585
86add_executable(mir_demo_client_progressbar progressbar.c)86mir_add_wrapped_executable(mir_demo_client_progressbar progressbar.c)
87target_link_libraries(mir_demo_client_progressbar mirclient)87target_link_libraries(mir_demo_client_progressbar mirclient)
8888
89add_executable(mir_demo_client_display_config demo_client_display_config.c)89mir_add_wrapped_executable(mir_demo_client_display_config demo_client_display_config.c)
90target_link_libraries(mir_demo_client_display_config eglapp)90target_link_libraries(mir_demo_client_display_config eglapp)
9191
92add_executable(mir_demo_client_flicker92mir_add_wrapped_executable(mir_demo_client_flicker
93 flicker.c93 flicker.c
94)94)
9595
@@ -101,7 +101,7 @@
101 ${CMAKE_THREAD_LIBS_INIT}101 ${CMAKE_THREAD_LIBS_INIT}
102)102)
103103
104add_executable(mir_demo_client_scroll104mir_add_wrapped_executable(mir_demo_client_scroll
105 scroll.cpp105 scroll.cpp
106)106)
107107
@@ -117,7 +117,7 @@
117117
118)118)
119119
120add_executable(mir_demo_client_prompt_session prompt_session.c)120mir_add_wrapped_executable(mir_demo_client_prompt_session prompt_session.c)
121target_link_libraries(mir_demo_client_prompt_session mirclient)121target_link_libraries(mir_demo_client_prompt_session mirclient)
122122
123add_library(mirdraw STATIC graphics_utils.cpp)123add_library(mirdraw STATIC graphics_utils.cpp)
@@ -130,7 +130,7 @@
130 ${GLESv2_INCLUDE_DIRS}130 ${GLESv2_INCLUDE_DIRS}
131)131)
132132
133add_executable(mir_demo_standalone_render_to_fb133mir_add_wrapped_executable(mir_demo_standalone_render_to_fb
134 render_to_fb.cpp134 render_to_fb.cpp
135)135)
136136
@@ -140,25 +140,7 @@
140 ${Boost_LIBRARIES}140 ${Boost_LIBRARIES}
141)141)
142142
143set (INSTALL_DEMOS143mir_add_wrapped_executable(mir_demo_server_basic
144 mir_demo_client_basic
145 mir_demo_client_flicker
146 mir_demo_client_scroll
147 mir_demo_client_eglflash
148 mir_demo_client_egltriangle
149 mir_demo_client_eglplasma
150 mir_demo_client_eglcounter
151 mir_demo_client_fingerpaint
152 mir_demo_client_multiwin
153 mir_demo_client_display_config
154 mir_demo_client_progressbar
155 mir_demo_client_prompt_session
156 mir_demo_standalone_render_to_fb
157)
158
159install(TARGETS ${INSTALL_DEMOS} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
160
161add_executable(mir_demo_server_basic
162 server_example.cpp144 server_example.cpp
163 glog_logger.cpp145 glog_logger.cpp
164)146)
@@ -171,17 +153,10 @@
171 ${Boost_LIBRARIES}153 ${Boost_LIBRARIES}
172)154)
173155
174install(TARGETS mir_demo_server_basic156mir_add_wrapped_executable(mir_demo_server_minimal server_minimal.cpp)
175 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
176)
177
178add_executable(mir_demo_server_minimal server_minimal.cpp)
179target_link_libraries(mir_demo_server_minimal mirserver)157target_link_libraries(mir_demo_server_minimal mirserver)
180install(TARGETS mir_demo_server_minimal
181 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
182)
183158
184add_executable(mir_demo_standalone_render_overlays159mir_add_wrapped_executable(mir_demo_standalone_render_overlays
185 render_overlays.cpp160 render_overlays.cpp
186)161)
187162
@@ -189,7 +164,3 @@
189 mirserver164 mirserver
190 mircommon165 mircommon
191)166)
192
193install(TARGETS mir_demo_standalone_render_overlays
194 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
195)
196167
=== modified file 'playground/demo-shell/CMakeLists.txt'
--- playground/demo-shell/CMakeLists.txt 2014-12-11 02:43:01 +0000
+++ playground/demo-shell/CMakeLists.txt 2014-12-12 01:38:38 +0000
@@ -4,7 +4,7 @@
4 window_manager.cpp4 window_manager.cpp
5)5)
66
7add_executable(mir_demo_server_shell7mir_add_wrapped_executable(mir_demo_server_shell
8 demo_shell.cpp8 demo_shell.cpp
9)9)
1010
@@ -14,5 +14,3 @@
14 playgroundserverconfig14 playgroundserverconfig
15 exampleserverconfig15 exampleserverconfig
16)16)
17
18install(TARGETS mir_demo_server_shell RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
1917
=== modified file 'src/CMakeLists.txt'
--- src/CMakeLists.txt 2014-12-08 04:03:47 +0000
+++ src/CMakeLists.txt 2014-12-12 01:38:38 +0000
@@ -20,3 +20,4 @@
20set(MIR_PLATFORM_REFERENCES ${MIR_PLATFORM_REFERENCES} PARENT_SCOPE)20set(MIR_PLATFORM_REFERENCES ${MIR_PLATFORM_REFERENCES} PARENT_SCOPE)
21set(MIR_COMMON_OBJECTS ${MIR_COMMON_OBJECTS} PARENT_SCOPE)21set(MIR_COMMON_OBJECTS ${MIR_COMMON_OBJECTS} PARENT_SCOPE)
22set(MIR_COMMON_REFERENCES ${MIR_COMMON_REFERENCES} PARENT_SCOPE)22set(MIR_COMMON_REFERENCES ${MIR_COMMON_REFERENCES} PARENT_SCOPE)
23set(MIR_CLIENT_PLATFORM_PATH ${MIR_CLIENT_PLATFORM_PATH} PARENT_SCOPE)
2324
=== modified file 'src/client/CMakeLists.txt'
--- src/client/CMakeLists.txt 2014-12-11 02:43:01 +0000
+++ src/client/CMakeLists.txt 2014-12-12 01:38:38 +0000
@@ -1,13 +1,3 @@
1set(MIRCLIENT_ABI 8)
2set(CLIENT_DRIVER client${MIRCLIENT_ABI}driver)
3set(MIR_CLIENT_DRIVER mir${CLIENT_DRIVER})
4set(MIR_CLIENT_DRIVER_BINARY lib${MIR_CLIENT_DRIVER}.so
5 CACHE STRING "File name of Mir client drivers")
6add_definitions(
7 -DMIR_CLIENT_DRIVER_BINARY="${MIR_CLIENT_DRIVER_BINARY}"
8 -DMIR_LOG_COMPONENT_FALLBACK="mirclient"
9)
10
11set(PREFIX "${CMAKE_INSTALL_PREFIX}")1set(PREFIX "${CMAKE_INSTALL_PREFIX}")
12set(EXEC_PREFIX "${CMAKE_INSTALL_PREFIX}")2set(EXEC_PREFIX "${CMAKE_INSTALL_PREFIX}")
13set(LIBDIR "${CMAKE_INSTALL_FULL_LIBDIR}")3set(LIBDIR "${CMAKE_INSTALL_FULL_LIBDIR}")
@@ -33,6 +23,20 @@
33 ${DRM_INCLUDE_DIRS}23 ${DRM_INCLUDE_DIRS}
34)24)
3525
26set(MIRCLIENT_ABI 8)
27set(CLIENT_PLATFORM_VERSION "MIR_CLIENT_PLATFORM_2")
28set(symbol_map ${CMAKE_SOURCE_DIR}/src/client/symbols.map)
29
30set(MIR_CLIENT_PLATFORM_PATH
31 ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/mir/client-platform
32)
33set(MIR_CLIENT_PLATFORM_PATH ${MIR_CLIENT_PLATFORM_PATH} PARENT_SCOPE)
34
35add_definitions(-DMIR_CLIENT_PLATFORM_PATH="${MIR_CLIENT_PLATFORM_PATH}/")
36add_definitions(-DCLIENT_PLATFORM_VERSION="${CLIENT_PLATFORM_VERSION}")
37add_definitions(-DMIR_LOGGING_COMPONENT_FALLBACK="mirclient")
38
39
36add_subdirectory(rpc/)40add_subdirectory(rpc/)
37add_subdirectory(lttng/)41add_subdirectory(lttng/)
3842
@@ -72,19 +76,16 @@
72 mir_prompt_session.cpp76 mir_prompt_session.cpp
73 mir_prompt_session_api.cpp77 mir_prompt_session_api.cpp
74 mir_event_distributor.cpp78 mir_event_distributor.cpp
79 probing_client_platform_factory.cpp
75 periodic_perf_report.cpp80 periodic_perf_report.cpp
76)81)
7782
78add_library(83add_library(mirclient SHARED
79 mirclient SHARED
8084
81 $<TARGET_OBJECTS:mirclientobjects>85 $<TARGET_OBJECTS:mirclientobjects>
82)86)
8387
84set(symbol_map ${CMAKE_CURRENT_SOURCE_DIR}/symbols.map)88set_target_properties(mirclient
85
86set_target_properties(
87 mirclient
8889
89 PROPERTIES90 PROPERTIES
90 SOVERSION ${MIRCLIENT_ABI}91 SOVERSION ${MIRCLIENT_ABI}
@@ -92,6 +93,7 @@
92)93)
9394
94target_link_libraries(mirclient95target_link_libraries(mirclient
96
95 mirclientrpc97 mirclientrpc
96 mirclientlttngstatic98 mirclientlttngstatic
97 mircommon99 mircommon
98100
=== modified file 'src/client/android/CMakeLists.txt'
--- src/client/android/CMakeLists.txt 2014-12-08 04:03:47 +0000
+++ src/client/android/CMakeLists.txt 2014-12-12 01:38:38 +0000
@@ -14,17 +14,18 @@
14)14)
1515
16add_library(16add_library(
17 mirclientplatformandroid SHARED17 mirclientplatformandroid MODULE
18 18
19 $<TARGET_OBJECTS:mirclientplatformandroidobjects>19 $<TARGET_OBJECTS:mirclientplatformandroidobjects>
20 $<TARGET_OBJECTS:mirclient_platformimpl>20 $<TARGET_OBJECTS:mirclient_platformimpl>
21)21)
2222
23set_target_properties(23set_target_properties(
24 mirclientplatformandroid PROPERTIES24 mirclientplatformandroid PROPERTIES
25 OUTPUT_NAME ${MIR_CLIENT_DRIVER}25 OUTPUT_NAME android
26 LIBRARY_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH}/android26 LIBRARY_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH}/client-modules
27 LINK_FLAGS "-Wl,--exclude-libs=ALL -Wl,--version-script,${symbol_map}"27 PREFIX ""
28 LINK_FLAGS "-Wl,--version-script,${symbol_map}"
28)29)
2930
30target_link_libraries(mirclientplatformandroid31target_link_libraries(mirclientplatformandroid
@@ -33,20 +34,4 @@
33 ${LIBHARDWARE_LIBRARIES}34 ${LIBHARDWARE_LIBRARIES}
34)35)
3536
36install(TARGETS mirclientplatformandroid LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mir/${CLIENT_DRIVER}/android)37install(TARGETS mirclientplatformandroid LIBRARY DESTINATION ${MIR_CLIENT_PLATFORM_PATH})
37
38if (MIR_TEST_PLATFORM STREQUAL "android")
39 add_custom_command(TARGET mirclientplatformandroid
40 POST_BUILD
41 COMMAND ${CMAKE_COMMAND} -E remove ${MIR_CLIENT_DRIVER_BINARY}
42 COMMAND ${CMAKE_COMMAND} -E create_symlink android/$<TARGET_FILE_NAME:mirclientplatformandroid> ${MIR_CLIENT_DRIVER_BINARY}
43 WORKING_DIRECTORY ${LIBRARY_OUTPUT_PATH}
44 )
45
46 install(CODE
47 "execute_process(
48 COMMAND ln -sf mir/${CLIENT_DRIVER}/android/${MIR_CLIENT_DRIVER_BINARY}
49 WORKING_DIRECTORY \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}
50 )"
51 )
52endif()
5338
=== modified file 'src/client/android/android_native_display_container.cpp'
--- src/client/android/android_native_display_container.cpp 2014-12-08 04:03:47 +0000
+++ src/client/android/android_native_display_container.cpp 2014-12-12 01:38:38 +0000
@@ -62,16 +62,24 @@
62bool62bool
63mcla::AndroidNativeDisplayContainer::validate(MirEGLNativeDisplayType display) const63mcla::AndroidNativeDisplayContainer::validate(MirEGLNativeDisplayType display) const
64{64{
65 return mir_connection_is_valid(static_cast<MirConnection*>(display));65 std::lock_guard<std::mutex> lg(guard);
66 return (valid_displays.find(display) != valid_displays.end());
66}67}
6768
68MirEGLNativeDisplayType69MirEGLNativeDisplayType
69mcla::AndroidNativeDisplayContainer::create(MirConnection* connection)70mcla::AndroidNativeDisplayContainer::create(ClientContext* context)
70{71{
71 return static_cast<MirEGLNativeDisplayType>(connection);72 std::lock_guard<std::mutex> lg(guard);
73 auto egl_display = static_cast<MirEGLNativeDisplayType>(context);
74 valid_displays.insert(egl_display);
75
76 return egl_display;
72}77}
7378
74void79void
75mcla::AndroidNativeDisplayContainer::release(MirEGLNativeDisplayType /* display */)80mcla::AndroidNativeDisplayContainer::release(MirEGLNativeDisplayType display)
76{81{
82 std::lock_guard<std::mutex> lg(guard);
83
84 valid_displays.erase(display);
77}85}
7886
=== modified file 'src/client/android/android_native_display_container.h'
--- src/client/android/android_native_display_container.h 2013-05-02 00:11:18 +0000
+++ src/client/android/android_native_display_container.h 2014-12-12 01:38:38 +0000
@@ -23,6 +23,9 @@
2323
24#include "mir_toolkit/client_types.h"24#include "mir_toolkit/client_types.h"
2525
26#include <unordered_set>
27#include <mutex>
28
26namespace mir29namespace mir
27{30{
28namespace client31namespace client
@@ -36,14 +39,18 @@
36 AndroidNativeDisplayContainer();39 AndroidNativeDisplayContainer();
37 virtual ~AndroidNativeDisplayContainer();40 virtual ~AndroidNativeDisplayContainer();
3841
39 MirEGLNativeDisplayType create(MirConnection* connection);42 MirEGLNativeDisplayType create(ClientContext* context) override;
40 void release(MirEGLNativeDisplayType display);43 void release(MirEGLNativeDisplayType display) override;
4144
42 bool validate(MirEGLNativeDisplayType display) const;45 bool validate(MirEGLNativeDisplayType display) const override;
4346
44protected:47protected:
45 AndroidNativeDisplayContainer(AndroidNativeDisplayContainer const&) = delete;48 AndroidNativeDisplayContainer(AndroidNativeDisplayContainer const&) = delete;
46 AndroidNativeDisplayContainer& operator=(AndroidNativeDisplayContainer const&) = delete;49 AndroidNativeDisplayContainer& operator=(AndroidNativeDisplayContainer const&) = delete;
50
51private:
52 std::mutex mutable guard;
53 std::unordered_set<MirEGLNativeDisplayType> valid_displays;
47};54};
4855
49}56}
5057
=== modified file 'src/client/android/client_platform_factory.cpp'
--- src/client/android/client_platform_factory.cpp 2014-02-07 15:43:41 +0000
+++ src/client/android/client_platform_factory.cpp 2014-12-12 01:38:38 +0000
@@ -16,19 +16,36 @@
16 * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>16 * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>
17 */17 */
1818
19#include "client_platform_factory.h"19#include "../client_platform_factory.h"
20#include "mir_toolkit/client_types.h"
21#include "../client_context.h"
20#include "android_client_platform.h"22#include "android_client_platform.h"
2123
24#include <boost/throw_exception.hpp>
25#include <stdexcept>
26
22namespace mcl = mir::client;27namespace mcl = mir::client;
23namespace mcla = mcl::android;28namespace mcla = mcl::android;
2429
25std::shared_ptr<mcl::ClientPlatform>30extern "C" std::shared_ptr<mcl::ClientPlatform>
26mcla::ClientPlatformFactory::create_client_platform(mcl::ClientContext* /*context*/)31mcl::create_client_platform(mcl::ClientContext* context)
27{32{
33 MirPlatformPackage platform;
34 context->populate(platform);
35 if (platform.data_items != 0 || platform.fd_items != 0)
36 {
37 BOOST_THROW_EXCEPTION((std::runtime_error{"Attempted to create Android client platform on non-Android server"}));
38 }
28 return std::make_shared<mcla::AndroidClientPlatform>();39 return std::make_shared<mcla::AndroidClientPlatform>();
29}40}
3041
31extern "C" std::shared_ptr<mcl::ClientPlatformFactory> mcl::create_client_platform_factory()42extern "C" bool
43mcl::is_appropriate_module(mcl::ClientContext* context)
32{44{
33 return std::make_shared<mcla::ClientPlatformFactory>();45 MirPlatformPackage platform;
46 context->populate(platform);
47 // TODO: Actually check what platform we're using, rather than blindly
48 // hope we can distinguish them from the stuff they've put in the
49 // PlatformPackage.
50 return platform.data_items == 0 && platform.fd_items == 0;
34}51}
3552
=== modified file 'src/client/android/client_platform_factory.h'
--- src/client/android/client_platform_factory.h 2014-02-07 15:43:41 +0000
+++ src/client/android/client_platform_factory.h 2014-12-12 01:38:38 +0000
@@ -28,11 +28,8 @@
28namespace android28namespace android
29{29{
3030
31class ClientPlatformFactory : public client::ClientPlatformFactory31extern "C" std::shared_ptr<ClientPlatform>
32{32create_client_platform(ClientContext* context);
33public:
34 std::shared_ptr<ClientPlatform> create_client_platform(ClientContext* context) override;
35};
3633
37}34}
38}35}
3936
=== modified file 'src/client/android/symbols.map'
--- src/client/android/symbols.map 2014-12-08 04:03:47 +0000
+++ src/client/android/symbols.map 2014-12-12 01:38:38 +0000
@@ -1,5 +1,6 @@
1MIR_CLIENTPLATFORM_1 {1MIR_CLIENT_PLATFORM_2 {
2 global: 2 global:
3 create_client_platform_factory;3 create_client_platform;
4 is_appropriate_module;
4 local: *;5 local: *;
5};
6\ No newline at end of file6\ No newline at end of file
7};
78
=== modified file 'src/client/client_context.h'
--- src/client/client_context.h 2013-08-28 03:41:48 +0000
+++ src/client/client_context.h 2014-12-12 01:38:38 +0000
@@ -19,6 +19,8 @@
19#ifndef MIR_CLIENT_CLIENT_CONTEXT_H_19#ifndef MIR_CLIENT_CLIENT_CONTEXT_H_
20#define MIR_CLIENT_CLIENT_CONTEXT_H_20#define MIR_CLIENT_CLIENT_CONTEXT_H_
2121
22#include "mir_toolkit/client_types.h"
23
22namespace mir24namespace mir
23{25{
24namespace client26namespace client
@@ -29,7 +31,6 @@
29public:31public:
30 virtual ~ClientContext() {}32 virtual ~ClientContext() {}
3133
32 virtual MirConnection* mir_connection() = 0;
33 virtual void populate(MirPlatformPackage& platform_package) = 0;34 virtual void populate(MirPlatformPackage& platform_package) = 0;
3435
35protected:36protected:
3637
=== modified file 'src/client/client_platform_factory.h'
--- src/client/client_platform_factory.h 2014-03-06 06:05:17 +0000
+++ src/client/client_platform_factory.h 2014-12-12 01:38:38 +0000
@@ -41,8 +41,11 @@
41 ClientPlatformFactory& operator=(ClientPlatformFactory const& p) = delete;41 ClientPlatformFactory& operator=(ClientPlatformFactory const& p) = delete;
42};42};
4343
44extern "C" typedef std::shared_ptr<ClientPlatformFactory>(*CreateClientPlatformFactory)();44extern "C" typedef std::shared_ptr<ClientPlatform>(*CreateClientPlatform)(ClientContext* context);
45extern "C" std::shared_ptr<ClientPlatformFactory> create_client_platform_factory();45extern "C" std::shared_ptr<ClientPlatform> create_client_platform(ClientContext* context);
46
47extern "C" typedef bool (*ClientPlatformProbe)(ClientContext* context);
48extern "C" bool is_appropriate_module(ClientContext* context);
4649
47}50}
48}51}
4952
=== modified file 'src/client/connection_configuration.h'
--- src/client/connection_configuration.h 2014-12-08 04:03:47 +0000
+++ src/client/connection_configuration.h 2014-12-12 01:38:38 +0000
@@ -39,8 +39,6 @@
39class Logger;39class Logger;
40}40}
4141
42class SharedLibrary;
43
44namespace client42namespace client
45{43{
46class ConnectionSurfaceMap;44class ConnectionSurfaceMap;
@@ -65,7 +63,6 @@
65 virtual std::shared_ptr<LifecycleControl> the_lifecycle_control() = 0;63 virtual std::shared_ptr<LifecycleControl> the_lifecycle_control() = 0;
66 virtual std::shared_ptr<EventSink> the_event_sink() = 0;64 virtual std::shared_ptr<EventSink> the_event_sink() = 0;
67 virtual std::shared_ptr<EventHandlerRegister> the_event_handler_register() = 0;65 virtual std::shared_ptr<EventHandlerRegister> the_event_handler_register() = 0;
68 virtual std::shared_ptr<SharedLibrary> the_platform_library() = 0;
6966
70protected:67protected:
71 ConnectionConfiguration() = default;68 ConnectionConfiguration() = default;
7269
=== modified file 'src/client/default_connection_configuration.cpp'
--- src/client/default_connection_configuration.cpp 2014-12-08 04:03:47 +0000
+++ src/client/default_connection_configuration.cpp 2014-12-12 01:38:38 +0000
@@ -35,6 +35,7 @@
35#include "lifecycle_control.h"35#include "lifecycle_control.h"
36#include "mir/shared_library.h"36#include "mir/shared_library.h"
37#include "client_platform_factory.h"37#include "client_platform_factory.h"
38#include "probing_client_platform_factory.h"
38#include "mir_event_distributor.h"39#include "mir_event_distributor.h"
39#include "mir/shared_library_prober.h"40#include "mir/shared_library_prober.h"
4041
@@ -47,7 +48,10 @@
47std::string const off_opt_val{"off"};48std::string const off_opt_val{"off"};
48std::string const log_opt_val{"log"};49std::string const log_opt_val{"log"};
49std::string const lttng_opt_val{"lttng"};50std::string const lttng_opt_val{"lttng"};
50std::string const default_platform_lib{MIR_CLIENT_DRIVER_BINARY};51
52// Shove this here until we properly manage the lifetime of our
53// loadable modules
54std::shared_ptr<mcl::ProbingClientPlatformFactory> the_platform_prober;
5155
52// Hack around the way Qt loads mir:56// Hack around the way Qt loads mir:
53// qtmir and therefore Mir are loaded via dlopen(..., RTLD_LOCAL).57// qtmir and therefore Mir are loaded via dlopen(..., RTLD_LOCAL).
@@ -108,11 +112,23 @@
108 return client_platform_factory(112 return client_platform_factory(
109 [this]113 [this]
110 {114 {
111 auto const create_client_platform_factory =115 ensure_loaded_with_rtld_global();
112 the_platform_library()->load_function<mcl::CreateClientPlatformFactory>(116 auto const platform_override = getenv("MIR_CLIENT_PLATFORM_LIB");
113 "create_client_platform_factory");117 std::vector<std::shared_ptr<mir::SharedLibrary>> platform_plugins;
114118 if (platform_override)
115 return create_client_platform_factory();119 {
120 platform_plugins.push_back(std::make_shared<mir::SharedLibrary>(platform_override));
121 }
122 else
123 {
124 auto const platform_path_override = getenv("MIR_CLIENT_PLATFORM_PATH");
125 auto const platform_path = platform_path_override ? platform_path_override : MIR_CLIENT_PLATFORM_PATH;
126 platform_plugins = mir::libraries_for_path(platform_path, *the_shared_library_prober_report());
127 }
128
129 the_platform_prober = std::make_shared<mcl::ProbingClientPlatformFactory>(platform_plugins);
130
131 return the_platform_prober;
116 });132 });
117}133}
118134
@@ -211,6 +227,7 @@
211 {227 {
212 auto val_raw = getenv("MIR_CLIENT_SHARED_LIBRARY_PROBER_REPORT");228 auto val_raw = getenv("MIR_CLIENT_SHARED_LIBRARY_PROBER_REPORT");
213 std::string const val{val_raw ? val_raw : off_opt_val};229 std::string const val{val_raw ? val_raw : off_opt_val};
230
214 if (val == log_opt_val)231 if (val == log_opt_val)
215 return std::make_shared<mir::logging::SharedLibraryProberReport>(the_logger());232 return std::make_shared<mir::logging::SharedLibraryProberReport>(the_logger());
216 else if (val == lttng_opt_val)233 else if (val == lttng_opt_val)
@@ -219,15 +236,3 @@
219 return std::make_shared<mir::logging::NullSharedLibraryProberReport>();236 return std::make_shared<mir::logging::NullSharedLibraryProberReport>();
220 });237 });
221}238}
222
223std::shared_ptr<mir::SharedLibrary> mcl::DefaultConnectionConfiguration::the_platform_library()
224{
225 if (!platform_library)
226 {
227 ensure_loaded_with_rtld_global();
228 auto const val_raw = getenv("MIR_CLIENT_PLATFORM_LIB");
229 std::string const libname{val_raw ? val_raw : default_platform_lib};
230 platform_library = std::make_shared<mir::SharedLibrary>(libname);
231 }
232 return platform_library;
233}
234239
=== modified file 'src/client/default_connection_configuration.h'
--- src/client/default_connection_configuration.h 2014-12-08 04:03:47 +0000
+++ src/client/default_connection_configuration.h 2014-12-12 01:38:38 +0000
@@ -60,16 +60,12 @@
60 std::shared_ptr<EventSink> the_event_sink() override;60 std::shared_ptr<EventSink> the_event_sink() override;
61 std::shared_ptr<EventHandlerRegister> the_event_handler_register() override;61 std::shared_ptr<EventHandlerRegister> the_event_handler_register() override;
62 std::shared_ptr<mir::SharedLibraryProberReport> the_shared_library_prober_report();62 std::shared_ptr<mir::SharedLibraryProberReport> the_shared_library_prober_report();
63 std::shared_ptr<SharedLibrary> the_platform_library() override;
6463
65 virtual std::string the_socket_file();64 virtual std::string the_socket_file();
66 virtual std::shared_ptr<rpc::RpcReport> the_rpc_report();65 virtual std::shared_ptr<rpc::RpcReport> the_rpc_report();
67 virtual std::shared_ptr<input::receiver::InputReceiverReport> the_input_receiver_report();66 virtual std::shared_ptr<input::receiver::InputReceiverReport> the_input_receiver_report();
6867
69protected:68protected:
70 // MUST be first data member so it is destroyed last.
71 std::shared_ptr<mir::SharedLibrary> platform_library;
72
73 CachedPtr<google::protobuf::RpcChannel> rpc_channel;69 CachedPtr<google::protobuf::RpcChannel> rpc_channel;
74 CachedPtr<mir::logging::Logger> logger;70 CachedPtr<mir::logging::Logger> logger;
75 CachedPtr<ClientPlatformFactory> client_platform_factory;71 CachedPtr<ClientPlatformFactory> client_platform_factory;
7672
=== modified file 'src/client/egl_native_display_container.h'
--- src/client/egl_native_display_container.h 2014-03-06 06:05:17 +0000
+++ src/client/egl_native_display_container.h 2014-12-12 01:38:38 +0000
@@ -26,12 +26,14 @@
26namespace client26namespace client
27{27{
2828
29class ClientContext;
30
29class EGLNativeDisplayContainer31class EGLNativeDisplayContainer
30{32{
31public:33public:
32 virtual ~EGLNativeDisplayContainer() {}34 virtual ~EGLNativeDisplayContainer() {}
3335
34 virtual MirEGLNativeDisplayType create(MirConnection* connection) = 0;36 virtual MirEGLNativeDisplayType create(ClientContext* context) = 0;
35 virtual void release(MirEGLNativeDisplayType display) = 0;37 virtual void release(MirEGLNativeDisplayType display) = 0;
3638
37 virtual bool validate(MirEGLNativeDisplayType display) const = 0;39 virtual bool validate(MirEGLNativeDisplayType display) const = 0;
3840
=== modified file 'src/client/mesa/CMakeLists.txt'
--- src/client/mesa/CMakeLists.txt 2014-12-08 04:03:47 +0000
+++ src/client/mesa/CMakeLists.txt 2014-12-12 01:38:38 +0000
@@ -15,7 +15,7 @@
15)15)
1616
17add_library(17add_library(
18 mirclientplatformmesa SHARED18 mirclientplatformmesa MODULE
1919
20 $<TARGET_OBJECTS:mirclientplatformmesaobjects>20 $<TARGET_OBJECTS:mirclientplatformmesaobjects>
21 $<TARGET_OBJECTS:mirclient_platformimpl>21 $<TARGET_OBJECTS:mirclient_platformimpl>
@@ -23,9 +23,10 @@
2323
24set_target_properties(24set_target_properties(
25 mirclientplatformmesa PROPERTIES25 mirclientplatformmesa PROPERTIES
26 OUTPUT_NAME ${MIR_CLIENT_DRIVER}26 OUTPUT_NAME mesa
27 LIBRARY_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH}/mesa27 LIBRARY_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH}/client-modules
28 LINK_FLAGS "-Wl,--exclude-libs=ALL -Wl,--version-script,${symbol_map}"28 PREFIX ""
29 LINK_FLAGS "-Wl,--version-script,${symbol_map}"
29)30)
3031
31target_link_libraries(mirclientplatformmesa32target_link_libraries(mirclientplatformmesa
@@ -33,21 +34,4 @@
33 ${DRM_LDFLAGS} ${DRM_LIBRARIES}34 ${DRM_LDFLAGS} ${DRM_LIBRARIES}
34)35)
3536
36install(TARGETS mirclientplatformmesa LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mir/${CLIENT_DRIVER}/mesa)37install(TARGETS mirclientplatformmesa LIBRARY DESTINATION ${MIR_CLIENT_PLATFORM_PATH})
37
38if (MIR_TEST_PLATFORM STREQUAL "mesa")
39 add_custom_command(TARGET mirclientplatformmesa
40 POST_BUILD
41 COMMAND ${CMAKE_COMMAND} -E remove ${MIR_CLIENT_DRIVER_BINARY}
42 COMMAND ${CMAKE_COMMAND} -E create_symlink mesa/$<TARGET_FILE_NAME:mirclientplatformmesa> ${MIR_CLIENT_DRIVER_BINARY}
43 WORKING_DIRECTORY ${LIBRARY_OUTPUT_PATH}
44 )
45
46 install(CODE
47 "execute_process(
48 COMMAND ln -sf mir/${CLIENT_DRIVER}/mesa/${MIR_CLIENT_DRIVER_BINARY}
49 WORKING_DIRECTORY \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}
50 )"
51 )
52endif()
53
5438
=== modified file 'src/client/mesa/client_platform.cpp'
--- src/client/mesa/client_platform.cpp 2014-03-06 06:05:17 +0000
+++ src/client/mesa/client_platform.cpp 2014-12-12 01:38:38 +0000
@@ -95,7 +95,7 @@
95std::shared_ptr<EGLNativeDisplayType> mclm::ClientPlatform::create_egl_native_display()95std::shared_ptr<EGLNativeDisplayType> mclm::ClientPlatform::create_egl_native_display()
96{96{
97 MirEGLNativeDisplayType *mir_native_display = new MirEGLNativeDisplayType;97 MirEGLNativeDisplayType *mir_native_display = new MirEGLNativeDisplayType;
98 *mir_native_display = display_container.create(context->mir_connection());98 *mir_native_display = display_container.create(context);
99 auto egl_native_display = reinterpret_cast<EGLNativeDisplayType*>(mir_native_display);99 auto egl_native_display = reinterpret_cast<EGLNativeDisplayType*>(mir_native_display);
100100
101 return std::shared_ptr<EGLNativeDisplayType>(egl_native_display, NativeDisplayDeleter(display_container));101 return std::shared_ptr<EGLNativeDisplayType>(egl_native_display, NativeDisplayDeleter(display_container));
102102
=== modified file 'src/client/mesa/client_platform_factory.cpp'
--- src/client/mesa/client_platform_factory.cpp 2014-02-07 15:43:41 +0000
+++ src/client/mesa/client_platform_factory.cpp 2014-12-12 01:38:38 +0000
@@ -16,13 +16,17 @@
16 * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>16 * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>
17 */17 */
1818
19#include "client_platform_factory.h"19#include "../client_platform_factory.h"
20#include "client_platform.h"20#include "client_platform.h"
21#include "mir_toolkit/client_types.h"
22#include "../client_context.h"
21#include "buffer_file_ops.h"23#include "buffer_file_ops.h"
22#include "../egl_native_display_container.h"24#include "../egl_native_display_container.h"
2325
24#include <sys/mman.h>26#include <sys/mman.h>
25#include <unistd.h>27#include <unistd.h>
28#include <stdexcept>
29#include <boost/throw_exception.hpp>
2630
27namespace mcl = mir::client;31namespace mcl = mir::client;
28namespace mclm = mcl::mesa;32namespace mclm = mcl::mesa;
@@ -57,15 +61,26 @@
5761
58}62}
5963
60std::shared_ptr<mcl::ClientPlatform>64extern "C" std::shared_ptr<mcl::ClientPlatform> mcl::create_client_platform(mcl::ClientContext* context)
61mclm::ClientPlatformFactory::create_client_platform(mcl::ClientContext* context)
62{65{
66 MirPlatformPackage package;
67 context->populate(package);
68 if (package.data_items != 0 || package.fd_items != 1)
69 {
70 BOOST_THROW_EXCEPTION((std::runtime_error{"Attempted to create Mesa client platform on non-Mesa server"}));
71 }
63 auto buffer_file_ops = std::make_shared<RealBufferFileOps>();72 auto buffer_file_ops = std::make_shared<RealBufferFileOps>();
64 return std::make_shared<mclm::ClientPlatform>(73 return std::make_shared<mclm::ClientPlatform>(
65 context, buffer_file_ops, mcl::EGLNativeDisplayContainer::instance());74 context, buffer_file_ops, mcl::EGLNativeDisplayContainer::instance());
66}75}
6776
68extern "C" std::shared_ptr<mcl::ClientPlatformFactory> mcl::create_client_platform_factory()77extern "C" bool
78mcl::is_appropriate_module(mcl::ClientContext* context)
69{79{
70 return std::make_shared<mclm::ClientPlatformFactory>();80 MirPlatformPackage platform;
81 context->populate(platform);
82 // TODO: Actually check what platform we're using, rather than blindly
83 // hope we can distinguish them from the stuff they've put in the
84 // PlatformPackage.
85 return platform.data_items == 0 && platform.fd_items == 1;
71}86}
7287
=== modified file 'src/client/mesa/client_platform_factory.h'
--- src/client/mesa/client_platform_factory.h 2014-02-07 15:43:41 +0000
+++ src/client/mesa/client_platform_factory.h 2014-12-12 01:38:38 +0000
@@ -28,11 +28,6 @@
28namespace mesa28namespace mesa
29{29{
3030
31class ClientPlatformFactory : public client::ClientPlatformFactory
32{
33public:
34 std::shared_ptr<ClientPlatform> create_client_platform(ClientContext* context) override;
35};
3631
37}32}
38}33}
3934
=== modified file 'src/client/mesa/mesa_native_display_container.cpp'
--- src/client/mesa/mesa_native_display_container.cpp 2014-12-08 04:03:47 +0000
+++ src/client/mesa/mesa_native_display_container.cpp 2014-12-12 01:38:38 +0000
@@ -18,7 +18,7 @@
1818
19#include "mesa_native_display_container.h"19#include "mesa_native_display_container.h"
2020
21#include "mir_toolkit/mir_client_library.h"21#include "../client_context.h"
2222
23#include <cstring>23#include <cstring>
24#include <unordered_set>24#include <unordered_set>
@@ -35,8 +35,8 @@
35static int egl_display_get_platform(MirMesaEGLNativeDisplay* display,35static int egl_display_get_platform(MirMesaEGLNativeDisplay* display,
36 MirPlatformPackage* package)36 MirPlatformPackage* package)
37{37{
38 auto connection = static_cast<MirConnection*>(display->context);38 auto context = static_cast<mcl::ClientContext*>(display->context);
39 mir_connection_get_platform(connection, package);39 context->populate(*package);
40 return MIR_MESA_TRUE;40 return MIR_MESA_TRUE;
41}41}
4242
@@ -93,11 +93,11 @@
93}93}
9494
95MirEGLNativeDisplayType95MirEGLNativeDisplayType
96mclm::MesaNativeDisplayContainer::create(MirConnection* connection)96mclm::MesaNativeDisplayContainer::create(ClientContext* context)
97{97{
98 MirMesaEGLNativeDisplay* display = new MirMesaEGLNativeDisplay();98 MirMesaEGLNativeDisplay* display = new MirMesaEGLNativeDisplay();
99 display->display_get_platform = egl_display_get_platform;99 display->display_get_platform = egl_display_get_platform;
100 display->context = connection;100 display->context = context;
101101
102 std::lock_guard<std::mutex> lg(guard);102 std::lock_guard<std::mutex> lg(guard);
103 auto egl_display = static_cast<MirEGLNativeDisplayType>(display);103 auto egl_display = static_cast<MirEGLNativeDisplayType>(display);
104104
=== modified file 'src/client/mesa/mesa_native_display_container.h'
--- src/client/mesa/mesa_native_display_container.h 2014-03-06 06:05:17 +0000
+++ src/client/mesa/mesa_native_display_container.h 2014-12-12 01:38:38 +0000
@@ -40,7 +40,7 @@
40 MesaNativeDisplayContainer();40 MesaNativeDisplayContainer();
41 virtual ~MesaNativeDisplayContainer();41 virtual ~MesaNativeDisplayContainer();
4242
43 MirEGLNativeDisplayType create(MirConnection* connection);43 MirEGLNativeDisplayType create(ClientContext* context);
44 void release(MirEGLNativeDisplayType display);44 void release(MirEGLNativeDisplayType display);
4545
46 bool validate(MirEGLNativeDisplayType display) const;46 bool validate(MirEGLNativeDisplayType display) const;
4747
=== modified file 'src/client/mesa/native_surface.cpp'
--- src/client/mesa/native_surface.cpp 2014-12-08 04:03:47 +0000
+++ src/client/mesa/native_surface.cpp 2014-12-12 01:38:38 +0000
@@ -20,7 +20,6 @@
20#include "../client_buffer.h"20#include "../client_buffer.h"
21#include "native_surface.h"21#include "native_surface.h"
2222
23#include <iostream>
24#include <boost/exception/diagnostic_information.hpp> 23#include <boost/exception/diagnostic_information.hpp>
2524
26namespace mclm=mir::client::mesa;25namespace mclm=mir::client::mesa;
2726
=== modified file 'src/client/mesa/symbols.map'
--- src/client/mesa/symbols.map 2014-12-08 04:03:47 +0000
+++ src/client/mesa/symbols.map 2014-12-12 01:38:38 +0000
@@ -1,7 +1,9 @@
1MIR_CLIENTPLATFORM_1 {1MIR_CLIENT_PLATFORM_2 {
2 global: 2 global:
3 create_client_platform_factory;3 create_client_platform;
4 is_appropriate_module;
4 # Needed by our Mesa EGL platform5 # Needed by our Mesa EGL platform
5 mir_client_mesa_egl_native_display_is_valid;6 mir_client_mesa_egl_native_display_is_valid;
6 local: *;7 local:
8 *;
7};9};
810
=== modified file 'src/client/mir_connection.cpp'
--- src/client/mir_connection.cpp 2014-12-11 02:43:01 +0000
+++ src/client/mir_connection.cpp 2014-12-12 01:38:38 +0000
@@ -95,11 +95,11 @@
95MirConnection::MirConnection(95MirConnection::MirConnection(
96 mir::client::ConnectionConfiguration& conf) :96 mir::client::ConnectionConfiguration& conf) :
97 deregisterer{this},97 deregisterer{this},
98 platform_library{conf.the_platform_library()},
99 channel(conf.the_rpc_channel()),98 channel(conf.the_rpc_channel()),
100 server(channel.get(), ::google::protobuf::Service::STUB_DOESNT_OWN_CHANNEL),99 server(channel.get(), ::google::protobuf::Service::STUB_DOESNT_OWN_CHANNEL),
101 debug(channel.get(), ::google::protobuf::Service::STUB_DOESNT_OWN_CHANNEL),100 debug(channel.get(), ::google::protobuf::Service::STUB_DOESNT_OWN_CHANNEL),
102 logger(conf.the_logger()),101 logger(conf.the_logger()),
102 connect_done{false},
103 client_platform_factory(conf.the_client_platform_factory()),103 client_platform_factory(conf.the_client_platform_factory()),
104 input_platform(conf.the_input_platform()),104 input_platform(conf.the_input_platform()),
105 display_configuration(conf.the_display_configuration()),105 display_configuration(conf.the_display_configuration()),
@@ -235,6 +235,9 @@
235 set_error_message("Connect failed");235 set_error_message("Connect failed");
236 }236 }
237 }237 }
238
239 connect_done = true;
240
238 /*241 /*
239 * We need to create the client platform after the connection has been242 * We need to create the client platform after the connection has been
240 * established, to ensure that the client platform has access to all243 * established, to ensure that the client platform has access to all
@@ -370,9 +373,9 @@
370373
371void MirConnection::populate(MirPlatformPackage& platform_package)374void MirConnection::populate(MirPlatformPackage& platform_package)
372{375{
373 std::lock_guard<decltype(mutex)> lock(mutex);376 // connect_result is write-once: once it's valid, we don't need to lock
374377 // to use it.
375 if (!connect_result.has_error() && connect_result.has_platform())378 if (connect_done && !connect_result.has_error() && connect_result.has_platform())
376 {379 {
377 auto const& platform = connect_result.platform();380 auto const& platform = connect_result.platform();
378381
@@ -428,11 +431,6 @@
428 return platform;431 return platform;
429}432}
430433
431MirConnection* MirConnection::mir_connection()
432{
433 return this;
434}
435
436EGLNativeDisplayType MirConnection::egl_native_display()434EGLNativeDisplayType MirConnection::egl_native_display()
437{435{
438 std::lock_guard<decltype(mutex)> lock(mutex);436 std::lock_guard<decltype(mutex)> lock(mutex);
439437
=== modified file 'src/client/mir_connection.h'
--- src/client/mir_connection.h 2014-12-11 02:43:01 +0000
+++ src/client/mir_connection.h 2014-12-12 01:38:38 +0000
@@ -22,6 +22,7 @@
22#include <memory>22#include <memory>
23#include <unordered_set>23#include <unordered_set>
24#include <unordered_map>24#include <unordered_map>
25#include <atomic>
2526
26#include <mutex>27#include <mutex>
2728
@@ -117,8 +118,6 @@
117118
118 static bool is_valid(MirConnection *connection);119 static bool is_valid(MirConnection *connection);
119120
120 MirConnection* mir_connection();
121
122 EGLNativeDisplayType egl_native_display();121 EGLNativeDisplayType egl_native_display();
123122
124 void on_surface_created(int id, MirSurface* surface);123 void on_surface_created(int id, MirSurface* surface);
@@ -153,6 +152,7 @@
153 std::shared_ptr<mir::logging::Logger> const logger;152 std::shared_ptr<mir::logging::Logger> const logger;
154 mir::protobuf::Void void_response;153 mir::protobuf::Void void_response;
155 mir::protobuf::Connection connect_result;154 mir::protobuf::Connection connect_result;
155 std::atomic<bool> connect_done;
156 mir::protobuf::Void ignored;156 mir::protobuf::Void ignored;
157 mir::protobuf::ConnectParameters connect_parameters;157 mir::protobuf::ConnectParameters connect_parameters;
158 mir::protobuf::DRMAuthMagicStatus drm_auth_magic_status;158 mir::protobuf::DRMAuthMagicStatus drm_auth_magic_status;
159159
=== modified file 'src/client/mir_surface_api.cpp'
--- src/client/mir_surface_api.cpp 2014-12-09 03:14:55 +0000
+++ src/client/mir_surface_api.cpp 2014-12-12 01:38:38 +0000
@@ -83,11 +83,13 @@
83 params.buffer_usage = requested_specification->buffer_usage;83 params.buffer_usage = requested_specification->buffer_usage;
84 params.output_id = requested_specification->output_id;84 params.output_id = requested_specification->output_id;
8585
86 bool fullscreen_tmp = requested_specification->fullscreen;
87
86 auto shim_callback = new std::function<void(MirSurface*)>;88 auto shim_callback = new std::function<void(MirSurface*)>;
87 *shim_callback = [requested_specification, shim_callback, callback, context]89 *shim_callback = [fullscreen_tmp, shim_callback, callback, context]
88 (MirSurface* surface)90 (MirSurface* surface)
89 {91 {
90 if (requested_specification->fullscreen)92 if (fullscreen_tmp)
91 {93 {
92 mir_surface_set_state(surface, mir_surface_state_fullscreen);94 mir_surface_set_state(surface, mir_surface_state_fullscreen);
93 }95 }
9496
=== added file 'src/client/probing_client_platform_factory.cpp'
--- src/client/probing_client_platform_factory.cpp 1970-01-01 00:00:00 +0000
+++ src/client/probing_client_platform_factory.cpp 2014-12-12 01:38:38 +0000
@@ -0,0 +1,38 @@
1#include "probing_client_platform_factory.h"
2
3#include <boost/exception/all.hpp>
4#include <stdexcept>
5
6namespace mcl = mir::client;
7
8mcl::ProbingClientPlatformFactory::ProbingClientPlatformFactory(std::vector<std::shared_ptr<mir::SharedLibrary>> const& modules)
9 : platform_modules{modules}
10{
11 if (modules.empty())
12 {
13 BOOST_THROW_EXCEPTION(
14 std::runtime_error{"Attempted to create a ClientPlatformFactory with no platform modules"});
15 }
16}
17
18std::shared_ptr<mcl::ClientPlatform>
19mcl::ProbingClientPlatformFactory::create_client_platform(mcl::ClientContext* context)
20{
21 for (auto& module : platform_modules)
22 {
23 try
24 {
25 auto probe = module->load_function<mir::client::ClientPlatformProbe>("is_appropriate_module", CLIENT_PLATFORM_VERSION);
26 if (probe(context))
27 {
28 auto factory = module->load_function<mir::client::CreateClientPlatform>("create_client_platform", CLIENT_PLATFORM_VERSION);
29 return factory(context);
30 }
31 }
32 catch(std::runtime_error)
33 {
34 // We were handled a SharedLibrary that's not a client platform module?
35 }
36 }
37 BOOST_THROW_EXCEPTION(std::runtime_error{"No appropriate client platform module found"});
38}
039
=== added file 'src/client/probing_client_platform_factory.h'
--- src/client/probing_client_platform_factory.h 1970-01-01 00:00:00 +0000
+++ src/client/probing_client_platform_factory.h 2014-12-12 01:38:38 +0000
@@ -0,0 +1,27 @@
1#ifndef MIR_CLIENT_PROBING_CLIENT_PLATFORM_FACTORY_H_
2#define MIR_CLIENT_PROBING_CLIENT_PLATFORM_FACTORY_H_
3
4#include <vector>
5
6#include "client_platform_factory.h"
7#include "mir/shared_library.h"
8
9namespace mir
10{
11namespace client
12{
13class ProbingClientPlatformFactory : public ClientPlatformFactory
14{
15public:
16 ProbingClientPlatformFactory(std::vector<std::shared_ptr<SharedLibrary>> const& modules);
17
18 std::shared_ptr<ClientPlatform> create_client_platform(ClientContext *context) override;
19private:
20 std::vector<std::shared_ptr<SharedLibrary>> platform_modules;
21};
22
23
24}
25}
26
27#endif // MIR_CLIENT_PROBING_CLIENT_PLATFORM_FACTORY_H_
028
=== modified file 'src/common/symbols.map'
--- src/common/symbols.map 2014-12-11 02:43:01 +0000
+++ src/common/symbols.map 2014-12-12 01:38:38 +0000
@@ -203,11 +203,10 @@
203};203};
204204
205MIR_COMMON_3.1 {205MIR_COMMON_3.1 {
206 global:206 global:
207 extern "C++" {207 extern "C++" {
208 mir::log*;208 mir::log*;
209 mir::logv*;209 mir::logv*;
210 };210 mir::libraries_for_path*;
211 local: *;211 };
212};212} MIR_COMMON_3;
213
214213
=== modified file 'tests/CMakeLists.txt'
--- tests/CMakeLists.txt 2014-12-08 04:03:47 +0000
+++ tests/CMakeLists.txt 2014-12-12 01:38:38 +0000
@@ -26,9 +26,17 @@
26endif()26endif()
2727
28if (MIR_TEST_PLATFORM STREQUAL "android")28if (MIR_TEST_PLATFORM STREQUAL "android")
29 add_definitions(-DANDROID)
30endif()
31
32if (MIR_BUILD_PLATFORM_ANDROID)
29 #avoid complaints about poor quality android headers33 #avoid complaints about poor quality android headers
30 include_directories(SYSTEM ${LIBHARDWARE_INCLUDE_DIRS})34 include_directories(SYSTEM ${LIBHARDWARE_INCLUDE_DIRS})
31 add_definitions(-DANDROID)35 add_definitions(-DMIR_BUILD_PLATFORM_ANDROID)
36endif()
37
38if (MIR_BUILD_PLATFORM_MESA)
39 add_definitions(-DMIR_BUILD_PLATFORM_MESA)
32endif()40endif()
3341
34include_directories(42include_directories(
3543
=== modified file 'tests/acceptance-tests/CMakeLists.txt'
--- tests/acceptance-tests/CMakeLists.txt 2014-12-11 02:43:01 +0000
+++ tests/acceptance-tests/CMakeLists.txt 2014-12-12 01:38:38 +0000
@@ -6,7 +6,6 @@
66
7add_definitions(7add_definitions(
8 -DMIR_PLATFORM_DRIVER_BINARY="${MIR_PLATFORM_DRIVER_BINARY}"8 -DMIR_PLATFORM_DRIVER_BINARY="${MIR_PLATFORM_DRIVER_BINARY}"
9 -DMIR_CLIENT_DRIVER_BINARY="${MIR_CLIENT_DRIVER_BINARY}"
10)9)
1110
12set(11set(
@@ -52,7 +51,7 @@
52 list(APPEND SOURCES test_symbols_required_by_mesa.cpp)51 list(APPEND SOURCES test_symbols_required_by_mesa.cpp)
53endif()52endif()
5453
55add_executable(54mir_add_wrapped_executable(
56 mir_acceptance_tests55 mir_acceptance_tests
5756
58 ${SOURCES}57 ${SOURCES}
@@ -74,9 +73,9 @@
74 mirplatform73 mirplatform
7574
76 mir-test75 mir-test
77 mir-test-framework
78 mir-test-doubles76 mir-test-doubles
79 mir-test-doubles-platform77 mir-test-doubles-platform
78 mir-test-framework
80 3rd_party79 3rd_party
8180
82 ${PROTOBUF_LIBRARIES}81 ${PROTOBUF_LIBRARIES}
@@ -97,8 +96,3 @@
97if (MIR_RUN_ACCEPTANCE_TESTS)96if (MIR_RUN_ACCEPTANCE_TESTS)
98 mir_discover_tests(mir_acceptance_tests)97 mir_discover_tests(mir_acceptance_tests)
99endif (MIR_RUN_ACCEPTANCE_TESTS)98endif (MIR_RUN_ACCEPTANCE_TESTS)
100
101install(
102 TARGETS mir_acceptance_tests
103 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
104)
10599
=== modified file 'tests/acceptance-tests/test_client_library.cpp'
--- tests/acceptance-tests/test_client_library.cpp 2014-12-11 02:43:01 +0000
+++ tests/acceptance-tests/test_client_library.cpp 2014-12-12 01:38:38 +0000
@@ -20,6 +20,7 @@
2020
21#include "mir_test_framework/headless_in_process_server.h"21#include "mir_test_framework/headless_in_process_server.h"
22#include "mir_test_framework/using_stub_client_platform.h"22#include "mir_test_framework/using_stub_client_platform.h"
23#include "mir_test_framework/stub_platform_helpers.h"
23#include "mir_test/validity_matchers.h"24#include "mir_test/validity_matchers.h"
2425
25#include "src/client/client_buffer.h"26#include "src/client/client_buffer.h"
@@ -201,6 +202,7 @@
201 EXPECT_EQ(request_buffer_usage, response_params.buffer_usage);202 EXPECT_EQ(request_buffer_usage, response_params.buffer_usage);
202203
203 mir_wait_for(mir_surface_release( surface, release_surface_callback, this));204 mir_wait_for(mir_surface_release( surface, release_surface_callback, this));
205 mir_connection_release(connection);
204}206}
205207
206TEST_F(ClientLibrary, can_set_surface_types)208TEST_F(ClientLibrary, can_set_surface_types)
@@ -545,15 +547,14 @@
545547
546TEST_F(ClientLibrary, accesses_platform_package)548TEST_F(ClientLibrary, accesses_platform_package)
547{549{
550 using namespace testing;
548 mir_wait_for(mir_connect(new_connection().c_str(), __PRETTY_FUNCTION__, connection_callback, this));551 mir_wait_for(mir_connect(new_connection().c_str(), __PRETTY_FUNCTION__, connection_callback, this));
549552
550 MirPlatformPackage platform_package;553 MirPlatformPackage platform_package;
551 platform_package.data_items = -1;554 ::memset(&platform_package, -1, sizeof(platform_package));
552 platform_package.fd_items = -1;
553555
554 mir_connection_get_platform(connection, &platform_package);556 mir_connection_get_platform(connection, &platform_package);
555 EXPECT_GE(0, platform_package.data_items);557 EXPECT_THAT(platform_package, mtf::IsStubPlatformPackage());
556 EXPECT_GE(0, platform_package.fd_items);
557558
558 mir_connection_release(connection);559 mir_connection_release(connection);
559}560}
560561
=== modified file 'tests/acceptance-tests/test_client_library_drm.cpp'
--- tests/acceptance-tests/test_client_library_drm.cpp 2014-12-08 04:03:47 +0000
+++ tests/acceptance-tests/test_client_library_drm.cpp 2014-12-12 01:38:38 +0000
@@ -32,10 +32,15 @@
32{32{
33 struct gbm_device* dev = reinterpret_cast<struct gbm_device*>(connection);33 struct gbm_device* dev = reinterpret_cast<struct gbm_device*>(connection);
3434
35 MirPlatformPackage pkg;
36
37 mir_connection_get_platform(connection, &pkg);
38 int const previous_data_count{pkg.data_items};
39
35 mir_connection_drm_set_gbm_device(connection, dev);40 mir_connection_drm_set_gbm_device(connection, dev);
41 mir_connection_get_platform(connection, &pkg);
3642
37 MirPlatformPackage pkg;43 EXPECT_THAT(pkg.data_items, Eq(previous_data_count + (sizeof(dev) / sizeof(int))));
38 mir_connection_get_platform(connection, &pkg);44 EXPECT_THAT(reinterpret_cast<struct gbm_device*>(pkg.data[previous_data_count]),
39 EXPECT_THAT(pkg.data_items, Eq(sizeof(dev) / sizeof(int)));45 Eq(dev));
40 EXPECT_THAT(*reinterpret_cast<struct gbm_device**>(&pkg.data[0]), Eq(dev));
41}46}
4247
=== modified file 'tests/acceptance-tests/test_symbols_required_by_mesa.cpp'
--- tests/acceptance-tests/test_symbols_required_by_mesa.cpp 2014-12-08 04:03:47 +0000
+++ tests/acceptance-tests/test_symbols_required_by_mesa.cpp 2014-12-12 01:38:38 +0000
@@ -21,11 +21,14 @@
2121
22#include <dlfcn.h>22#include <dlfcn.h>
2323
24#include "mir_test_framework/executable_path.h"
25
24using namespace testing;26using namespace testing;
27namespace mtf = mir_test_framework;
2528
26TEST(SymbolsRequiredByMesa, are_exported_by_libmirclientplatform)29TEST(SymbolsRequiredByMesa, are_exported_by_client_platform_mesa)
27{30{
28 auto const handle = dlopen(MIR_CLIENT_DRIVER_BINARY, RTLD_LAZY);31 auto const handle = dlopen((mtf::library_path() + "/client-modules/mesa.so").c_str(), RTLD_LAZY);
29 ASSERT_THAT(handle, NotNull());32 ASSERT_THAT(handle, NotNull());
3033
31 auto const sym = dlsym(handle, "mir_client_mesa_egl_native_display_is_valid");34 auto const sym = dlsym(handle, "mir_client_mesa_egl_native_display_is_valid");
3235
=== modified file 'tests/include/mir_test_doubles/mock_client_context.h'
--- tests/include/mir_test_doubles/mock_client_context.h 2013-04-24 05:22:20 +0000
+++ tests/include/mir_test_doubles/mock_client_context.h 2014-12-12 01:38:38 +0000
@@ -33,18 +33,12 @@
33struct MockClientContext : public client::ClientContext33struct MockClientContext : public client::ClientContext
34{34{
35 MockClientContext()35 MockClientContext()
36 : connection{reinterpret_cast<MirConnection*>(0xabcdef)}
37 {36 {
38 using namespace testing;37 using namespace testing;
3938
40 ON_CALL(*this, mir_connection()).WillByDefault(Return(connection));
41 EXPECT_CALL(*this, mir_connection()).Times(AtLeast(0));
42 EXPECT_CALL(*this, populate(_)).Times(AtLeast(0));39 EXPECT_CALL(*this, populate(_)).Times(AtLeast(0));
43 }40 }
4441
45 MirConnection* connection;
46
47 MOCK_METHOD0(mir_connection, MirConnection*());
48 MOCK_METHOD1(populate, void(MirPlatformPackage&));42 MOCK_METHOD1(populate, void(MirPlatformPackage&));
49};43};
5044
5145
=== modified file 'tests/include/mir_test_doubles/stub_client_buffer.h'
--- tests/include/mir_test_doubles/stub_client_buffer.h 2014-11-24 16:04:38 +0000
+++ tests/include/mir_test_doubles/stub_client_buffer.h 2014-12-12 01:38:38 +0000
@@ -65,7 +65,11 @@
6565
66 std::shared_ptr<graphics::NativeBuffer> native_buffer_handle() const override66 std::shared_ptr<graphics::NativeBuffer> native_buffer_handle() const override
67 {67 {
68#ifndef ANDROID
69 return package;
70#else
68 return std::shared_ptr<graphics::NativeBuffer>();71 return std::shared_ptr<graphics::NativeBuffer>();
72#endif
69 }73 }
70 void update_from(MirBufferPackage const&) override {}74 void update_from(MirBufferPackage const&) override {}
71 void fill_update_msg(MirBufferPackage&) override{}75 void fill_update_msg(MirBufferPackage&) override{}
7276
=== added file 'tests/include/mir_test_framework/client_platform_factory.h'
--- tests/include/mir_test_framework/client_platform_factory.h 1970-01-01 00:00:00 +0000
+++ tests/include/mir_test_framework/client_platform_factory.h 2014-12-12 01:38:38 +0000
@@ -0,0 +1,72 @@
1/*
2 * Copyright © 2014 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Christopher James Halse Rogers <christopher.halse.rogers@canonical.com>
17 */
18
19#ifndef MIR_TEST_FRAMEWORK_CLIENT_PLATFORM_FACTORY_H_
20#define MIR_TEST_FRAMEWORK_CLIENT_PLATFORM_FACTORY_H_
21
22
23#include "mir/shared_library.h"
24#include "src/client/client_platform_factory.h"
25#include "executable_path.h"
26#include "mir_test_doubles/mock_client_context.h"
27
28namespace mtd = mir::test::doubles;
29
30namespace mir_test_framework
31{
32std::shared_ptr<mir::SharedLibrary> platform_library;
33
34std::shared_ptr<mir::client::ClientPlatform> create_android_client_platform()
35{
36 using namespace testing;
37 mtd::MockClientContext ctx;
38 ON_CALL(ctx, populate(_))
39 .WillByDefault(Invoke([](MirPlatformPackage& package) { ::memset(&package, 0, sizeof(package)); }));
40 platform_library = std::make_shared<mir::SharedLibrary>(library_path() + "/client-modules/android.so");
41 auto platform_factory = platform_library->load_function<mir::client::CreateClientPlatform>("create_client_platform");
42 return platform_factory(&ctx);
43}
44
45std::shared_ptr<mir::client::ClientPlatform> create_mesa_client_platform()
46{
47 using namespace testing;
48 mtd::MockClientContext ctx;
49 ON_CALL(ctx, populate(_))
50 .WillByDefault(Invoke([](MirPlatformPackage& package)
51 {
52 ::memset(&package, 0, sizeof(package));
53 package.fd_items = 1;
54 }));
55 platform_library = std::make_shared<mir::SharedLibrary>(library_path() + "/client-modules/mesa.so");
56 auto platform_factory = platform_library->load_function<mir::client::CreateClientPlatform>("create_client_platform");
57 return platform_factory(&ctx);
58}
59
60std::shared_ptr<mir::SharedLibrary>
61get_platform_library()
62{
63 if (!platform_library)
64 {
65 throw std::logic_error{"Must call one of create_*_client_platform() before calling get_platform_library()"};
66 }
67 return platform_library;
68}
69
70}
71
72#endif // MIR_TEST_FRAMEWORK_CLIENT_PLATFORM_FACTORY_H_
073
=== added file 'tests/include/mir_test_framework/stub_client_platform_factory.h'
--- tests/include/mir_test_framework/stub_client_platform_factory.h 1970-01-01 00:00:00 +0000
+++ tests/include/mir_test_framework/stub_client_platform_factory.h 2014-12-12 01:38:38 +0000
@@ -0,0 +1,33 @@
1/*
2 * Copyright © 2014 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Christopher James Halse Rogers <christopher.halse.rogers@canonical.com>
17 */
18
19#ifndef MIR_TEST_FRAMEWORK_STUB_CLIENT_PLATFORM_FACTORY_
20#define MIR_TEST_FRAMEWORK_STUB_CLIENT_PLATFORM_FACTORY_
21
22#include "src/client/client_platform_factory.h"
23
24namespace mir_test_framework
25{
26
27struct StubClientPlatformFactory : public mir::client::ClientPlatformFactory
28{
29 std::shared_ptr<mir::client::ClientPlatform> create_client_platform(mir::client::ClientContext* context) override;
30};
31
32}
33#endif /* MIR_TEST_FRAMEWORK_STUB_CLIENT_PLATFORM_ */
034
=== added file 'tests/include/mir_test_framework/stub_platform_helpers.h'
--- tests/include/mir_test_framework/stub_platform_helpers.h 1970-01-01 00:00:00 +0000
+++ tests/include/mir_test_framework/stub_platform_helpers.h 2014-12-12 01:38:38 +0000
@@ -0,0 +1,53 @@
1/*
2 * Copyright © 2014 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Christopher James Halse Rogers <christopher.halse.rogers@canonical.com>
17 */
18
19#ifndef MIR_TEST_FRAMEWORK_STUB_PLATFORM_HELPERS_H_
20#define MIR_TEST_FRAMEWORK_STUB_PLATFORM_HELPERS_H_
21
22#include "mir/graphics/platform_ipc_package.h"
23#include "mir_toolkit/client_types.h"
24
25#include <gmock/gmock.h>
26
27namespace mir_test_framework
28{
29constexpr int stub_data_size{21};
30constexpr int stub_data_guard{0x0eadbeef};
31
32static inline void pack_stub_ipc_package(mir::graphics::PlatformIPCPackage& package)
33{
34 package.ipc_data = std::vector<int32_t>(stub_data_size, -1);
35 package.ipc_data[0] = stub_data_guard;
36}
37
38static inline void create_stub_platform_package(MirPlatformPackage& package)
39{
40 ::memset(&package, 0, sizeof(package));
41 package.data_items = stub_data_size;
42 package.data[0] = stub_data_guard;
43}
44
45MATCHER(IsStubPlatformPackage, "")
46{
47 return (arg.data_items == stub_data_size) &&
48 (arg.data[0] == stub_data_guard) &&
49 (arg.fd_items == 0);
50}
51}
52
53#endif // MIR_TEST_FRAMEWORK_STUB_PLATFORM_HELPERS_H_
054
=== modified file 'tests/integration-tests/CMakeLists.txt'
--- tests/integration-tests/CMakeLists.txt 2014-12-08 04:03:47 +0000
+++ tests/integration-tests/CMakeLists.txt 2014-12-12 01:38:38 +0000
@@ -66,7 +66,7 @@
66endif()66endif()
6767
68link_directories(${LIBRARY_OUTPUT_PATH})68link_directories(${LIBRARY_OUTPUT_PATH})
69add_executable(69mir_add_wrapped_executable(
70 mir_integration_tests70 mir_integration_tests
71 ${INTEGRATION_TESTS_SRCS}71 ${INTEGRATION_TESTS_SRCS}
72 ${MIR_SERVER_OBJECTS}72 ${MIR_SERVER_OBJECTS}
@@ -126,8 +126,3 @@
126if (MIR_RUN_INTEGRATION_TESTS)126if (MIR_RUN_INTEGRATION_TESTS)
127 mir_discover_tests(mir_integration_tests)127 mir_discover_tests(mir_integration_tests)
128endif (MIR_RUN_INTEGRATION_TESTS)128endif (MIR_RUN_INTEGRATION_TESTS)
129
130install(
131 TARGETS mir_integration_tests
132 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
133)
134129
=== modified file 'tests/mir_test_doubles/CMakeLists.txt'
--- tests/mir_test_doubles/CMakeLists.txt 2014-12-08 04:03:47 +0000
+++ tests/mir_test_doubles/CMakeLists.txt 2014-12-12 01:38:38 +0000
@@ -30,13 +30,14 @@
30 ${CMAKE_CURRENT_SOURCE_DIR}/mock_gl.cpp30 ${CMAKE_CURRENT_SOURCE_DIR}/mock_gl.cpp
31)31)
3232
33if (MIR_TEST_PLATFORM STREQUAL "mesa")33if (MIR_BUILD_PLATFORM_MESA)
34include_directories(${DRM_INCLUDE_DIRS} ${GBM_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR})34include_directories(${DRM_INCLUDE_DIRS} ${GBM_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR})
35list(APPEND MIR_TEST_DOUBLES_PLATFORM_SRCS35list(APPEND MIR_TEST_DOUBLES_PLATFORM_SRCS
36 ${CMAKE_CURRENT_SOURCE_DIR}/mock_drm.cpp36 ${CMAKE_CURRENT_SOURCE_DIR}/mock_drm.cpp
37 ${CMAKE_CURRENT_SOURCE_DIR}/mock_gbm.cpp37 ${CMAKE_CURRENT_SOURCE_DIR}/mock_gbm.cpp
38)38)
39elseif (MIR_TEST_PLATFORM STREQUAL "android")39endif()
40if (MIR_BUILD_PLATFORM_ANDROID)
40list(APPEND MIR_TEST_DOUBLES_PLATFORM_SRCS41list(APPEND MIR_TEST_DOUBLES_PLATFORM_SRCS
41 ${CMAKE_CURRENT_SOURCE_DIR}/mock_android_hw.cpp42 ${CMAKE_CURRENT_SOURCE_DIR}/mock_android_hw.cpp
42)43)
4344
=== modified file 'tests/mir_test_framework/CMakeLists.txt'
--- tests/mir_test_framework/CMakeLists.txt 2014-12-11 02:43:01 +0000
+++ tests/mir_test_framework/CMakeLists.txt 2014-12-12 01:38:38 +0000
@@ -4,10 +4,11 @@
4 ${PROJECT_SOURCE_DIR}/src/include/common4 ${PROJECT_SOURCE_DIR}/src/include/common
5 ${PROJECT_SOURCE_DIR}/src/include/server5 ${PROJECT_SOURCE_DIR}/src/include/server
6 ${PROJECT_SOURCE_DIR}/src/include/client6 ${PROJECT_SOURCE_DIR}/src/include/client
7 ${Boost_INCLUDE_DIRS}7 ${Boost_INCLUDE_DIRS}
8 ${GLESv2_INCLUDE_DIRS}8 ${GLESv2_INCLUDE_DIRS}
9 ${CMAKE_SOURCE_DIR}9 ${CMAKE_SOURCE_DIR}
10 ${UMOCKDEV_INCLUDE_DIRS}10 ${UMOCKDEV_INCLUDE_DIRS}
11 ${ANDROID_HEADERS_INCLUDE_DIRS}
11)12)
1213
13set(14set(
@@ -31,6 +32,7 @@
31 display_server_test_fixture.cpp32 display_server_test_fixture.cpp
32 process.cpp33 process.cpp
33 using_stub_client_platform.cpp34 using_stub_client_platform.cpp
35 stub_client_platform_factory.cpp
34 udev_environment.cpp36 udev_environment.cpp
35 declarative_placement_strategy.cpp37 declarative_placement_strategy.cpp
36 fake_event_hub_server_configuration.cpp38 fake_event_hub_server_configuration.cpp
@@ -68,6 +70,29 @@
68 ${CMAKE_THREAD_LIBS_INIT} # Link in pthread.70 ${CMAKE_THREAD_LIBS_INIT} # Link in pthread.
69)71)
7072
73set(symbol_map ${CMAKE_CURRENT_SOURCE_DIR}/symbols-client.map)
74
75add_library(
76 mirclientplatformstub MODULE
77
78 stub_client_platform_module.cpp
79)
80
81target_link_libraries(
82 mirclientplatformstub
83
84 mir-test-framework
85 ${UMOCKDEV_LDFLAGS} ${UMOCKDEV_LIBRARIES}
86)
87
88set_target_properties(
89 mirclientplatformstub PROPERTIES;
90 LIBRARY_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH}/client-modules
91 OUTPUT_NAME dummy
92 PREFIX ""
93 LINK_FLAGS "-Wl,--version-script,${symbol_map}"
94)
95
71add_custom_command(TARGET mir-test-framework POST_BUILD96add_custom_command(TARGET mir-test-framework POST_BUILD
72 COMMAND ${CMAKE_COMMAND} -E copy_directory97 COMMAND ${CMAKE_COMMAND} -E copy_directory
73 ${CMAKE_CURRENT_SOURCE_DIR}/udev_recordings ${CMAKE_BINARY_DIR}/bin/udev_recordings98 ${CMAKE_CURRENT_SOURCE_DIR}/udev_recordings ${CMAKE_BINARY_DIR}/bin/udev_recordings
@@ -96,3 +121,4 @@
96)121)
97122
98install(TARGETS mirplatformstub LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})123install(TARGETS mirplatformstub LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
124install(TARGETS mirclientplatformstub LIBRARY DESTINATION ${MIR_CLIENT_PLATFORM_PATH})
99125
=== added file 'tests/mir_test_framework/stub_client_platform_factory.cpp'
--- tests/mir_test_framework/stub_client_platform_factory.cpp 1970-01-01 00:00:00 +0000
+++ tests/mir_test_framework/stub_client_platform_factory.cpp 2014-12-12 01:38:38 +0000
@@ -0,0 +1,74 @@
1/*
2 * Copyright © 2014 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Christopher James Halse Rogers <christopher.halse.rogers@canonical.com>
17 */
18
19#include "mir_test_framework/stub_client_platform_factory.h"
20#include "mir_test_doubles/stub_client_buffer_factory.h"
21#include "src/client/client_buffer_factory.h"
22#include "src/client/client_buffer.h"
23#include "src/client/client_platform.h"
24
25#include <string.h>
26
27namespace mcl = mir::client;
28namespace geom = mir::geometry;
29namespace mtf = mir_test_framework;
30namespace mtd = mir::test::doubles;
31
32namespace
33{
34struct StubClientPlatform : public mcl::ClientPlatform
35{
36 MirPlatformType platform_type() const
37 {
38 return mir_platform_type_gbm;
39 }
40
41 std::shared_ptr<mcl::ClientBufferFactory> create_buffer_factory()
42 {
43 return std::make_shared<mtd::StubClientBufferFactory>();
44 }
45
46 std::shared_ptr<EGLNativeWindowType> create_egl_native_window(mcl::ClientSurface*)
47 {
48 auto fake_window = reinterpret_cast<EGLNativeWindowType>(0x12345678lu);
49 return std::make_shared<EGLNativeWindowType>(fake_window);
50 }
51
52 std::shared_ptr<EGLNativeDisplayType> create_egl_native_display()
53 {
54 auto fake_display = reinterpret_cast<EGLNativeDisplayType>(0x12345678lu);
55 return std::make_shared<EGLNativeDisplayType>(fake_display);
56 }
57
58 MirNativeBuffer* convert_native_buffer(mir::graphics::NativeBuffer* buf) const
59 {
60 static_cast<void>(buf);
61#ifndef ANDROID
62 return buf;
63#else
64 return nullptr;
65#endif
66 }
67};
68}
69
70std::shared_ptr<mcl::ClientPlatform>
71mtf::StubClientPlatformFactory::create_client_platform(mcl::ClientContext*)
72{
73 return std::make_shared<StubClientPlatform>();
74}
075
=== added file 'tests/mir_test_framework/stub_client_platform_module.cpp'
--- tests/mir_test_framework/stub_client_platform_module.cpp 1970-01-01 00:00:00 +0000
+++ tests/mir_test_framework/stub_client_platform_module.cpp 2014-12-12 01:38:38 +0000
@@ -0,0 +1,41 @@
1/*
2 * Copyright © 2014 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Christopher James Halse Rogers <christopher.halse.rogers@canonical.com>>
17 */
18
19#include "src/client/client_platform_factory.h"
20#include "src/client/client_context.h"
21
22#include "mir_test_framework/stub_client_platform_factory.h"
23#include "mir_test_framework/stub_platform_helpers.h"
24#include <memory>
25#include <gmock/gmock.h>
26
27namespace mtf = mir_test_framework;
28namespace mcl = mir::client;
29
30extern "C" std::shared_ptr<mcl::ClientPlatform> create_client_platform(mcl::ClientContext* context)
31{
32 return mtf::StubClientPlatformFactory{}.create_client_platform(context);
33}
34
35extern "C" bool is_appropriate_module(mcl::ClientContext* context)
36{
37 using namespace testing;
38 MirPlatformPackage package;
39 context->populate(package);
40 return Matches(mtf::IsStubPlatformPackage())(package);
41}
042
=== modified file 'tests/mir_test_framework/stubbed_graphics_platform.cpp'
--- tests/mir_test_framework/stubbed_graphics_platform.cpp 2014-12-11 02:43:01 +0000
+++ tests/mir_test_framework/stubbed_graphics_platform.cpp 2014-12-12 01:38:38 +0000
@@ -22,6 +22,8 @@
22#include "mir/graphics/buffer_writer.h"22#include "mir/graphics/buffer_writer.h"
23#include "mir/graphics/native_platform.h"23#include "mir/graphics/native_platform.h"
2424
25#include "mir_test_framework/stub_platform_helpers.h"
26
25#include "mir_test_doubles/stub_buffer_allocator.h"27#include "mir_test_doubles/stub_buffer_allocator.h"
26#include "mir_test_doubles/stub_display.h"28#include "mir_test_doubles/stub_display.h"
2729
@@ -146,7 +148,9 @@
146148
147 std::shared_ptr<mg::PlatformIPCPackage> connection_ipc_package() override149 std::shared_ptr<mg::PlatformIPCPackage> connection_ipc_package() override
148 {150 {
149 return std::make_shared<mg::PlatformIPCPackage>();151 auto package = std::make_shared<mg::PlatformIPCPackage>();
152 mtf::pack_stub_ipc_package(*package);
153 return package;
150 }154 }
151155
152 mg::PlatformIPCPackage platform_operation(156 mg::PlatformIPCPackage platform_operation(
153157
=== added file 'tests/mir_test_framework/symbols-client.map'
--- tests/mir_test_framework/symbols-client.map 1970-01-01 00:00:00 +0000
+++ tests/mir_test_framework/symbols-client.map 2014-12-12 01:38:38 +0000
@@ -0,0 +1,7 @@
1MIR_CLIENT_PLATFORM_2 {
2 global:
3 create_client_platform;
4 is_appropriate_module;
5 local:
6 *;
7};
08
=== modified file 'tests/unit-tests/CMakeLists.txt'
--- tests/unit-tests/CMakeLists.txt 2014-12-08 04:03:47 +0000
+++ tests/unit-tests/CMakeLists.txt 2014-12-12 01:38:38 +0000
@@ -56,7 +56,7 @@
5656
57link_directories(${LIBRARY_OUTPUT_PATH})57link_directories(${LIBRARY_OUTPUT_PATH})
5858
59add_executable(mir_unit_tests 59mir_add_wrapped_executable(mir_unit_tests
60 ${UNIT_TEST_SOURCES}60 ${UNIT_TEST_SOURCES}
61 ${MIR_SERVER_OBJECTS}61 ${MIR_SERVER_OBJECTS}
62 $<TARGET_OBJECTS:mirclientobjects>62 $<TARGET_OBJECTS:mirclientobjects>
@@ -117,11 +117,6 @@
117 mir_discover_tests(mir_unit_tests LD_PRELOAD=libumockdev-preload.so.0 G_SLICE=always-malloc G_DEBUG=gc-friendly)117 mir_discover_tests(mir_unit_tests LD_PRELOAD=libumockdev-preload.so.0 G_SLICE=always-malloc G_DEBUG=gc-friendly)
118endif (MIR_RUN_UNIT_TESTS)118endif (MIR_RUN_UNIT_TESTS)
119119
120install(
121 TARGETS mir_unit_tests
122 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
123)
124
125add_custom_command(TARGET mir_unit_tests POST_BUILD120add_custom_command(TARGET mir_unit_tests POST_BUILD
126 COMMAND ${CMAKE_COMMAND} -E copy_directory121 COMMAND ${CMAKE_COMMAND} -E copy_directory
127 ${CMAKE_CURRENT_SOURCE_DIR}/test_data ${CMAKE_BINARY_DIR}/bin/test_data122 ${CMAKE_CURRENT_SOURCE_DIR}/test_data ${CMAKE_BINARY_DIR}/bin/test_data
128123
=== modified file 'tests/unit-tests/client/CMakeLists.txt'
--- tests/unit-tests/client/CMakeLists.txt 2014-12-08 04:03:47 +0000
+++ tests/unit-tests/client/CMakeLists.txt 2014-12-12 01:38:38 +0000
@@ -10,6 +10,7 @@
10 ${CMAKE_CURRENT_SOURCE_DIR}/test_client_display_conf.cpp10 ${CMAKE_CURRENT_SOURCE_DIR}/test_client_display_conf.cpp
11 ${CMAKE_CURRENT_SOURCE_DIR}/test_mir_screencast.cpp11 ${CMAKE_CURRENT_SOURCE_DIR}/test_mir_screencast.cpp
12 ${CMAKE_CURRENT_SOURCE_DIR}/test_protobuf_rpc_channel.cpp12 ${CMAKE_CURRENT_SOURCE_DIR}/test_protobuf_rpc_channel.cpp
13 ${CMAKE_CURRENT_SOURCE_DIR}/test_probing_client_platform_factory.cpp
13 ${CMAKE_CURRENT_SOURCE_DIR}/test_mir_prompt_session.cpp14 ${CMAKE_CURRENT_SOURCE_DIR}/test_mir_prompt_session.cpp
14 ${CMAKE_CURRENT_SOURCE_DIR}/test_event_distributor.cpp15 ${CMAKE_CURRENT_SOURCE_DIR}/test_event_distributor.cpp
15 ${CMAKE_CURRENT_SOURCE_DIR}/test_periodic_perf_report.cpp16 ${CMAKE_CURRENT_SOURCE_DIR}/test_periodic_perf_report.cpp
1617
=== modified file 'tests/unit-tests/client/android/test_android_client_platform.cpp'
--- tests/unit-tests/client/android/test_android_client_platform.cpp 2014-03-06 06:05:17 +0000
+++ tests/unit-tests/client/android/test_android_client_platform.cpp 2014-12-12 01:38:38 +0000
@@ -17,9 +17,9 @@
17 */17 */
1818
19#include "src/client/client_platform.h"19#include "src/client/client_platform.h"
20#include "src/client/android/client_platform_factory.h"
21#include "mir_test_doubles/mock_client_context.h"20#include "mir_test_doubles/mock_client_context.h"
22#include "mir_test_doubles/mock_client_surface.h"21#include "mir_test_doubles/mock_client_surface.h"
22#include "mir_test_framework/client_platform_factory.h"
2323
24#include <EGL/egl.h>24#include <EGL/egl.h>
2525
@@ -28,13 +28,12 @@
28namespace mcl = mir::client;28namespace mcl = mir::client;
29namespace mt = mir::test;29namespace mt = mir::test;
30namespace mtd = mt::doubles;30namespace mtd = mt::doubles;
31namespace mtf = mir_test_framework;
3132
32TEST(AndroidClientPlatformTest, egl_native_display_is_egl_default_display)33TEST(AndroidClientPlatformTest, egl_native_display_is_egl_default_display)
33{34{
34 mtd::MockClientContext context;
35 mcl::android::ClientPlatformFactory factory;
36 mtd::MockClientSurface surface;35 mtd::MockClientSurface surface;
37 auto platform = factory.create_client_platform(&context);36 auto platform = mtf::create_android_client_platform();
38 auto mock_client_surface = std::make_shared<mtd::MockClientSurface>();37 auto mock_client_surface = std::make_shared<mtd::MockClientSurface>();
39 auto native_display = platform->create_egl_native_display();38 auto native_display = platform->create_egl_native_display();
40 EXPECT_EQ(EGL_DEFAULT_DISPLAY, *native_display);39 EXPECT_EQ(EGL_DEFAULT_DISPLAY, *native_display);
@@ -42,10 +41,8 @@
4241
43TEST(AndroidClientPlatformTest, egl_native_window_is_set)42TEST(AndroidClientPlatformTest, egl_native_window_is_set)
44{43{
45 mtd::MockClientContext context;
46 mcl::android::ClientPlatformFactory factory;
47 mtd::MockClientSurface surface;44 mtd::MockClientSurface surface;
48 auto platform = factory.create_client_platform(&context);45 auto platform = mtf::create_android_client_platform();
49 auto mock_client_surface = std::make_shared<mtd::MockClientSurface>();46 auto mock_client_surface = std::make_shared<mtd::MockClientSurface>();
50 auto egl_native_window = platform->create_egl_native_window(&surface);47 auto egl_native_window = platform->create_egl_native_window(&surface);
51 EXPECT_NE(nullptr, egl_native_window);48 EXPECT_NE(nullptr, egl_native_window);
5249
=== modified file 'tests/unit-tests/client/mesa/test_client_platform.cpp'
--- tests/unit-tests/client/mesa/test_client_platform.cpp 2014-03-06 06:05:17 +0000
+++ tests/unit-tests/client/mesa/test_client_platform.cpp 2014-12-12 01:38:38 +0000
@@ -17,9 +17,9 @@
17 */17 */
1818
19#include "src/client/client_platform.h"19#include "src/client/client_platform.h"
20#include "src/client/mesa/client_platform_factory.h"20#include "mir/shared_library.h"
21#include "src/client/mesa/mesa_native_display_container.h"21#include "src/client/mesa/mesa_native_display_container.h"
22#include "mir_test_doubles/mock_client_context.h"22#include "mir_test_framework/client_platform_factory.h"
23#include "mir_test_doubles/mock_client_surface.h"23#include "mir_test_doubles/mock_client_surface.h"
2424
25#include "mir_toolkit/mesa/native_display.h"25#include "mir_toolkit/mesa/native_display.h"
@@ -30,19 +30,20 @@
30namespace mclm = mir::client::mesa;30namespace mclm = mir::client::mesa;
31namespace mt = mir::test;31namespace mt = mir::test;
32namespace mtd = mir::test::doubles;32namespace mtd = mir::test::doubles;
33namespace mtf = mir_test_framework;
3334
34TEST(MesaClientPlatformTest, egl_native_display_is_valid_until_released)35TEST(MesaClientPlatformTest, egl_native_display_is_valid_until_released)
35{36{
36 mtd::MockClientContext context;37 auto platform = mtf::create_mesa_client_platform();
37 mclm::ClientPlatformFactory factory;38 auto platform_lib = mtf::get_platform_library();
38 auto platform = factory.create_client_platform(&context);
3939
40 MirMesaEGLNativeDisplay* nd;40 MirMesaEGLNativeDisplay* nd;
41 {41 {
42 std::shared_ptr<EGLNativeDisplayType> native_display = platform->create_egl_native_display();42 std::shared_ptr<EGLNativeDisplayType> native_display = platform->create_egl_native_display();
4343
44 nd = reinterpret_cast<MirMesaEGLNativeDisplay*>(*native_display);44 nd = reinterpret_cast<MirMesaEGLNativeDisplay*>(*native_display);
45 EXPECT_EQ(MIR_MESA_TRUE, mclm::mir_client_mesa_egl_native_display_is_valid(nd));45 auto validate = platform_lib->load_function<MirBool(*)(MirMesaEGLNativeDisplay*)>("mir_client_mesa_egl_native_display_is_valid");
46 EXPECT_EQ(MIR_MESA_TRUE, validate(nd));
46 }47 }
47 EXPECT_EQ(MIR_MESA_FALSE, mclm::mir_client_mesa_egl_native_display_is_valid(nd));48 EXPECT_EQ(MIR_MESA_FALSE, mclm::mir_client_mesa_egl_native_display_is_valid(nd));
48}49}
4950
=== modified file 'tests/unit-tests/client/mesa/test_mesa_native_display_container.cpp'
--- tests/unit-tests/client/mesa/test_mesa_native_display_container.cpp 2014-03-06 06:05:17 +0000
+++ tests/unit-tests/client/mesa/test_mesa_native_display_container.cpp 2014-12-12 01:38:38 +0000
@@ -40,7 +40,7 @@
40 }40 }
4141
42 std::shared_ptr<mclg::MesaNativeDisplayContainer> const container;42 std::shared_ptr<mclg::MesaNativeDisplayContainer> const container;
43 MirConnection* connection;43 mir::client::ClientContext* connection;
44};44};
4545
46}46}
4747
=== modified file 'tests/unit-tests/client/test_client_platform.cpp'
--- tests/unit-tests/client/test_client_platform.cpp 2014-03-06 06:05:17 +0000
+++ tests/unit-tests/client/test_client_platform.cpp 2014-12-12 01:38:38 +0000
@@ -20,60 +20,153 @@
20#include "src/client/mir_client_surface.h"20#include "src/client/mir_client_surface.h"
21#include "mir_test_doubles/mock_client_context.h"21#include "mir_test_doubles/mock_client_context.h"
22#include "mir_test_doubles/mock_client_surface.h"22#include "mir_test_doubles/mock_client_surface.h"
23#include "mir_test_framework/executable_path.h"
24#include "mir_test_framework/stub_platform_helpers.h"
2325
24#ifdef ANDROID26#ifdef MIR_BUILD_PLATFORM_ANDROID
25#include "mir_test_doubles/mock_android_hw.h"27#include "mir_test_doubles/mock_android_hw.h"
26#include "src/client/android/client_platform_factory.h"
27#else
28#include "src/client/mesa/client_platform_factory.h"
29#endif28#endif
3029
30#include "src/client/client_platform_factory.h"
31
32#include "mir/shared_library.h"
33
31#include <gmock/gmock.h>34#include <gmock/gmock.h>
32#include <gtest/gtest.h>35#include <gtest/gtest.h>
3336
34namespace mcl=mir::client;37namespace mcl=mir::client;
35namespace mtd = mir::test::doubles;38namespace mtd = mir::test::doubles;
3639namespace mtf = mir_test_framework;
37struct ClientPlatformTest : public ::testing::Test40
38{41namespace
42{
43struct ClientPlatformTraits
44{
45 ClientPlatformTraits(std::string const& library,
46 std::function<void(MirPlatformPackage&)> populator,
47 MirPlatformType type)
48 : platform_library_name{library},
49 populate_package_for{populator},
50 platform_type{type}
51 {
52 }
53
54 std::string const platform_library_name;
55 std::function<void(MirPlatformPackage&)> const populate_package_for;
56 MirPlatformType const platform_type;
57};
58
59struct ClientPlatformTest : public ::testing::TestWithParam<ClientPlatformTraits const*>
60{
61 ClientPlatformTest()
62 : platform_library{mtf::library_path() + "/" + GetParam()->platform_library_name},
63 create_client_platform{platform_library.load_function<mcl::CreateClientPlatform>("create_client_platform")},
64 probe{platform_library.load_function<mcl::ClientPlatformProbe>("is_appropriate_module")}
65 {
66 using namespace testing;
67 ON_CALL(context, populate(_))
68 .WillByDefault(Invoke(GetParam()->populate_package_for));
69 }
70
39 mtd::MockClientContext context;71 mtd::MockClientContext context;
40#ifdef ANDROID72#ifdef MIR_BUILD_PLATFORM_ANDROID
41 testing::NiceMock<mtd::HardwareAccessMock> hw_access_mock;73 testing::NiceMock<mtd::HardwareAccessMock> hw_access_mock;
42 mcl::android::ClientPlatformFactory factory;
43#else
44 mcl::mesa::ClientPlatformFactory factory;
45#endif74#endif
75 mir::SharedLibrary platform_library;
76 mcl::CreateClientPlatform const create_client_platform;
77 mcl::ClientPlatformProbe const probe;
46};78};
4779
48TEST_F(ClientPlatformTest, platform_name)80#ifdef MIR_BUILD_PLATFORM_ANDROID
49{81ClientPlatformTraits const android_platform{"/client-modules/android.so",
50 auto platform = factory.create_client_platform(&context);82 [](MirPlatformPackage& pkg)
51#ifdef ANDROID83 {
52 auto type = mir_platform_type_android;84 ::memset(&pkg, 0, sizeof(pkg));
53#else85 },
54 auto type = mir_platform_type_gbm;86 mir_platform_type_android
55#endif87 };
56 EXPECT_EQ(type, platform->platform_type());88
57}89INSTANTIATE_TEST_CASE_P(Android,
5890 ClientPlatformTest,
59TEST_F(ClientPlatformTest, platform_creates)91 ::testing::Values(&android_platform));
60{92
61 auto platform = factory.create_client_platform(&context);93#endif
94
95#ifdef MIR_BUILD_PLATFORM_MESA
96ClientPlatformTraits const mesa_platform{"/client-modules/mesa.so",
97 [](MirPlatformPackage& pkg)
98 {
99 ::memset(&pkg, 0, sizeof(pkg));
100 pkg.fd_items = 1;
101 },
102 mir_platform_type_gbm
103 };
104
105INSTANTIATE_TEST_CASE_P(Mesa,
106 ClientPlatformTest,
107 ::testing::Values(&mesa_platform));
108
109#endif
110
111ClientPlatformTraits const dummy_platform{"/client-modules/dummy.so",
112 [](MirPlatformPackage& pkg)
113 {
114 mtf::create_stub_platform_package(pkg);
115 },
116 mir_platform_type_gbm
117 };
118
119INSTANTIATE_TEST_CASE_P(Dummy,
120 ClientPlatformTest,
121 ::testing::Values(&dummy_platform));
122}
123
124TEST_P(ClientPlatformTest, platform_name)
125{
126 auto platform = create_client_platform(&context);
127
128 EXPECT_EQ(GetParam()->platform_type, platform->platform_type());
129}
130
131TEST_P(ClientPlatformTest, platform_creates)
132{
133 auto platform = create_client_platform(&context);
62 auto buffer_factory = platform->create_buffer_factory();134 auto buffer_factory = platform->create_buffer_factory();
63 EXPECT_NE(buffer_factory.get(), (mcl::ClientBufferFactory*) NULL);135 EXPECT_NE(buffer_factory.get(), (mcl::ClientBufferFactory*) NULL);
64}136}
65137
66TEST_F(ClientPlatformTest, platform_creates_native_window)138TEST_P(ClientPlatformTest, platform_creates_native_window)
67{139{
68 auto platform = factory.create_client_platform(&context);140 auto platform = create_client_platform(&context);
69 auto mock_client_surface = std::make_shared<mtd::MockClientSurface>();141 auto mock_client_surface = std::make_shared<mtd::MockClientSurface>();
70 auto native_window = platform->create_egl_native_window(mock_client_surface.get());142 auto native_window = platform->create_egl_native_window(mock_client_surface.get());
71 EXPECT_NE(*native_window, (EGLNativeWindowType) NULL);143 EXPECT_NE(*native_window, (EGLNativeWindowType) NULL);
72}144}
73145
74TEST_F(ClientPlatformTest, platform_creates_egl_native_display)146TEST_P(ClientPlatformTest, platform_creates_egl_native_display)
75{147{
76 auto platform = factory.create_client_platform(&context);148 auto platform = create_client_platform(&context);
77 auto native_display = platform->create_egl_native_display();149 auto native_display = platform->create_egl_native_display();
78 EXPECT_NE(nullptr, native_display.get());150 EXPECT_NE(nullptr, native_display.get());
79}151}
152
153TEST_P(ClientPlatformTest, platform_probe_returns_success_when_matching)
154{
155 EXPECT_TRUE(probe(&context));
156}
157
158TEST_P(ClientPlatformTest, platform_probe_returns_false_when_not_matching)
159{
160 using namespace testing;
161 ON_CALL(context, populate(_))
162 .WillByDefault(Invoke([](MirPlatformPackage& pkg)
163 {
164 //Mock up something that hopefully looks nothing like
165 //what the platform is expecting...
166 ::memset(&pkg, 0, sizeof(pkg));
167 pkg.data_items = mir_platform_package_max + 1;
168 pkg.fd_items = -23;
169 }));
170
171 EXPECT_FALSE(probe(&context));
172}
80173
=== added file 'tests/unit-tests/client/test_probing_client_platform_factory.cpp'
--- tests/unit-tests/client/test_probing_client_platform_factory.cpp 1970-01-01 00:00:00 +0000
+++ tests/unit-tests/client/test_probing_client_platform_factory.cpp 2014-12-12 01:38:38 +0000
@@ -0,0 +1,142 @@
1/*
2 * Copyright © 2014 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Christopher James Halse Rogers <christopher.halse.rogers@canonical.com>
17 */
18
19#include "src/client/client_platform.h"
20#include "src/client/probing_client_platform_factory.h"
21
22#include "mir_test_doubles/mock_client_context.h"
23#include "mir_test_framework/executable_path.h"
24#include "mir_test_framework/stub_platform_helpers.h"
25
26#include <gmock/gmock.h>
27#include <gtest/gtest.h>
28
29namespace mtf = mir_test_framework;
30namespace mtd = mir::test::doubles;
31
32namespace
33{
34std::vector<std::shared_ptr<mir::SharedLibrary>>
35all_available_modules()
36{
37 std::vector<std::shared_ptr<mir::SharedLibrary>> modules;
38#ifdef MIR_BUILD_PLATFORM_MESA
39 modules.push_back(std::make_shared<mir::SharedLibrary>(mtf::library_path() + "/client-modules/mesa.so"));
40#endif
41#ifdef MIR_BUILD_PLATFORM_ANDROID
42 modules.push_back(std::make_shared<mir::SharedLibrary>(mtf::library_path() + "/client-modules/android.so"));
43#endif
44 return modules;
45}
46}
47
48TEST(ProbingClientPlatformFactory, ThrowsErrorWhenConstructedWithNoPlatforms)
49{
50 std::vector<std::shared_ptr<mir::SharedLibrary>> empty_modules;
51 EXPECT_THROW(mir::client::ProbingClientPlatformFactory{empty_modules},
52 std::runtime_error);
53}
54
55TEST(ProbingClientPlatformFactory, ThrowsErrorWhenNoPlatformPluginProbesSuccessfully)
56{
57 using namespace testing;
58
59 mir::client::ProbingClientPlatformFactory factory{all_available_modules()};
60
61 mtd::MockClientContext context;
62 ON_CALL(context, populate(_))
63 .WillByDefault(Invoke([](MirPlatformPackage& pkg)
64 {
65 ::memset(&pkg, 0, sizeof(MirPlatformPackage));
66 // Mock up a platform package that looks nothing like
67 // either an Android or Mesa package
68 pkg.fd_items = 0xdeadbeef;
69 pkg.data_items = -23;
70 }));
71
72 EXPECT_THROW(factory.create_client_platform(&context),
73 std::runtime_error);
74}
75
76#ifdef MIR_BUILD_PLATFORM_MESA
77TEST(ProbingClientPlatformFactory, CreatesMesaPlatformWhenAppropriate)
78#else
79TEST(ProbingClientPlatformFactory, DISABLED_CreatesMesaPlatformWhenAppropriate)
80#endif
81{
82 using namespace testing;
83
84 mir::client::ProbingClientPlatformFactory factory{all_available_modules()};
85
86 mtd::MockClientContext context;
87 ON_CALL(context, populate(_))
88 .WillByDefault(Invoke([](MirPlatformPackage& pkg)
89 {
90 ::memset(&pkg, 0, sizeof(MirPlatformPackage));
91 // Mock up something that looks like a GBM platform package,
92 // until we send the actual platform type over the wire!
93 pkg.fd_items = 1;
94 pkg.fd[0] = 23;
95 }));
96 auto platform = factory.create_client_platform(&context);
97 EXPECT_EQ(mir_platform_type_gbm, platform->platform_type());
98}
99
100#ifdef MIR_BUILD_PLATFORM_ANDROID
101TEST(ProbingClientPlatformFactory, CreatesAndroidPlatformWhenAppropriate)
102#else
103TEST(ProbingClientPlatformFactory, DISABLED_CreatesAndroidPlatformWhenAppropriate)
104#endif
105{
106 using namespace testing;
107
108 mir::client::ProbingClientPlatformFactory factory{all_available_modules()};
109
110 mtd::MockClientContext context;
111 ON_CALL(context, populate(_))
112 .WillByDefault(Invoke([](MirPlatformPackage& pkg)
113 {
114 // Mock up something that looks like a Android platform package,
115 // until we send the actual platform type over the wire!
116 ::memset(&pkg, 0, sizeof(MirPlatformPackage));
117 }));
118
119 auto platform = factory.create_client_platform(&context);
120 EXPECT_EQ(mir_platform_type_android, platform->platform_type());
121}
122
123TEST(ProbingClientPlatformFactory, IgnoresNonClientPlatformModules)
124{
125 using namespace testing;
126
127 auto modules = all_available_modules();
128 // NOTE: For minimum fuss, load something that has minimal side-effects...
129 modules.push_back(std::make_shared<mir::SharedLibrary>("libc.so.6"));
130 modules.push_back(std::make_shared<mir::SharedLibrary>(mtf::library_path() + "/client-modules/dummy.so"));
131
132 mir::client::ProbingClientPlatformFactory factory{modules};
133
134 mtd::MockClientContext context;
135 ON_CALL(context, populate(_))
136 .WillByDefault(Invoke([](MirPlatformPackage& pkg)
137 {
138 mtf::create_stub_platform_package(pkg);
139 }));
140
141 auto platform = factory.create_client_platform(&context);
142}
0143
=== modified file 'tests/unit-tests/shared_library_test.cpp'
--- tests/unit-tests/shared_library_test.cpp 2014-12-08 04:03:47 +0000
+++ tests/unit-tests/shared_library_test.cpp 2014-12-12 01:38:38 +0000
@@ -59,10 +59,10 @@
59public:59public:
60 SharedLibrary()60 SharedLibrary()
61 : nonexistent_library{"imma_totally_not_a_library"},61 : nonexistent_library{"imma_totally_not_a_library"},
62 existing_library{mtf::library_path() + "/" MIR_CLIENT_DRIVER_BINARY},62 existing_library{mtf::library_path() + "/client-modules/mesa.so"},
63 nonexistent_function{"yo_dawg"},63 nonexistent_function{"yo_dawg"},
64 existing_function{"create_client_platform_factory"},64 existing_function{"create_client_platform"},
65 existent_version{"MIR_CLIENTPLATFORM_1"},65 existent_version{"MIR_CLIENT_PLATFORM_2"},
66 nonexistent_version{"GOATS_ON_THE_GREEN"}66 nonexistent_version{"GOATS_ON_THE_GREEN"}
67 {67 {
68 }68 }

Subscribers

People subscribed via source and target branches