Mir

Merge lp:~nick-dedekind/mir/trusted_sessions into lp:mir

Proposed by Nick Dedekind
Status: Superseded
Proposed branch: lp:~nick-dedekind/mir/trusted_sessions
Merge into: lp:mir
Diff against target: 4768 lines (+3439/-57) (has conflicts)
81 files modified
examples/CMakeLists.txt (+6/-2)
examples/demo-inprocess-surface-client/inprocess_egl_client.cpp (+1/-1)
examples/trust_session.c (+249/-0)
include/client/mir_toolkit/mir_trust_session.h (+119/-0)
include/server/mir/default_server_configuration.h (+3/-0)
include/server/mir/frontend/connection_context.h (+58/-0)
include/server/mir/frontend/event_sink.h (+2/-0)
include/server/mir/frontend/session.h (+1/-0)
include/server/mir/frontend/session_mediator_report.h (+6/-0)
include/server/mir/frontend/shell.h (+9/-0)
include/server/mir/frontend/trust_session.h (+53/-0)
include/server/mir/scene/null_trust_session_listener.h (+50/-0)
include/server/mir/scene/session.h (+3/-1)
include/server/mir/scene/trust_session.h (+43/-0)
include/server/mir/scene/trust_session_creation_parameters.h (+46/-0)
include/server/mir/scene/trust_session_listener.h (+52/-0)
include/shared/mir_toolkit/client_types.h (+40/-0)
include/shared/mir_toolkit/common.h (+17/-0)
include/shared/mir_toolkit/event.h (+10/-1)
include/test/mir_test/test_protobuf_client.h (+18/-0)
include/test/mir_test_doubles/mock_scene_session.h (+3/-0)
include/test/mir_test_doubles/mock_shell.h (+9/-0)
include/test/mir_test_doubles/mock_trust_session_listener.h (+48/-0)
include/test/mir_test_doubles/null_trust_session.h (+70/-0)
include/test/mir_test_doubles/stub_scene_session.h (+8/-0)
include/test/mir_test_doubles/stub_session.h (+4/-0)
include/test/mir_test_doubles/stub_shell.h (+15/-0)
src/client/CMakeLists.txt (+4/-1)
src/client/connection_configuration.h (+2/-0)
src/client/default_connection_configuration.cpp (+11/-1)
src/client/default_connection_configuration.h (+2/-0)
src/client/event_distributor.cpp (+57/-0)
src/client/event_distributor.h (+52/-0)
src/client/mir_connection.cpp (+9/-2)
src/client/mir_connection.h (+5/-0)
src/client/mir_trust_session.cpp (+182/-0)
src/client/mir_trust_session.h (+88/-0)
src/client/mir_trust_session_api.cpp (+133/-0)
src/client/rpc/make_rpc_channel.h (+3/-1)
src/client/rpc/make_socket_rpc_channel.cpp (+4/-3)
src/client/rpc/mir_socket_rpc_channel.cpp (+26/-7)
src/client/rpc/mir_socket_rpc_channel.h (+6/-2)
src/server/default_server_configuration.cpp (+11/-0)
src/server/frontend/protobuf_message_processor.cpp (+23/-4)
src/server/frontend/session_mediator.cpp (+133/-0)
src/server/frontend/session_mediator.h (+29/-3)
src/server/report/logging/session_mediator_report.cpp (+15/-0)
src/server/report/logging/session_mediator_report.h (+6/-0)
src/server/report/lttng/session_mediator_report.cpp (+11/-0)
src/server/report/lttng/session_mediator_report.h (+3/-0)
src/server/report/lttng/session_mediator_report_tp.h (+21/-0)
src/server/report/null/session_mediator_report.cpp (+12/-0)
src/server/report/null/session_mediator_report.h (+6/-0)
src/server/scene/CMakeLists.txt (+3/-0)
src/server/scene/application_session.cpp (+21/-0)
src/server/scene/application_session.h (+3/-0)
src/server/scene/default_configuration.cpp (+3/-2)
src/server/scene/session_manager.cpp (+125/-3)
src/server/scene/session_manager.h (+20/-1)
src/server/scene/trust_session_container.cpp (+95/-0)
src/server/scene/trust_session_container.h (+103/-0)
src/server/scene/trust_session_creation_parameters.cpp (+51/-0)
src/server/scene/trust_session_impl.cpp (+187/-0)
src/server/scene/trust_session_impl.h (+74/-0)
src/shared/protobuf/mir_protobuf.proto (+54/-14)
tests/acceptance-tests/CMakeLists.txt (+1/-0)
tests/acceptance-tests/test_client_trust_session_api.cpp (+106/-0)
tests/acceptance-tests/test_nested_mir.cpp (+3/-0)
tests/acceptance-tests/test_server_shutdown.cpp (+43/-0)
tests/integration-tests/frontend/test_application_mediator_report.cpp (+181/-0)
tests/integration-tests/test_session_manager.cpp (+3/-1)
tests/mir_test_doubles/test_protobuf_client.cpp (+27/-1)
tests/unit-tests/client/CMakeLists.txt (+1/-0)
tests/unit-tests/client/test_mir_trust_session.cpp (+244/-0)
tests/unit-tests/frontend/stress_protobuf_communicator.cpp (+3/-1)
tests/unit-tests/frontend/test_session_mediator.cpp (+52/-0)
tests/unit-tests/graphics/mesa/test_drm_helper.cpp.moved (+65/-0)
tests/unit-tests/scene/CMakeLists.txt (+1/-0)
tests/unit-tests/scene/test_application_session.cpp (+45/-0)
tests/unit-tests/scene/test_session_manager.cpp (+55/-5)
tests/unit-tests/scene/test_trust_session.cpp (+73/-0)
Text conflict in include/server/mir/frontend/connection_context.h
Text conflict in include/shared/mir_toolkit/client_types.h
Text conflict in src/server/frontend/protobuf_message_processor.cpp
Text conflict in src/server/frontend/session_mediator.cpp
Text conflict in src/server/frontend/session_mediator.h
Text conflict in src/shared/protobuf/mir_protobuf.proto
Text conflict in tests/acceptance-tests/test_server_shutdown.cpp
Text conflict in tests/unit-tests/frontend/test_session_mediator.cpp
To merge this branch: bzr merge lp:~nick-dedekind/mir/trusted_sessions
Reviewer Review Type Date Requested Status
Alan Griffiths Needs Fixing
Daniel van Vugt Needs Fixing
PS Jenkins bot (community) continuous-integration Approve
Alexandros Frantzis (community) Needs Fixing
Andreas Pokorny (community) Needs Fixing
Review via email: mp+209224@code.launchpad.net

This proposal has been superseded by a proposal from 2014-05-09.

Commit message

This adds/implements the API required for client & server to manage "trust sessions".

A mir client is now able to create a relationship between one or more process sessions and itself. This will manifest in the server as the trusted helper (the client using the api) being set as the parent of the trusted sessions. The shell is responsible for determining what this relationship "means", visually.

Description of the change

This adds/implements the API required for client & server to manage "trust sessions".

To post a comment you must log in.
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

There's a lot of this to digest - and I don't know what feature(s) it is supposed to support.

Accordingly, I get bogged down in details like:

@SessionId - why is this useful (compared to, say, std::[shared|weak]_ptr<Session>)

@TrustedSessionCreationParameters - this has one public mutable member (which initializes itself). Why does it need a constructor? (And does it really belong in the shell namespace?)

61 + * Copyright © 2012 Canonical Ltd.

Wrong year.

@examples/trusted_session_trusted_session.c

This is written using the original (async) APIs it would probably be clearer using the (slightly) more recent sync ones. (I suspect cut & paste from an example that should have been updated last year.)

review: Needs Information
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 :

Wow, so much code. This will take a while...

(1) One quick note:
1196 +MirTrustedSession* mir_trusted_session_create(MirConnection* connection)
The pattern we use is "NAMESPACE_OBJECT_ACTION", so that should be:
    MirTrustedSession* mir_connection_create_trusted_session(MirConnection* connection)
Although since "session" was never an object in the client API before, the word "trusted" is superfluous and could be removed. Even if only from the public client API.

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

(2) Quick requirements/analysis sanity check: Can you explain why this feature needs to be in Mir itself?

Revision history for this message
Nick Dedekind (nick-dedekind) wrote :

> Wow, so much code. This will take a while...
>
> (1) One quick note:
> 1196 +MirTrustedSession* mir_trusted_session_create(MirConnection*
> connection)
> The pattern we use is "NAMESPACE_OBJECT_ACTION", so that should be:
> MirTrustedSession* mir_connection_create_trusted_session(MirConnection*
> connection)
> Although since "session" was never an object in the client API before, the
> word "trusted" is superfluous and could be removed. Even if only from the
> public client API.

It doesn't mean the same thing without "trusted". The TrustedSession is "the object" we are creating. A "trusted session" describes the trust relationship between mir [server] sessions. https://wiki.ubuntu.com/Security/TrustStoreAndSessions

Revision history for this message
Nick Dedekind (nick-dedekind) wrote :

> (2) Quick requirements/analysis sanity check: Can you explain why this feature
> needs to be in Mir itself?

The trust session needs to be created by a mir client, and interpreted by the shell (in our case, the mirserver api shell layer - unity-mir).
Since it describes the relationship between sessions, it seems like the logical place. Without mir we would need to create a new framework for the client to communicate this with the shell.

tvoss may have a more speicific answer for you.

Revision history for this message
Nick Dedekind (nick-dedekind) wrote :

> > Wow, so much code. This will take a while...
> >
> > (1) One quick note:
> > 1196 +MirTrustedSession* mir_trusted_session_create(MirConnection*
> > connection)
> > The pattern we use is "NAMESPACE_OBJECT_ACTION", so that should be:
> > MirTrustedSession* mir_connection_create_trusted_session(MirConnection*
> > connection)
> > Although since "session" was never an object in the client API before, the
> > word "trusted" is superfluous and could be removed. Even if only from the
> > public client API.
>
> It doesn't mean the same thing without "trusted". The TrustedSession is "the
> object" we are creating. A "trusted session" describes the trust relationship
> between mir [server] sessions.
> https://wiki.ubuntu.com/Security/TrustStoreAndSessions

In retrospect, it's actually a "trust session". I'll change that.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

FAILED: Continuous integration, rev:1400
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https://code.launchpad.net/~nick-dedekind/mir/trusted_sessions/+merge/209224/+edit-commit-message

http://jenkins.qa.ubuntu.com/job/mir-team-mir-development-branch-ci/1002/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-android-trusty-i386-build/1150
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-clang-trusty-amd64-build/1148
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-trusty-touch/732
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-team-mir-development-branch-trusty-amd64-ci/734
        deb: http://jenkins.qa.ubuntu.com/job/mir-team-mir-development-branch-trusty-amd64-ci/734/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-team-mir-development-branch-trusty-armhf-ci/739
        deb: http://jenkins.qa.ubuntu.com/job/mir-team-mir-development-branch-trusty-armhf-ci/739/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-trusty-armhf/733
        deb: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-trusty-armhf/733/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-runner-mako/694
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/4531

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/mir-team-mir-development-branch-ci/1002/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Nick Dedekind (nick-dedekind) wrote :

> There's a lot of this to digest - and I don't know what feature(s) it is
> supposed to support.

Thanks for the review.
This adds/implements the API required for client & server to manage "trust sessions" (as the name suggests).
The easiest way to get an overview of what this code "does" is by looking at the diagram:
https://docs.google.com/a/canonical.com/drawings/d/1Sx3Q6IugYY0DjrQfN3em6PBhyeNotXtYAa4UioVdT8c/edit

>
> Accordingly, I get bogged down in details like:
>
> @SessionId - why is this useful (compared to, say,
> std::[shared|weak]_ptr<Session>)

:/ This was a bit of a mixed implementation. The client side supports multiple trust sessions per connection, while the server does not. So [at least for now] I've removed support for multiple trust sessions (start refused). So removed the SessionId in favour of std::shared_ptr<TrustSession>

>
> @TrustedSessionCreationParameters - this has one public mutable member (which
> initializes itself). Why does it need a constructor? (And does it really
> belong in the shell namespace?)
>
> 61 + * Copyright © 2012 Canonical Ltd.
>
> Wrong year.
>
> @examples/trusted_session_trusted_session.c
>
> This is written using the original (async) APIs it would probably be clearer
> using the (slightly) more recent sync ones. (I suspect cut & paste from an
> example that should have been updated last year.)

Refactored example & added sync methods to trust session API.

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

First run on the public client side API

+ 399 wrong comment
+ 408 Really Lifecycle, not just "state"?
+ 443 wrong comment

In general - do we need to the start and stop states? Isnt create/destroy enough?

+ 399ff this means all sessions of the same process pid are trusted? Couldnt that be: mir_trust_session_trust_process(session, pid);

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

This isn't a full review, but some minor fixes to do in the mean time...

(1) Please follow the existing convention, which would mean:
396 +MirTrustSession* mir_trust_session_create(MirConnection* connection);
becomes:
MirTrustSession* mir_connection_create_trust_session(MirConnection* connection);

(2) Please put the details/justification you mentioned in the commit message or proposal description. A four word description for a 3713 line proposal is a bit brief...

review: Needs Fixing
Revision history for this message
Nick Dedekind (nick-dedekind) wrote :

> First run on the public client side API
>
> + 399 wrong comment
> + 408 Really Lifecycle, not just "state"?
> + 443 wrong comment

Fixed.

>
> In general - do we need to the start and stop states? Isnt create/destroy
> enough?
>
> + 399ff this means all sessions of the same process pid are trusted? Couldnt
> that be: mir_trust_session_trust_process(session, pid);

The trust sessions doesn't exist on the server until we call start. The trust session is set up (add pids), after which we call mir_trust_session_start (which creates the server side impl). And the server can manually stop the trust session as well, so that's why we need the state callback.

renamed to mir_trust_session_add_trusted_pid

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

Overall, very nice. The size of the proposal however means the little issues are adding up to quite a list...

(1) 397 +MirTrustSession* mir_connection_trust_session_create(MirConnection* connection);
should be renamed to follow the existing convention:
MirTrustSession* mir_connection_create_trust_session(MirConnection* connection);

(2) Please expand on the commit message/description further. It's still too brief for a large enhancement.

(3) Please remove "handle_trust_session_event()". EventSink is only meant to have one method "handle_event" which handles any and all event types. The other methods of EventSink are mistakes we need to revert already. Sorry it's misleading.

(4) ABI bumps: The server ABI seems to have changed, but the client ABI is not broken by this proposal. Please revent the MIR_CLIENT_ABI bump.

(5) trust_session.c: The program prints messages referring to itself as "demo_client_trusted_helper" and "demo_client_app2". However the binary name is "mir_demo_client_trust_session". Maybe it should be printing that or just argv[0] to avoid confusion.

(6) trust_session.c: Forks into two processes, which is unusual for a client. Is that the expected/normal use case?

(7) read(STDIN_FILENO, &buff, 1) - Why not getchar()? It's simpler more portable too.

(8) Long lines - I prefer code wrapped before column 80 and so do plenty of people. Not just because that's what a terminal defaults to, but it's easier for the brain to follow line continuation when you avoid them getting too long.

(9) frontend/trust_session.h: Is std::vector necessary to maintain an ordered list? If not then the more appropriate container is std::unordered_set

(10) frontend/trust_session.h: a stop() method but no start() method? Is that a good idea? Is the start implicit in construction?

(11) MirTrustSessionAddTrustResult: The enum values are arguably too long. IMHO.

(12) Identical descriptions for different function types?
784 + * Callback member of MirTrustSession for handling of trust sessions.
791 + * Callback member of MirTrustSession for handling of trust sessions.

(13) We should avoid landing new code with known race conditions:
1618 + /* todo: race condition. protobuf does not guarantee that callbacks will be synchronized. potential
1619 + race in session, last_buffer_id */

(14) Superficially it's confusing as to why these with equivalent names should be separate classes:
1592 +struct MirTrustSession : public mir::client::TrustSession
But now I notice how simple mir::client::TrustSession is, they're clearly quite different things. So the class names should clarify the differences between them.

(15) What's a "Control"?
1885 +class TrustSessionControl
I'm not familiar with that abstraction. Even though there seems to be another "Control" class there already :S

(16) test_protobuf_client.cpp: A busy wait loop seems like a lazy approach to this (albeit a lazy approach we've already used in other tests). It would be cleaner to use a std::condition_variable with a std::mutex and bool. That would also avoid the expected Helgrind complaints about std::atomic being racy.

(17) test_trust_session.cpp: Wrong copyright year range.

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

A first pass...

Since mir_client_library.cpp has started to become unwieldly I propose we follow the convention mir_screencast is using, i.e.:

1. Public header file goes in mir_toolkit/mir_trust_session.h
2. C API implementation goes in src/client/mir_trust_session_api.cpp
3. Internal classes as usual, src/client/mir_trust_session.{cpp,h}

148 +///\page trust_session.c trust_session.c: A mir client which starts a trust session and trusted client app.
149 +/// mir_demo_client_trust_session shows the use of mir trust session API.
150 +/// This program opens a mir connection and creates a trust session.
...

519 + virtual std::shared_ptr<TrustSession> start_trust_session_for(std::string& error,
520 + std::shared_ptr<Session> const& session,

Since this is a C file, the C(/Javadoc) format is preferred, like in the public files.

519 + virtual std::shared_ptr<TrustSession> start_trust_session_for(std::string& error,
520 + std::shared_ptr<Session> const& session,
...

Either use a 4-space indentation or align with char after '('.

567 + virtual ~TrustSession() {}
1129 + TrustSession() {}
1130 + virtual ~TrustSession() {}

Use '= default' instead;

744 +#include <string>

Not needed.

1239 +/**************************
1240 + * Trust session specific functions *
1241 + **************************/

This can be made prettier :)

1249 + pid_t pid)

1255 + mir_trust_session_callback callback,
1256 + void* context)

1272 + reinterpret_cast<mir_trust_session_callback>
1273 + (assign_result),
1274 + NULL));

1279 + mir_trust_session_callback callback,
1280 + void* context)

1296 + reinterpret_cast<mir_trust_session_callback>
1297 + (assign_result),
1298 + NULL));

1308 + mir_trust_session_event_callback callback,
1309 + void* context)

Either use a 4-space indentation or align with char after '(' on previous line.

1427 + [this]
1428 + (MirTrustSessionState new_state)

1501 + [this, callback, context]
1502 + (MirTrustSessionState state)

2771 + [this]
2772 + (std::shared_ptr<msh::Session> const& child_session)

We tend to prefer to keep the parameter list on the same line as the capture list:
[this] (MirTrustSessionState new_state), but that's not a hard and fast rule AFAIK.

1430 + std::lock_guard<std::recursive_mutex> lock(mutex);

Why do we need a recursive mutex?

1595 + MirTrustSession(mir::protobuf::DisplayServer::Stub & server,
1600 + MirTrustSession(MirTrustSession const &) = delete;
1601 + MirTrustSession& operator=(MirTrustSession const &) = delete;
... and others in the class

* and & go with the type (or 'const' if there is one).

1820 + std::unique_lock<std::mutex> lk(guard);

Since the lock is not used with condition variables or moved, we could use the simpler std::lock_guard<>.

1814 +mcl::TrustSessionControl::~TrustSessionControl()
1815 +{
1816 +}

Is this needed?

2737 + TrustSession* impl = new TrustSession(trusted_helper, parameters, sink);
2738 + std::shared_ptr<msh::TrustSession> ptr(impl);

auto const trust_session = std::make_shared<TrustSession>(trusted_helper, parameters, sink);

review: Needs Fixing
Revision history for this message
Nick Dedekind (nick-dedekind) wrote :
Download full text (4.8 KiB)

> Overall, very nice. The size of the proposal however means the little issues
> are adding up to quite a list...
>
> (1) 397 +MirTrustSession* mir_connection_trust_session_create(MirConnection*
> connection);
> should be renamed to follow the existing convention:
> MirTrustSession* mir_connection_create_trust_session(MirConnection*
> connection);

My bad again. Done

>
> (2) Please expand on the commit message/description further. It's still too
> brief for a large enhancement.

Done

>
> (3) Please remove "handle_trust_session_event()". EventSink is only meant to
> have one method "handle_event" which handles any and all event types. The
> other methods of EventSink are mistakes we need to revert already. Sorry it's
> misleading.

Hmm. bit of an interesting one about this one. The only consumer for MirEvents are the surfaces.
Which means we'll need another consumer to push the events to clients without a surface.
I've removed the TrustSessionControl class, and added a mcl::EventDistributor class to the client library which does this.

>
> (4) ABI bumps: The server ABI seems to have changed, but the client ABI is not
> broken by this proposal. Please revent the MIR_CLIENT_ABI bump.

Done

>
> (5) trust_session.c: The program prints messages referring to itself as
> "demo_client_trusted_helper" and "demo_client_app2". However the binary name
> is "mir_demo_client_trust_session". Maybe it should be printing that or just
> argv[0] to avoid confusion.

Made references/stdout of each process more explicit.

>
> (6) trust_session.c: Forks into two processes, which is unusual for a client.
> Is that the expected/normal use case?

We need 2 processes for a trust session, the "trusted helper", and the "trusted app".
It would probably be more normal for the trusted helper to start an external process, but I it
better to enclose all behaviour in the single example.

>
> (7) read(STDIN_FILENO, &buff, 1) - Why not getchar()? It's simpler more
> portable too.

Done

>
> (8) Long lines - I prefer code wrapped before column 80 and so do plenty of
> people. Not just because that's what a terminal defaults to, but it's easier
> for the brain to follow line continuation when you avoid them getting too
> long.
>
> (9) frontend/trust_session.h: Is std::vector necessary to maintain an ordered
> list? If not then the more appropriate container is std::unordered_set

Needs to be ordered for the shell. (last session is on top)

>
> (10) frontend/trust_session.h: a stop() method but no start() method? Is that
> a good idea? Is the start implicit in construction?

It's not ideal, but there is a static start_for function on the src/server/scene/trust_session.cpp
Which essentially is implicit start on creation. Can't do what we need from a member start.

>
> (11) MirTrustSessionAddTrustResult: The enum values are arguably too long.
> IMHO.

Now shorter (kind of). Though there are some pretty long ones about still.

>
> (12) Identical descriptions for different function types?
> 784 + * Callback member of MirTrustSession for handling of trust sessions.
> 791 + * Callback member of MirTrustSession for handling of trust sessions.
>

Fixed.

> (13) We ...

Read more...

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Nick Dedekind (nick-dedekind) wrote :
Download full text (3.6 KiB)

> A first pass...
>
> Since mir_client_library.cpp has started to become unwieldly I propose we
> follow the convention mir_screencast is using, i.e.:
>
> 1. Public header file goes in mir_toolkit/mir_trust_session.h
> 2. C API implementation goes in src/client/mir_trust_session_api.cpp
> 3. Internal classes as usual, src/client/mir_trust_session.{cpp,h}

Done

>
> 148 +///\page trust_session.c trust_session.c: A mir client which starts a
> trust session and trusted client app.
> 149 +/// mir_demo_client_trust_session shows the use of mir trust session
> API.
> 150 +/// This program opens a mir connection and creates a trust session.
> ...
>
> 519 + virtual std::shared_ptr<TrustSession>
> start_trust_session_for(std::string& error,
> 520 + std::shared_ptr<Session> const& session,
>
> Since this is a C file, the C(/Javadoc) format is preferred, like in the
> public files.
>

This is using the same format as the other examples.

>
> 519 + virtual std::shared_ptr<TrustSession>
> start_trust_session_for(std::string& error,
> 520 + std::shared_ptr<Session> const& session,
> ...
>
> Either use a 4-space indentation or align with char after '('.

Done

>
> 567 + virtual ~TrustSession() {}
> 1129 + TrustSession() {}
> 1130 + virtual ~TrustSession() {}
>
> Use '= default' instead;

Done

>
> 744 +#include <string>
>
> Not needed.

Done

>
> 1239 +/**************************
> 1240 + * Trust session specific functions *
> 1241 + **************************/
>
> This can be made prettier :)

Removed with separation of client api source files

>
> 1249 + pid_t pid)
>
> 1255 + mir_trust_session_callback callback,
> 1256 + void* context)
>
> 1272 + reinterpret_cast<mir_trust_session_callback>
> 1273 + (assign_result),
> 1274 + NULL));
>
> 1279 + mir_trust_session_callback callback,
> 1280 + void* context)
>
> 1296 + reinterpret_cast<mir_trust_session_callback>
> 1297 + (assign_result),
> 1298 + NULL));
>
> 1308 + mir_trust_session_event_callback callback,
> 1309 + void* context)
>
> Either use a 4-space indentation or align with char after '(' on previous
> line.
>
> 1427 + [this]
> 1428 + (MirTrustSessionState new_state)
>
> 1501 + [this, callback, context]
> 1502 + (MirTrustSessionState state)
>
> 2771 + [this]
> 2772 + (std::shared_ptr<msh::Session> const& child_session)
>
> We tend to prefer to keep the parameter list on the same line as the capture
> list:
> [this] (MirTrustSessionState new_state), but that's not a hard and fast rule
> AFAIK.

Must have picked it up on some other project. Switched to single line

>
> 1430 + std::lock_guard<std::recursive_mutex> lock(mutex);
>
> Why do we need a recursive mutex?

Changed already

>
> 1595 + MirTrustSession(mir::protobuf::DisplayServer::Stub & server,
> 1600 + MirTrustSession(MirTrustSession const &) = delete;
> 1601 + MirTrustSession& operator=(MirTrustSession const &) = delete;
> ... and others in the class
>
> * and & go with the type (or 'const' if there is one).

Done

>
> 1820 + std::unique_lock<std::mutex> lk(guard);
>
> Since the lock is not used with condition...

Read more...

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
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

2919 + * Copyright © 2013 Canonical Ltd.

Surely 2014 deserves a mention?

~~~~

534 === renamed file 'src/server/scene/session_container.h' => 'include/server/mir/scene/session_container.h'

Why is this interface being made public? It is internal to the Mir scene implementation and should be access via SessionManager (which has public interfaces frontend::Shell and shell::FocusController)

Oh, I see: it has an entirely new use with shell::Session::get_children(). That opens a whole new debate about procedural vs OO design:

In this instance, for example, in TrustSession::stop() we should be telling the trusted_helper that the session has stopped, not asking for this collection and manipulating it.

This isn't the only part of the design that makes use of manipulating state directly instead of tell what is going on. A quick search for [sg]et_ turns up more.

~~~~

There's a misuse of smart pointers - shared_ptr is about "ownership" and this needs to be a directed *acyclic* graph to correctly manage memory. Having the parent and child both "own" each other is wrong. At least one of these smart pointers should be a raw pointer.

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

> There's a misuse of smart pointers - shared_ptr is about "ownership" and this
> needs to be a directed *acyclic* graph to correctly manage memory. Having the
> parent and child both "own" each other is wrong. At least one of these smart
> pointers should be a raw pointer.

I've not checked the required semantics, but another solution that might be evaluated is to use weak_ptr.

Revision history for this message
Alberto Mardegan (mardy) wrote :

I had a quick look at the proposed API; please consider adding an API to add an application by app-id, so that we can add applications which have not been started yet.
More about that here:

https://lists.launchpad.net/ubuntu-phone/msg06680.html

(I myself would have preferred a different approach, where an app could add itself to an existing session)

Revision history for this message
Nick Dedekind (nick-dedekind) wrote :

> > There's a misuse of smart pointers - shared_ptr is about "ownership" and
> this
> > needs to be a directed *acyclic* graph to correctly manage memory. Having
> the
> > parent and child both "own" each other is wrong. At least one of these smart
> > pointers should be a raw pointer.
>
> I've not checked the required semantics, but another solution that might be
> evaluated is to use weak_ptr.

Would have liked to use weak_ptr, but it wouldn't work for setting child parents from within Session::begin_trust_session.

Revision history for this message
Nick Dedekind (nick-dedekind) wrote :

> I had a quick look at the proposed API; please consider adding an API to add
> an application by app-id, so that we can add applications which have not been
> started yet.
> More about that here:
>
> https://lists.launchpad.net/ubuntu-phone/msg06680.html
>
> (I myself would have preferred a different approach, where an app could add
> itself to an existing session)

From when I've seen, a mir session has no concept of an app id, so we wouldn't be able to determine if we needed to add a newly started session to the existing trust session. There is a "Session::name", but that doesn't seem to equate to anything.
I'm not sure how we're supposed to deal with this.

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

I'm wondering why we have single "trust session" object managed by the client that can contain zero or more pids - wouldn't a more useful design be to have a collection of zero or more trusted pids that can be managed by the client?

Vis:

start_trust_session(pid1, pid2)
...
stop_trust_session(pid1)
...
start_trust_session(pid3)
...
stop_trust_session(pid2, pid3)

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

532 === renamed file 'src/server/scene/session_container.h' => 'include/server/mir/scene/session_container.h'

[Already discussed] above this interface should not be published. It is internal to the Mir scene implementation.

~~~~

424 +
425 + // TODO - remove these in favour of using handle_event

What has this to do with trust sessions?

~~~~

437 + virtual void session_start_trust_session_called(std::string const& app_name) = 0;

Is the name of the current session enough information to be useful? Would some information about what is trusted be appropriate?

~~~~

1902 + // only surface events have e.surface.id . Other events will throw exception.
1903 + try
1904 + {
1905 + surface_map->with_surface_do(e.surface.id,
1906 + [&e](MirSurface* surface)
1907 + {
1908 + surface->handle_event(e);
1909 + });
1910 + }
1911 + catch (std::exception const& x)
1912 + {
1913 + rpc_report->event_parsing_failed(event);
1914 + // Eat this exception as it doesn't affect other events
1915 + }

This looks suspiciously like using exceptions in the normal control path. We're not even logging information from x.

~~~~

2016 + BOOST_THROW_EXCEPTION(std::logic_error("Cannot start another trust session"));

If I read the surrounding code correctly, the client has requested a trust session while the server already has one associated with the client? That doesn't sound like a logic_error (in the Mir code), more like a runtime_error as the client code hasn't acted in the expected manner.

review: Needs Fixing
Revision history for this message
Nick Dedekind (nick-dedekind) wrote :

Moved the relationship information to the trust session, rather than being a property of the session itself.

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 :

The conflicts are not as numerous as Launchpad reports, but still numerous:
Text conflict in CMakeLists.txt
Text conflict in debian/changelog
Text conflict in include/server/mir/shell/session.h
Text conflict in src/client/CMakeLists.txt
Text conflict in src/client/default_connection_configuration.cpp
Text conflict in src/client/rpc/mir_socket_rpc_channel.cpp
Text conflict in src/server/frontend/default_configuration.cpp
Text conflict in src/server/frontend/session_mediator.cpp
Text conflict in tests/unit-tests/scene/test_application_session.cpp
Text conflict in tests/unit-tests/scene/test_session_manager.cpp
Text conflict in tests/unit-tests/scene/test_surface_impl.cpp
11 conflicts encountered.

review: Needs Fixing
Revision history for this message
Nick Dedekind (nick-dedekind) wrote :

Fixed conflicts.

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

(18) Spurious (old) changes to debian/changelog have now crept in.

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

(19) Conflict:
Text conflict in tests/unit-tests/scene/test_session_manager.cpp
1 conflicts encountered.

review: Needs Fixing
Revision history for this message
Alberto Mardegan (mardy) wrote :

Hi! I was asked to comment on the current approach, so here I am. :-)

I'll first recap what Online Accounts needs on a higher level (see also the description of bug 1230091):

The Online Accounts ("OA" for brevity) D-Bus service responds to client requests, and in response to these requests it's possible that we need to open the Online Accounts UI on top of the client application in a modal way: without blocking its process execution, but preventing it from getting mouse/keyboard input.

While the user is working with the OA window, it may be that we need to start other processes; these are not ordinary applications, but account plugins: there is a single binary which loads different QML UIs depending on the account provider (where provider is "google", "facebook", etc.). Also, the apparmor confinement under which the account plugin process is run depends on the account provider (we want to confine account plugins which come as part of click packages).

Note that different applications can talk to the OA API at the same time, and it's possible that at a certain given moment there are two different client applications involved in two different trust sessions, with two OA windows (each one being modal to one client application) and each one having an account plugin UI opened, which might be the same plugin for both sessions, or a different one.

We currently produce all the OA UIs from a single process (the OA D-Bus service); this bit of implementation can be changed if needed, and we can make so that each OA UI window leaves in a different process. This however would require more IPC and added complexity, and I believe that when Mir/Unity8 will hit the desktop it will anyway have to support the case of a single process creating multiple windows, so I hope that "1 pid = 1 window" won't be a requirement for the trust sessions.

Considering all the above, the API proposed in this branch doesn't seem to provide the functionality we need, since it only accepts PIDs as members of a session.

With no intention of sounding more expert than what I am, I'll quickly describe how my ideal API would look like, while indeed acknowledging that other implementations might exist and be better suited:
- refer to individual windows, not processes or applications
- API to request a window to be placed as modal of another window (possibly created by another process)
- such request might fail if the calling process is confined and has not been authorized
- API to authorize a process (by APP_ID) to set any of its window as modal to a given window
That is, mainly a couple of methods:
  void Window::setTransientFor(WindowHandle obscuredWindow);
  void Window::allowModalWindowsFromApplication(AppId app);
The first one for actually doing the reparenting work, and the latter to decide who can do that (besides unconfined apps).

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

Pushing to WIP as Nick's been off and the MP has yet to incorporate the results of various discussions.

Revision history for this message
Nick Dedekind (nick-dedekind) wrote :
Download full text (3.5 KiB)

> Hi! I was asked to comment on the current approach, so here I am. :-)
>
> I'll first recap what Online Accounts needs on a higher level (see also the
> description of bug 1230091):
>
> The Online Accounts ("OA" for brevity) D-Bus service responds to client
> requests, and in response to these requests it's possible that we need to open
> the Online Accounts UI on top of the client application in a modal way:
> without blocking its process execution, but preventing it from getting
> mouse/keyboard input.
>
> While the user is working with the OA window, it may be that we need to start
> other processes; these are not ordinary applications, but account plugins:
> there is a single binary which loads different QML UIs depending on the
> account provider (where provider is "google", "facebook", etc.). Also, the
> apparmor confinement under which the account plugin process is run depends on
> the account provider (we want to confine account plugins which come as part of
> click packages).
>
> Note that different applications can talk to the OA API at the same time, and
> it's possible that at a certain given moment there are two different client
> applications involved in two different trust sessions, with two OA windows
> (each one being modal to one client application) and each one having an
> account plugin UI opened, which might be the same plugin for both sessions, or
> a different one.
>
> We currently produce all the OA UIs from a single process (the OA D-Bus
> service); this bit of implementation can be changed if needed, and we can make
> so that each OA UI window leaves in a different process. This however would
> require more IPC and added complexity, and I believe that when Mir/Unity8 will
> hit the desktop it will anyway have to support the case of a single process
> creating multiple windows, so I hope that "1 pid = 1 window" won't be a
> requirement for the trust sessions.
>
> Considering all the above, the API proposed in this branch doesn't seem to
> provide the functionality we need, since it only accepts PIDs as members of a
> session.
>
>
> With no intention of sounding more expert than what I am, I'll quickly
> describe how my ideal API would look like, while indeed acknowledging that
> other implementations might exist and be better suited:
> - refer to individual windows, not processes or applications
> - API to request a window to be placed as modal of another window (possibly
> created by another process)
> - such request might fail if the calling process is confined and has not been
> authorized
> - API to authorize a process (by APP_ID) to set any of its window as modal to
> a given window
> That is, mainly a couple of methods:
> void Window::setTransientFor(WindowHandle obscuredWindow);
> void Window::allowModalWindowsFromApplication(AppId app);
> The first one for actually doing the reparenting work, and the latter to
> decide who can do that (besides unconfined apps).

As far as I'm aware, we're not doing any Qt API for trust sessions. This will be dealt with by dedicated trusted helpers which use the mir API directly.
[At the moment,] a trusted helper starts a trust session between 2 or more sessions. T...

Read more...

Revision history for this message
Nick Dedekind (nick-dedekind) wrote :

Maybe quite a few changes.

1) The mir_trust_session_add_trusted_session should now be called after a mir_trust_session_start. Allows trusted helpers to dynamically add sessions to the trust session. This is more for phase 2.

use case:
Gallery -> ContentHub -> Facebook/Flickr/Twitter
   a) user starts gallery
   a.1) user view: gallery app pops up
   b) user selects picture and clicks "share"
   c) content hub creates destination picker
   c.1) user view: destination picker surface pops up
   d) user selects Facebook
   d.1) user view: Facebook pops up.

While it's possible for the trust session to know about the content hub + gallery, it doesn't know the user will select facebook when it starts.

2) I've separated out the trust session notifications from the SessionListener into it's own TrustSessionListener.

3) Added a trust session container, which has bidirectional mapping between process ids and TrustSessions. This allows quick lookup when we need to add/remove sessions from a trust session.
3.1) mir::Session now has no links to trust session/trusted helper.

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

Looking at the client API:

    MirTrustSession* mir_connection_create_trust_session(MirConnection* connection);

I would expect "create_trust_session" to take parameters (such as the event callback) and create the server-side trust session (which would implicitly make it an async call).

AIUI this just creates a client-side object that still needs to be initialized before the server-side trust session is created using "mir_trust_session_start".

Is there any reason to separate out these create/set_event_callback/start calls?

~~~~

mir_trust_session_add_trusted_session

This is an async call - so presumably it is expected to be invoked after the trust session is started?

Does that imply a round trip for each pid added to the trust session? If so would it be better to accept a list of pids?

Can it be called on a created (but not started) trust session?

~~~~

Is there a missing mir_trust_session_remove_trusted_session() for revoking trust?

~~~~

mir_trust_session_set_event_callback

The only state changes appear to be "start" and "stop" - which are under the control of the client. So does this do any more than duplicate the functionality of the WaitHandles returned by the start/stop functions?

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

std::shared_ptr<TrustSession> Shell::start_trust_session_for(std::string& error,
                                                                  std::shared_ptr<Session> const& session,
                                                                  shell::TrustSessionCreationParameters const& params) = 0;

This "error" parameter is not an idiomatic way to handle failure. Simply throwing an exception derived from std::exception that returns the error in what() will result in invoke<>() setting the error.

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

bool shell::TrustSession::add_trusted_child(std::shared_ptr<shell::Session> const& session) = 0;

I'm not convinced that TrustSession *owns* Session is the correct model. It means that if a client disconnects while in a trust session the Mir Session remains alive. Which is confusing at best.

I note that in practice scene::TrustSession only keeps weak_ptr<Session> which is a better reflection of the relationship. However, I still think that the relationship between TrustSession and Session better modeled as an association than as attributes.

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

In TrustSession::add_trusted_child() there's a call "session->begin_trust_session();" which will send a mir_event_type_trust_session_state_change to the "child" process.

But AIUI the child isn't the "helper" process that created the trust session and can't have registered a mir_trust_session_event_callback (which needs a trust session).

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

+class TrustSession
+{
+public:
+ virtual ~TrustSession() = default;
+
+ virtual void for_each_trusted_client_process(std::function<void(pid_t pid)> f, bool reverse) const = 0;

I don't see what this function is for. It isn't used. Which is just as well because the implementation is useless:

+void ms::TrustSession::for_each_trusted_client_process(std::function<void(pid_t pid)>, bool) const
+{
+}

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

+class TrustSessionListener
+{
+public:
+ virtual void starting(std::shared_ptr<TrustSession> const& trust_session) = 0;
+ virtual void stopping(std::shared_ptr<TrustSession> const& trust_session) = 0;
+
+ virtual void trusted_session_beginning(TrustSession& trust_session, std::shared_ptr<Session> const& session) = 0;
+ virtual void trusted_session_ending(TrustSession& trust_session, std::shared_ptr<Session> const& session) = 0;

The listener shouldn't be given any ownership of the referenced objects. So the prototypes should be:

    virtual void starting(TrustSession const& trust_session) = 0;
    virtual void stopping(TrustSession const& trust_session) = 0;

    virtual void trusted_session_beginning(TrustSession& trust_session, Session const& session) = 0;
    virtual void trusted_session_ending(TrustSession& trust_session, Session const& session) = 0;

review: Needs Fixing
Revision history for this message
Nick Dedekind (nick-dedekind) wrote :

> Looking at the client API:
>
> MirTrustSession* mir_connection_create_trust_session(MirConnection*
> connection);
>
> I would expect "create_trust_session" to take parameters (such as the event
> callback) and create the server-side trust session (which would implicitly
> make it an async call).
>
> AIUI this just creates a client-side object that still needs to be initialized
> before the server-side trust session is created using
> "mir_trust_session_start".
>
> Is there any reason to separate out these create/set_event_callback/start
> calls?

I guess not anymore. Previously it would be possible to start and stop trust sessions multiple times; but I think with the "post-start" adding of participants, it's no longer a possibility.
I've merged all of these into a mir_connection_start_trust_session which async returns a MirTrustSession.
Not sure if the stop/release should be separate now. Left as is for now.

>
> ~~~~
>
> mir_trust_session_add_trusted_session
>
> This is an async call - so presumably it is expected to be invoked after the
> trust session is started?
>
> Does that imply a round trip for each pid added to the trust session? If so
> would it be better to accept a list of pids?
>
> Can it be called on a created (but not started) trust session?
>

It does have a round trip, but as I don't think it's an issue. We call the start_trust_session with the pid of the "source" participant (whatever is "using" the trust helper. eg. gallery application). From there, thinking about the flow, we would be layering the trust as the user makes decisions (eg. content hub "share with google+", then online accounts "log in to google+"). So practically speaking we only do one layer of trust at a time.

> ~~~~
>
> Is there a missing mir_trust_session_remove_trusted_session() for revoking
> trust?

Closing a session will remove it from the server trust session, but I'm not sure about the helper explicitly removing it. For the moment at least, I think we can do without it.

>
> ~~~~
>
> mir_trust_session_set_event_callback
>
> The only state changes appear to be "start" and "stop" - which are under the
> control of the client. So does this do any more than duplicate the
> functionality of the WaitHandles returned by the start/stop functions?

The server can also stop an active trust session (if the application closes, we don't want it hanging around). Also, for first iteration, we want to stop the trust session when switching away from the app.
So we need the helper to get a notification of this.

Revision history for this message
Nick Dedekind (nick-dedekind) wrote :

> std::shared_ptr<TrustSession> Shell::start_trust_session_for(std::string&
> error,
> std::shared_ptr<Session> const& session,
> shell::TrustSessionCreationParameters const& params) = 0;
>
> This "error" parameter is not an idiomatic way to handle failure. Simply
> throwing an exception derived from std::exception that returns the error in
> what() will result in invoke<>() setting the error.

Thanks, didn't know that.
Removed error parameter from interface.

Revision history for this message
Nick Dedekind (nick-dedekind) wrote :

> In TrustSession::add_trusted_child() there's a call
> "session->begin_trust_session();" which will send a
> mir_event_type_trust_session_state_change to the "child" process.
>
> But AIUI the child isn't the "helper" process that created the trust session
> and can't have registered a mir_trust_session_event_callback (which needs a
> trust session).

Right. this was so that the participants could be informed that a trust session has been started with them; if they need to do anything fancy. But at the moment, I don't think there's a client API for applying for general distributor events (only trust session & surface events I think), so I've removed the event send from the participants, but left it on the helper.

Revision history for this message
Nick Dedekind (nick-dedekind) wrote :

> +class TrustSession
> +{
> +public:
> + virtual ~TrustSession() = default;
> +
> + virtual void for_each_trusted_client_process(std::function<void(pid_t
> pid)> f, bool reverse) const = 0;
>
> I don't see what this function is for. It isn't used. Which is just as well
> because the implementation is useless:
>
> +void
> ms::TrustSession::for_each_trusted_client_process(std::function<void(pid_t
> pid)>, bool) const
> +{
> +}

old code from before the process<->trust_session bi-directional map.
removed.

Revision history for this message
Nick Dedekind (nick-dedekind) wrote :

> +class TrustSessionListener
> +{
> +public:
> + virtual void starting(std::shared_ptr<TrustSession> const& trust_session)
> = 0;
> + virtual void stopping(std::shared_ptr<TrustSession> const& trust_session)
> = 0;
> +
> + virtual void trusted_session_beginning(TrustSession& trust_session,
> std::shared_ptr<Session> const& session) = 0;
> + virtual void trusted_session_ending(TrustSession& trust_session,
> std::shared_ptr<Session> const& session) = 0;
>
> The listener shouldn't be given any ownership of the referenced objects. So
> the prototypes should be:
>
> virtual void starting(TrustSession const& trust_session) = 0;
> virtual void stopping(TrustSession const& trust_session) = 0;
>
> virtual void trusted_session_beginning(TrustSession& trust_session,
> Session const& session) = 0;
> virtual void trusted_session_ending(TrustSession& trust_session, Session
> const& session) = 0;

changed.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'examples/CMakeLists.txt'
--- examples/CMakeLists.txt 2014-05-05 03:36:45 +0000
+++ examples/CMakeLists.txt 2014-05-09 12:26:43 +0000
@@ -92,6 +92,9 @@
9292
93)93)
9494
95add_executable(mir_demo_client_trust_session trust_session.c)
96target_link_libraries(mir_demo_client_trust_session mirclient)
97
95add_library(mirdraw STATIC graphics_utils.cpp)98add_library(mirdraw STATIC graphics_utils.cpp)
96target_link_libraries(mirdraw ${GLESv2_LIBRARIES})99target_link_libraries(mirdraw ${GLESv2_LIBRARIES})
97100
@@ -143,7 +146,7 @@
143 server_configuration.cpp146 server_configuration.cpp
144)147)
145148
146target_link_libraries(mir_demo_standalone_input_filter 149target_link_libraries(mir_demo_standalone_input_filter
147 mirserver150 mirserver
148)151)
149152
@@ -158,8 +161,9 @@
158 mir_demo_client_multiwin161 mir_demo_client_multiwin
159 mir_demo_client_display_config162 mir_demo_client_display_config
160 mir_demo_client_progressbar163 mir_demo_client_progressbar
164 mir_demo_client_trust_session
161 mir_demo_standalone_input_filter165 mir_demo_standalone_input_filter
162 mir_demo_standalone_render_to_fb 166 mir_demo_standalone_render_to_fb
163 mir_demo_standalone_render_surfaces167 mir_demo_standalone_render_surfaces
164)168)
165169
166170
=== modified file 'examples/demo-inprocess-surface-client/inprocess_egl_client.cpp'
--- examples/demo-inprocess-surface-client/inprocess_egl_client.cpp 2014-04-15 05:31:19 +0000
+++ examples/demo-inprocess-surface-client/inprocess_egl_client.cpp 2014-05-09 12:26:43 +0000
@@ -102,7 +102,7 @@
102102
103 auto input_platform = mircv::InputPlatform::create();103 auto input_platform = mircv::InputPlatform::create();
104 input_thread = input_platform->create_input_thread(104 input_thread = input_platform->create_input_thread(
105 surface->client_input_fd(), 105 surface->client_input_fd(),
106 std::bind(std::mem_fn(&me::InprocessEGLClient::handle_event), this, std::placeholders::_1));106 std::bind(std::mem_fn(&me::InprocessEGLClient::handle_event), this, std::placeholders::_1));
107 input_thread->start();107 input_thread->start();
108108
109109
=== modified file 'examples/fingerpaint.c'
=== added file 'examples/trust_session.c'
--- examples/trust_session.c 1970-01-01 00:00:00 +0000
+++ examples/trust_session.c 2014-05-09 12:26:43 +0000
@@ -0,0 +1,249 @@
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: Nick Dedekind <nick.dedekind <nick.dedekind@canonical.com>
17 */
18
19#define _POSIX_SOURCE
20
21#include "mir_toolkit/mir_client_library.h"
22#include "mir_toolkit/mir_trust_session.h"
23
24#include <assert.h>
25#include <string.h>
26#include <stdio.h>
27#include <stdlib.h>
28#include <getopt.h>
29#include <unistd.h>
30#include <errno.h>
31#include <sys/wait.h>
32#include <sys/types.h>
33#include <signal.h>
34
35///\page trust_session.c trust_session.c: A mir client which starts a trust session and trusted client app.
36/// mir_demo_client_trust_session shows the use of mir trust session API.
37/// This program opens a mir connection and creates a trust session.
38///\section trusted_helper trusted_helper()
39/// Opens a mir connection and creates a trust session
40/// before closing the trust session and connection.
41///\section trust_session_app trust_session_app()
42/// Opens a mir connection and creates a surface
43/// before releasing the surface and closing the connection.
44///\example trust_session.c A mir client demonstrating trust sessions.
45///\section MirDemoState MirDemoState
46/// The handles needs to be accessible both to callbacks and to the control function.
47///\snippet trust_session.c MirDemoState_tag
48///\section Callbacks Callbacks
49///\snippet trust_session.c Callback_tag
50/// This program creates two processes, both opening a mir connection, one starting
51/// a trust session with the other process.
52
53///\internal [MirDemoState_tag]
54// Utility structure for the state of a single session.
55typedef struct MirDemoState
56{
57 MirConnection *connection;
58 MirSurface *surface;
59 MirTrustSession *trust_session;
60 pid_t child_pid;
61} MirDemoState;
62///\internal [MirDemoState_tag]
63
64
65///\internal [Callback_tag]
66// Callback to update MirDemoState on trust_session_event
67static void trust_session_event_callback(MirTrustSession* trust_session,
68 MirTrustSessionState state,
69 void* context)
70{
71 (void)trust_session;
72 MirDemoState* demo_state = (MirDemoState*)context;
73
74 printf("Trust Session state updated to %d\n", state);
75 if (state == mir_trust_session_state_stopped)
76 {
77 kill(demo_state->child_pid, SIGINT);
78 }
79}
80///\internal [Callback_tag]
81
82void start_session(const char* server, const char* name, MirDemoState* mcd)
83{
84 // Call mir_connect synchronously
85 mcd->connection = mir_connect_sync(server, name);
86
87 // We expect a connection handle;
88 // we expect it to be valid; and,
89 // we don't expect an error description
90 assert(mcd->connection != NULL);
91 assert(mir_connection_is_valid(mcd->connection));
92 assert(strcmp(mir_connection_get_error_message(mcd->connection), "") == 0);
93 printf("%s: Connected\n", name);
94
95 // We can query information about the platform we're running on
96 {
97 MirPlatformPackage platform_package;
98 platform_package.data_items = -1;
99 platform_package.fd_items = -1;
100
101 mir_connection_get_platform(mcd->connection, &platform_package);
102 assert(0 <= platform_package.data_items);
103 assert(0 <= platform_package.fd_items);
104 }
105}
106
107void stop_session(MirDemoState* mcd, const char* name)
108{
109 if (mcd->trust_session)
110 {
111 mir_trust_session_release(mcd->trust_session);
112 mcd->trust_session = 0;
113 printf("%s: Trust session released \n", name);
114 }
115
116 if (mcd->surface)
117 {
118 // We should release our surface
119 mir_surface_release_sync(mcd->surface);
120 mcd->surface = 0;
121 printf("%s: Surface released\n", name);
122 }
123
124 // We should release our connection
125 mir_connection_release(mcd->connection);
126 printf("%s: Connection released\n", name);
127}
128
129void trusted_helper(const char* server, pid_t child_pid)
130{
131 MirDemoState mcd;
132 mcd.connection = 0;
133 mcd.surface = 0;
134 mcd.trust_session = 0;
135 mcd.child_pid = child_pid;
136 start_session(server, "trusted_helper", &mcd);
137
138 // We create a trust session
139 mcd.trust_session = mir_connection_start_trust_session_sync(mcd.connection, getpid(), trust_session_event_callback, &mcd);
140 assert(mcd.trust_session != NULL);
141
142 assert(mir_trust_session_get_state(mcd.trust_session) == mir_trust_session_state_started);
143 puts("trusted_helper: Started trust session");
144
145 MirTrustSessionAddTrustResult add_result = mir_trust_session_add_trusted_session_sync(mcd.trust_session, child_pid);
146 assert(add_result == mir_trust_session_add_tust_succeeded);
147 printf("trusted_helper: added trusted session pid: %d\n", child_pid);
148
149 int status;
150 printf("trusted_helper: waiting on child app: %d\n", child_pid);
151 waitpid(child_pid, &status, 0);
152
153 if (mir_trust_session_get_state(mcd.trust_session) == mir_trust_session_state_started)
154 {
155 mir_trust_session_stop_sync(mcd.trust_session);
156 assert(mir_trust_session_get_state(mcd.trust_session) == mir_trust_session_state_stopped);
157 puts("trusted_helper: Stopped trust session");
158 }
159 else
160 {
161 puts("trusted_helper: Trusted session stoped by server");
162 }
163 puts("trusted_helper: Done");
164
165 stop_session(&mcd, "trusted_helper");
166}
167
168void trust_session_app(const char* server)
169{
170 MirDemoState mcd;
171 mcd.connection = 0;
172 mcd.surface = 0;
173 mcd.trust_session = 0;
174 start_session(server, "trust_session_app", &mcd);
175
176 // Identify a supported pixel format
177 MirPixelFormat pixel_format;
178 unsigned int valid_formats;
179 mir_connection_get_available_surface_formats(mcd.connection, &pixel_format, 1, &valid_formats);
180 MirSurfaceParameters const request_params =
181 {__PRETTY_FUNCTION__, 640, 480, pixel_format,
182 mir_buffer_usage_hardware, mir_display_output_id_invalid};
183
184 // ...we create a surface using that format and wait for callback to complete.
185 mcd.surface = mir_connection_create_surface_sync(mcd.connection, &request_params);
186
187 // We expect a surface handle;
188 // we expect it to be valid; and,
189 // we don't expect an error description
190 assert(mcd.surface != NULL);
191 assert(mir_surface_is_valid(mcd.surface));
192 assert(strcmp(mir_surface_get_error_message(mcd.surface), "") == 0);
193 puts("trust_session_app: Surface created");
194
195 puts("trust_session_app: Press any key to exit");
196 // Wait for stdin
197 getchar();
198 puts("trust_session_app: Done");
199
200 stop_session(&mcd, "trust_session_app");
201}
202
203// The main() function deals with parsing arguments and defaults
204int main(int argc, char* argv[])
205{
206 // Some variables for holding command line options
207 char const *server = NULL;
208
209 // Parse the command line
210 {
211 int arg;
212 opterr = 0;
213 while ((arg = getopt (argc, argv, "c:hm:")) != -1)
214 {
215 switch (arg)
216 {
217 case 'm':
218 server = optarg;
219 break;
220
221 case '?':
222 case 'h':
223 default:
224 puts(argv[0]);
225 puts("Usage:");
226 puts(" -m <Mir server socket>");
227 puts(" -h: this help text");
228 return -1;
229 }
230 }
231 }
232
233 // Start a new process.
234 // This simulates the helper starting a new application which it adds to the trusted session.
235 pid_t pid = fork();
236
237 if (pid == 0)
238 {
239 sleep(1);
240 trust_session_app(server);
241 }
242 else if (pid > 0)
243 {
244 printf("trusted_helper: pid:%d , child:%d\n", getpid(), pid);
245 trusted_helper(server, pid);
246 }
247
248 return 0;
249}
0250
=== added file 'include/client/mir_toolkit/mir_trust_session.h'
--- include/client/mir_toolkit/mir_trust_session.h 1970-01-01 00:00:00 +0000
+++ include/client/mir_toolkit/mir_trust_session.h 2014-05-09 12:26:43 +0000
@@ -0,0 +1,119 @@
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 Lesser 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 Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef MIR_TOOLKIT_MIR_TRUST_SESSION_H_
18#define MIR_TOOLKIT_MIR_TRUST_SESSION_H_
19
20#include "mir_toolkit/mir_client_library.h"
21
22#include <sys/types.h>
23
24#ifdef __cplusplus
25/**
26 * \addtogroup mir_toolkit
27 * @{
28 */
29extern "C" {
30#endif
31
32/**
33 * Create an new trust session
34 * \param [in] connection The connection
35 * \param [in] base_session_pid The process id of the initiating application
36 * \param [in] start_callback Callback function to be invoked when request
37 * completes
38 * \param [in] start_callback The function to be called when the trust session event occurs
39 * \param [in,out] context User data passed to the callback functions
40 * \return A handle that can be passed to mir_wait_for
41 */
42MirWaitHandle *mir_connection_start_trust_session(MirConnection* connection,
43 pid_t base_session_pid,
44 mir_trust_session_callback start_callback,
45 mir_trust_session_event_callback event_callback,
46 void* context);
47
48/**
49 * Create an new trust session
50 * \param [in] connection The connection
51 * \param [in] base_session_pid The process id of the initiating application
52 * \param [in] callback Callback function to be invoked when request
53 * completes
54 * \param [in,out] context User data passed to the callback function
55 * \param [in] callback The function to be called when the trust session event occurs
56 * \return A handle that can be passed to mir_wait_for
57 */
58MirTrustSession *mir_connection_start_trust_session_sync(MirConnection* connection,
59 pid_t base_session_pid,
60 mir_trust_session_event_callback event_callback,
61 void* context);
62
63/**
64 * Add a process id to the trust session relationship
65 * \param [in] trust_session The trust session
66 * \param [in] session_pid The process id of the application to add
67 * \param [in] callback Callback function to be invoked when request
68 * completes
69 * \return A MirTrustSessionAddTrustResult result of the call
70 */
71MirWaitHandle *mir_trust_session_add_trusted_session(MirTrustSession *trust_session,
72 pid_t session_pid,
73 mir_trust_session_add_trusted_session_callback callback,
74 void* context);
75
76/**
77 * Perform a mir_trust_session_add_trusted_pid() but also wait for and return the result.
78 * \param [in] trust_session The trust session
79 * \param [in] pid The process id of the application to add
80 * \return A MirTrustSessionAddTrustResult result of the call
81 */
82MirTrustSessionAddTrustResult mir_trust_session_add_trusted_session_sync(MirTrustSession *trust_session,
83 pid_t pid);
84
85/**
86 * Request the cancellation of a trust session
87 * \param [in] trust_session The trust session
88 * \return True if the request was made successfully,
89 * false otherwise
90 */
91MirWaitHandle *mir_trust_session_stop(MirTrustSession *trust_session, mir_trust_session_callback callback, void* context);
92
93/**
94 * Perform a mir_trust_session_stop() but also wait for and return the result.
95 * \param [in] trust_session The trust session
96 * \return True if the request was made successfully,
97 * false otherwise
98 */
99MirBool mir_trust_session_stop_sync(MirTrustSession *trust_session);
100
101/**
102 * Return the state of trust session
103 * \param [in] trust_session The trust session
104 * \return The state of the trust session
105 */
106MirTrustSessionState mir_trust_session_get_state(MirTrustSession *trust_session);
107
108/**
109 * Release a trust session
110 * \param [in] trust_session The trust session to release
111 */
112void mir_trust_session_release(MirTrustSession* trust_session);
113
114#ifdef __cplusplus
115}
116/**@}*/
117#endif
118
119#endif /* MIR_TOOLKIT_MIR_TRUST_SESSION_H_ */
0120
=== modified file 'include/server/mir/default_server_configuration.h'
--- include/server/mir/default_server_configuration.h 2014-05-09 03:00:20 +0000
+++ include/server/mir/default_server_configuration.h 2014-05-09 12:26:43 +0000
@@ -83,6 +83,7 @@
83class SurfaceStack;83class SurfaceStack;
84class InputRegistrar;84class InputRegistrar;
85class SceneReport;85class SceneReport;
86class TrustSessionListener;
86}87}
87namespace graphics88namespace graphics
88{89{
@@ -212,6 +213,7 @@
212 virtual std::shared_ptr<scene::PlacementStrategy> the_placement_strategy();213 virtual std::shared_ptr<scene::PlacementStrategy> the_placement_strategy();
213 virtual std::shared_ptr<scene::SessionListener> the_session_listener();214 virtual std::shared_ptr<scene::SessionListener> the_session_listener();
214 virtual std::shared_ptr<shell::DisplayLayout> the_shell_display_layout();215 virtual std::shared_ptr<shell::DisplayLayout> the_shell_display_layout();
216 virtual std::shared_ptr<scene::TrustSessionListener> the_trust_session_listener();
215 /** @} */217 /** @} */
216218
217 /** @name internal scene configuration219 /** @name internal scene configuration
@@ -322,6 +324,7 @@
322 CachedPtr<scene::MediatingDisplayChanger> mediating_display_changer;324 CachedPtr<scene::MediatingDisplayChanger> mediating_display_changer;
323 CachedPtr<graphics::GLProgramFactory> gl_program_factory;325 CachedPtr<graphics::GLProgramFactory> gl_program_factory;
324 CachedPtr<graphics::GLConfig> gl_config;326 CachedPtr<graphics::GLConfig> gl_config;
327 CachedPtr<scene::TrustSessionListener> trust_session_listener;
325328
326private:329private:
327 std::shared_ptr<options::Configuration> const configuration_options;330 std::shared_ptr<options::Configuration> const configuration_options;
328331
=== modified file 'include/server/mir/frontend/connection_context.h'
--- include/server/mir/frontend/connection_context.h 2014-05-08 13:07:13 +0000
+++ include/server/mir/frontend/connection_context.h 2014-05-09 12:26:43 +0000
@@ -1,3 +1,4 @@
1<<<<<<< TREE
1/*2/*
2 * Copyright © 2014 Canonical Ltd.3 * Copyright © 2014 Canonical Ltd.
3 *4 *
@@ -50,3 +51,60 @@
50}51}
5152
52#endif /* MIR_FRONTEND_CONNECTION_CONTEXT_H_ */53#endif /* MIR_FRONTEND_CONNECTION_CONTEXT_H_ */
54=======
55/*
56 * Copyright © 014 Canonical Ltd.
57 *
58 * This program is free software: you can redistribute it and/or modify it
59 * under the terms of the GNU General Public License version 3,
60 * as published by the Free Software Foundation.
61 *
62 * This program is distributed in the hope that it will be useful,
63 * but WITHOUT ANY WARRANTY; without even the implied warranty of
64 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
65 * GNU General Public License for more details.
66 *
67 * You should have received a copy of the GNU General Public License
68 * along with this program. If not, see <http://www.gnu.org/licenses/>.
69 *
70 * Authored by: Alan Griffiths <alan@octopull.co.uk>
71 */
72
73#ifndef MIR_FRONTEND_CONNECTION_CONTEXT_H_
74#define MIR_FRONTEND_CONNECTION_CONTEXT_H_
75
76#include <functional>
77#include <memory>
78
79namespace mir
80{
81namespace frontend
82{
83class Connector;
84class Session;
85
86class ConnectionContext
87{
88public:
89 ConnectionContext() = delete;
90 ConnectionContext(const ConnectionContext&) = default;
91 ConnectionContext& operator=(const ConnectionContext&) = default;
92 ConnectionContext(Connector const* connector) :
93 ConnectionContext([](std::shared_ptr<Session> const&){}, connector) {}
94 ConnectionContext(
95 std::function<void(std::shared_ptr<Session> const& session)> const connect_handler,
96 Connector const* connector);
97
98 int fd_for_new_client(std::function<void(std::shared_ptr<Session> const& session)> const& connect_handler) const;
99
100 void handle_client_connect(std::shared_ptr<Session> const& session) const { connect_handler(session); }
101
102private:
103 std::function<void(std::shared_ptr<Session> const& session)> const connect_handler;
104 Connector const* const connector;
105};
106}
107}
108
109#endif /* MIR_FRONTEND_CONNECTION_CONTEXT_H_ */
110>>>>>>> MERGE-SOURCE
53111
=== modified file 'include/server/mir/frontend/event_sink.h'
--- include/server/mir/frontend/event_sink.h 2013-08-28 03:41:48 +0000
+++ include/server/mir/frontend/event_sink.h 2014-05-09 12:26:43 +0000
@@ -35,6 +35,8 @@
35 virtual ~EventSink() = default;35 virtual ~EventSink() = default;
3636
37 virtual void handle_event(MirEvent const& e) = 0;37 virtual void handle_event(MirEvent const& e) = 0;
38
39 // TODO - remove these in favour of using handle_event
38 virtual void handle_lifecycle_event(MirLifecycleState state) = 0;40 virtual void handle_lifecycle_event(MirLifecycleState state) = 0;
39 virtual void handle_display_config_change(graphics::DisplayConfiguration const& config) = 0;41 virtual void handle_display_config_change(graphics::DisplayConfiguration const& config) = 0;
4042
4143
=== modified file 'include/server/mir/frontend/session.h'
--- include/server/mir/frontend/session.h 2014-05-06 16:54:43 +0000
+++ include/server/mir/frontend/session.h 2014-05-09 12:26:43 +0000
@@ -50,6 +50,7 @@
50 virtual void destroy_surface(SurfaceId surface) = 0;50 virtual void destroy_surface(SurfaceId surface) = 0;
51 virtual std::shared_ptr<Surface> get_surface(SurfaceId surface) const = 0;51 virtual std::shared_ptr<Surface> get_surface(SurfaceId surface) const = 0;
5252
53 virtual pid_t process_id() const = 0;
53 virtual std::string name() const = 0;54 virtual std::string name() const = 0;
5455
55 virtual void hide() = 0;56 virtual void hide() = 0;
5657
=== modified file 'include/server/mir/frontend/session_mediator_report.h'
--- include/server/mir/frontend/session_mediator_report.h 2014-03-06 06:05:17 +0000
+++ include/server/mir/frontend/session_mediator_report.h 2014-05-09 12:26:43 +0000
@@ -48,6 +48,12 @@
4848
49 virtual void session_configure_display_called(std::string const& app_name) = 0;49 virtual void session_configure_display_called(std::string const& app_name) = 0;
5050
51 virtual void session_start_trust_session_called(std::string const& app_name, std::string const& trust_info) = 0;
52
53 virtual void session_add_trusted_session_called(std::string const& app_name, std::string const& trust_info) = 0;
54
55 virtual void session_stop_trust_session_called(std::string const& app_name) = 0;
56
51 virtual void session_error(57 virtual void session_error(
52 std::string const& app_name,58 std::string const& app_name,
53 char const* method,59 char const* method,
5460
=== modified file 'include/server/mir/frontend/shell.h'
--- include/server/mir/frontend/shell.h 2014-04-15 05:31:19 +0000
+++ include/server/mir/frontend/shell.h 2014-05-09 12:26:43 +0000
@@ -20,6 +20,7 @@
20#define MIR_FRONTEND_SHELL_H_20#define MIR_FRONTEND_SHELL_H_
2121
22#include "mir/frontend/surface_id.h"22#include "mir/frontend/surface_id.h"
23#include "mir_toolkit/common.h"
2324
24#include <sys/types.h>25#include <sys/types.h>
2526
@@ -30,11 +31,13 @@
30namespace scene31namespace scene
31{32{
32struct SurfaceCreationParameters;33struct SurfaceCreationParameters;
34struct TrustSessionCreationParameters;
33}35}
34namespace frontend36namespace frontend
35{37{
36class EventSink;38class EventSink;
37class Session;39class Session;
40class TrustSession;
3841
39class Shell42class Shell
40{43{
@@ -54,6 +57,12 @@
5457
55 virtual void handle_surface_created(std::shared_ptr<Session> const& session) = 0;58 virtual void handle_surface_created(std::shared_ptr<Session> const& session) = 0;
5659
60 virtual std::shared_ptr<TrustSession> start_trust_session_for(std::shared_ptr<Session> const& session,
61 scene::TrustSessionCreationParameters const& params) = 0;
62 virtual MirTrustSessionAddTrustResult add_trusted_session_for(std::shared_ptr<TrustSession> const& trust_session,
63 pid_t session_pid) = 0;
64 virtual void stop_trust_session(std::shared_ptr<TrustSession> const& trust_session) = 0;
65
57protected:66protected:
58 Shell() = default;67 Shell() = default;
59 Shell(const Shell&) = delete;68 Shell(const Shell&) = delete;
6069
=== added file 'include/server/mir/frontend/trust_session.h'
--- include/server/mir/frontend/trust_session.h 1970-01-01 00:00:00 +0000
+++ include/server/mir/frontend/trust_session.h 2014-05-09 12:26:43 +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 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: Nick Dedekind <nick.dedekind@canonical.com>
17 */
18
19#ifndef MIR_FRONTEND_TRUST_SESSION_H_
20#define MIR_FRONTEND_TRUST_SESSION_H_
21
22#include "mir_toolkit/common.h"
23
24#include <sys/types.h>
25#include <vector>
26#include <string>
27#include <memory>
28
29namespace mir
30{
31
32namespace frontend
33{
34class TrustSession
35{
36public:
37 virtual ~TrustSession() = default;
38
39 virtual MirTrustSessionState get_state() const = 0;
40
41 virtual void start() = 0;
42 virtual void stop() = 0;
43
44protected:
45 TrustSession() = default;
46 TrustSession(const TrustSession&) = delete;
47 TrustSession& operator=(const TrustSession&) = delete;
48};
49
50}
51}
52
53#endif // MIR_FRONTEND_TRUST_SESSION_H_
054
=== added file 'include/server/mir/scene/null_trust_session_listener.h'
--- include/server/mir/scene/null_trust_session_listener.h 1970-01-01 00:00:00 +0000
+++ include/server/mir/scene/null_trust_session_listener.h 2014-05-09 12:26:43 +0000
@@ -0,0 +1,50 @@
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: Nick Dedekind <nick.dedekind@canonical.com>
17 */
18
19#ifndef MIR_SCENE_NULL_TRUST_SESSION_LISTENER_H_
20#define MIR_SCENE_NULL_TRUST_SESSION_LISTENER_H_
21
22#include "mir/scene/trust_session_listener.h"
23
24namespace mir
25{
26namespace scene
27{
28
29class NullTrustSessionListener : public TrustSessionListener
30{
31public:
32 NullTrustSessionListener() = default;
33 virtual ~NullTrustSessionListener() noexcept(true) = default;
34
35 void starting(TrustSession const&) override {};
36 void stopping(TrustSession const&) override {};
37
38 void trusted_session_beginning(TrustSession&, Session const&) override {};
39 void trusted_session_ending(TrustSession&, Session const&) override {};
40
41protected:
42 NullTrustSessionListener(const NullTrustSessionListener&) = delete;
43 NullTrustSessionListener& operator=(const NullTrustSessionListener&) = delete;
44};
45
46}
47}
48
49
50#endif // MIR_SHELL_NULL_TRUST_SESSION_LISTENER_H_
051
=== modified file 'include/server/mir/scene/session.h'
--- include/server/mir/scene/session.h 2014-04-15 05:31:19 +0000
+++ include/server/mir/scene/session.h 2014-05-09 12:26:43 +0000
@@ -34,12 +34,14 @@
34{34{
35public:35public:
36 virtual void force_requests_to_complete() = 0;36 virtual void force_requests_to_complete() = 0;
37 virtual pid_t process_id() const = 0;
3837
39 virtual void take_snapshot(SnapshotCallback const& snapshot_taken) = 0;38 virtual void take_snapshot(SnapshotCallback const& snapshot_taken) = 0;
40 virtual std::shared_ptr<Surface> default_surface() const = 0;39 virtual std::shared_ptr<Surface> default_surface() const = 0;
41 virtual void set_lifecycle_state(MirLifecycleState state) = 0;40 virtual void set_lifecycle_state(MirLifecycleState state) = 0;
42 virtual void send_display_config(graphics::DisplayConfiguration const&) = 0;41 virtual void send_display_config(graphics::DisplayConfiguration const&) = 0;
42
43 virtual void begin_trust_session() = 0;
44 virtual void end_trust_session() = 0;
43};45};
44}46}
45}47}
4648
=== added file 'include/server/mir/scene/trust_session.h'
--- include/server/mir/scene/trust_session.h 1970-01-01 00:00:00 +0000
+++ include/server/mir/scene/trust_session.h 2014-05-09 12:26:43 +0000
@@ -0,0 +1,43 @@
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: Nick Dedekind <nick.dedekind@canonical.com>
17 */
18
19#ifndef MIR_SCENE_TRUST_SESSION_H_
20#define MIR_SCENE_TRUST_SESSION_H_
21
22#include "mir/frontend/trust_session.h"
23
24namespace mir
25{
26namespace scene
27{
28class Session;
29
30class TrustSession : public frontend::TrustSession
31{
32public:
33 virtual std::weak_ptr<Session> get_trusted_helper() const = 0;
34
35 virtual bool add_trusted_child(std::shared_ptr<Session> const& session) = 0;
36 virtual void remove_trusted_child(std::shared_ptr<Session> const& session) = 0;
37 virtual void for_each_trusted_child(std::function<void(std::shared_ptr<Session> const&)> f, bool reverse) const = 0;
38};
39
40}
41}
42
43#endif // MIR_SHELL_TRUST_SESSION_H_
044
=== added file 'include/server/mir/scene/trust_session_creation_parameters.h'
--- include/server/mir/scene/trust_session_creation_parameters.h 1970-01-01 00:00:00 +0000
+++ include/server/mir/scene/trust_session_creation_parameters.h 2014-05-09 12:26:43 +0000
@@ -0,0 +1,46 @@
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: Nick Dedekind <nick.dedekind@canonical.com>
17 */
18
19#ifndef MIR_SCENE_TRUSTED_SESSION_CREATION_PARAMETERS_H_
20#define MIR_SCENE_TRUSTED_SESSION_CREATION_PARAMETERS_H_
21
22#include <sys/types.h>
23#include <vector>
24
25namespace mir
26{
27namespace scene
28{
29
30struct TrustSessionCreationParameters
31{
32 TrustSessionCreationParameters();
33
34 TrustSessionCreationParameters& set_base_process_id(pid_t process_id);
35
36 pid_t base_process_id;
37};
38
39bool operator==(const TrustSessionCreationParameters& lhs, const TrustSessionCreationParameters& rhs);
40bool operator!=(const TrustSessionCreationParameters& lhs, const TrustSessionCreationParameters& rhs);
41
42TrustSessionCreationParameters a_trust_session();
43}
44}
45
46#endif /* MIR_SCENE_TRUSTED_SESSION_CREATION_PARAMETERS_H_ */
047
=== added file 'include/server/mir/scene/trust_session_listener.h'
--- include/server/mir/scene/trust_session_listener.h 1970-01-01 00:00:00 +0000
+++ include/server/mir/scene/trust_session_listener.h 2014-05-09 12:26:43 +0000
@@ -0,0 +1,52 @@
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: Nick Dedekind <nick.dedekind@canonical.com>
17 */
18
19#ifndef MIR_SCENE_TRUST_SESSION_LISTENER_H_
20#define MIR_SCENE_TRUST_SESSION_LISTENER_H_
21
22#include <memory>
23
24namespace mir
25{
26namespace scene
27{
28class Session;
29class TrustSession;
30
31class TrustSessionListener
32{
33public:
34 virtual void starting(TrustSession const& trust_session) = 0;
35 virtual void stopping(TrustSession const& trust_session) = 0;
36
37 virtual void trusted_session_beginning(TrustSession& trust_session, Session const& session) = 0;
38 virtual void trusted_session_ending(TrustSession& trust_session, Session const& session) = 0;
39
40protected:
41 TrustSessionListener() = default;
42 virtual ~TrustSessionListener() = default;
43
44 TrustSessionListener(const TrustSessionListener&) = delete;
45 TrustSessionListener& operator=(const TrustSessionListener&) = delete;
46};
47
48}
49}
50
51
52#endif // MIR_SCENE_TRUST_SESSION_LISTENER_H_
053
=== modified file 'include/shared/mir_toolkit/client_types.h'
--- include/shared/mir_toolkit/client_types.h 2014-05-08 11:48:23 +0000
+++ include/shared/mir_toolkit/client_types.h 2014-05-09 12:26:43 +0000
@@ -46,6 +46,7 @@
46typedef struct MirConnection MirConnection;46typedef struct MirConnection MirConnection;
47typedef struct MirSurface MirSurface;47typedef struct MirSurface MirSurface;
48typedef struct MirScreencast MirScreencast;48typedef struct MirScreencast MirScreencast;
49typedef struct MirTrustSession MirTrustSession;
4950
50/**51/**
51 * Returned by asynchronous functions. Must not be free'd by52 * Returned by asynchronous functions. Must not be free'd by
@@ -104,6 +105,7 @@
104 MirConnection* connection, void* context);105 MirConnection* connection, void* context);
105106
106/**107/**
108<<<<<<< TREE
107 * Callback called when a request for client file descriptors completes109 * Callback called when a request for client file descriptors completes
108 * \param [in] connection The connection associated with the display change110 * \param [in] connection The connection associated with the display change
109 * \param [in] count The number of FDs allocated111 * \param [in] count The number of FDs allocated
@@ -117,6 +119,19 @@
117 MirConnection* connection, size_t count, int const* fds, void* context);119 MirConnection* connection, size_t count, int const* fds, void* context);
118120
119/**121/**
122=======
123 * Callback called when a request for client file descriptors completes
124 * \param [in] connection The connection associated with the display change
125 * \param [in] count The number of FDs allocated
126 * \param [in] fds Array of FDs
127 * \param [in,out] context The context provided by client
128 */
129
130typedef void (*mir_client_fd_callback)(
131 MirConnection* connection, size_t count, int const* fds, void* context);
132
133/**
134>>>>>>> MERGE-SOURCE
120 * MirBufferUsage specifies how a surface can and will be used. A "hardware"135 * MirBufferUsage specifies how a surface can and will be used. A "hardware"
121 * surface can be used for OpenGL accelerated rendering. A "software" surface136 * surface can be used for OpenGL accelerated rendering. A "software" surface
122 * is one that can be addressed in main memory and blitted to directly.137 * is one that can be addressed in main memory and blitted to directly.
@@ -319,6 +334,31 @@
319 */334 */
320typedef void (*mir_screencast_callback)(MirScreencast *screencast, void *client_context);335typedef void (*mir_screencast_callback)(MirScreencast *screencast, void *client_context);
321336
337/**
338 * Callback member of MirTrustSession for handling of trust sessions.
339 * \param [in] tps The trust session associated with the callback
340 * \param [in,out] context The context provided by the client
341 */
342typedef void (*mir_trust_session_callback)(MirTrustSession* tps, void* context);
343
344/**
345 * Callback member of MirTrustSession for adding trusted sessions
346 * \param [in] trusted_session The trust session associated with the callback
347 * \param [in] result The result of adding a trusted session
348 * \param [in,out] context The context provided by the client
349 */
350typedef void (*mir_trust_session_add_trusted_session_callback)(
351 MirTrustSession* trusted_session, MirTrustSessionAddTrustResult result, void* context);
352
353/**
354 * Callback member of MirTrustSession for handling of trust sessions events.
355 * \param [in] trusted_session The trust session associated with the callback
356 * \param [in] state The state of the trust session
357 * \param [in,out] context The context provided by the client
358 */
359typedef void (*mir_trust_session_event_callback)(
360 MirTrustSession* trusted_session, MirTrustSessionState state, void* context);
361
322#ifdef __cplusplus362#ifdef __cplusplus
323}363}
324/**@}*/364/**@}*/
325365
=== modified file 'include/shared/mir_toolkit/common.h'
--- include/shared/mir_toolkit/common.h 2014-03-06 06:05:17 +0000
+++ include/shared/mir_toolkit/common.h 2014-05-09 12:26:43 +0000
@@ -87,6 +87,23 @@
87 mir_power_mode_off /* Powered down. */87 mir_power_mode_off /* Powered down. */
88} MirPowerMode;88} MirPowerMode;
8989
90typedef enum MirTrustSessionState
91{
92 mir_trust_session_state_stopped = 0,
93 mir_trust_session_state_started
94} MirTrustSessionState;
95
96/**
97 * MirTrustSessionAddTrustResult specifies the result of a
98 * call to add an app id to a trust session
99 */
100typedef enum
101{
102 mir_trust_session_add_tust_failed,
103 mir_trust_session_add_tust_duplicate,
104 mir_trust_session_add_tust_succeeded
105} MirTrustSessionAddTrustResult;
106
90/**107/**
91 * The order of components in a format enum matches the108 * The order of components in a format enum matches the
92 * order of the components as they would be written in an109 * order of the components as they would be written in an
93110
=== modified file 'include/shared/mir_toolkit/event.h'
--- include/shared/mir_toolkit/event.h 2014-03-06 06:05:17 +0000
+++ include/shared/mir_toolkit/event.h 2014-05-09 12:26:43 +0000
@@ -40,7 +40,8 @@
40 mir_event_type_key,40 mir_event_type_key,
41 mir_event_type_motion,41 mir_event_type_motion,
42 mir_event_type_surface,42 mir_event_type_surface,
43 mir_event_type_resize43 mir_event_type_resize,
44 mir_event_type_trust_session_state_change
44} MirEventType;45} MirEventType;
4546
46typedef enum {47typedef enum {
@@ -204,6 +205,13 @@
204 int height;205 int height;
205} MirResizeEvent;206} MirResizeEvent;
206207
208typedef struct
209{
210 MirEventType type;
211
212 MirTrustSessionState new_state;
213} MirTrustSessionEvent;
214
207typedef union215typedef union
208{216{
209 MirEventType type;217 MirEventType type;
@@ -211,6 +219,7 @@
211 MirMotionEvent motion;219 MirMotionEvent motion;
212 MirSurfaceEvent surface;220 MirSurfaceEvent surface;
213 MirResizeEvent resize;221 MirResizeEvent resize;
222 MirTrustSessionEvent trust_session;
214} MirEvent;223} MirEvent;
215224
216#ifdef __cplusplus225#ifdef __cplusplus
217226
=== modified file 'include/test/mir_test/test_protobuf_client.h'
--- include/test/mir_test/test_protobuf_client.h 2013-08-28 03:41:48 +0000
+++ include/test/mir_test/test_protobuf_client.h 2014-05-09 12:26:43 +0000
@@ -21,6 +21,7 @@
21#define MIR_TEST_TEST_CLIENT_H_21#define MIR_TEST_TEST_CLIENT_H_
2222
23#include "mir_protobuf.pb.h"23#include "mir_protobuf.pb.h"
24#include "wait_condition.h"
2425
25#include <gmock/gmock.h>26#include <gmock/gmock.h>
2627
@@ -49,6 +50,10 @@
49 mir::protobuf::Connection connection;50 mir::protobuf::Connection connection;
50 mir::protobuf::DisplayConfiguration disp_config;51 mir::protobuf::DisplayConfiguration disp_config;
51 mir::protobuf::DisplayConfiguration disp_config_response;52 mir::protobuf::DisplayConfiguration disp_config_response;
53 mir::protobuf::TrustSessionParameters trust_session_parameters;
54 mir::protobuf::TrustedSession trusted_session;
55 mir::protobuf::TrustSession trust_session;
56 mir::protobuf::TrustSessionAddResult add_trust_result;
5257
53 MOCK_METHOD0(connect_done, void());58 MOCK_METHOD0(connect_done, void());
54 MOCK_METHOD0(create_surface_done, void());59 MOCK_METHOD0(create_surface_done, void());
@@ -57,6 +62,9 @@
57 MOCK_METHOD0(disconnect_done, void());62 MOCK_METHOD0(disconnect_done, void());
58 MOCK_METHOD0(drm_auth_magic_done, void());63 MOCK_METHOD0(drm_auth_magic_done, void());
59 MOCK_METHOD0(display_configure_done, void());64 MOCK_METHOD0(display_configure_done, void());
65 MOCK_METHOD0(trust_session_start_done, void());
66 MOCK_METHOD0(trust_session_add_trusted_session_done, void());
67 MOCK_METHOD0(trust_session_stop_done, void());
6068
61 void on_connect_done();69 void on_connect_done();
6270
@@ -94,6 +102,12 @@
94102
95 void wait_for_configure_display_done();103 void wait_for_configure_display_done();
96104
105 void wait_for_trust_session_start_done();
106
107 void wait_for_trust_session_add_trusted_session_done();
108
109 void wait_for_trust_session_stop_done();
110
97 const int maxwait;111 const int maxwait;
98 std::atomic<bool> connect_done_called;112 std::atomic<bool> connect_done_called;
99 std::atomic<bool> create_surface_called;113 std::atomic<bool> create_surface_called;
@@ -104,6 +118,10 @@
104 std::atomic<bool> configure_display_done_called;118 std::atomic<bool> configure_display_done_called;
105 std::atomic<bool> tfd_done_called;119 std::atomic<bool> tfd_done_called;
106120
121 WaitCondition wc_trust_session_start;
122 WaitCondition wc_trust_session_add;
123 WaitCondition wc_trust_session_stop;
124
107 std::atomic<int> connect_done_count;125 std::atomic<int> connect_done_count;
108 std::atomic<int> create_surface_done_count;126 std::atomic<int> create_surface_done_count;
109 std::atomic<int> disconnect_done_count;127 std::atomic<int> disconnect_done_count;
110128
=== modified file 'include/test/mir_test_doubles/mock_scene_session.h'
--- include/test/mir_test_doubles/mock_scene_session.h 2014-05-07 14:25:45 +0000
+++ include/test/mir_test_doubles/mock_scene_session.h 2014-05-09 12:26:43 +0000
@@ -52,6 +52,9 @@
52 MOCK_METHOD3(configure_surface, int(frontend::SurfaceId, MirSurfaceAttrib, int));52 MOCK_METHOD3(configure_surface, int(frontend::SurfaceId, MirSurfaceAttrib, int));
5353
54 MOCK_METHOD1(set_lifecycle_state, void(MirLifecycleState state));54 MOCK_METHOD1(set_lifecycle_state, void(MirLifecycleState state));
55
56 MOCK_METHOD0(begin_trust_session, void());
57 MOCK_METHOD0(end_trust_session, void());
55};58};
5659
57}60}
5861
=== modified file 'include/test/mir_test_doubles/mock_shell.h'
--- include/test/mir_test_doubles/mock_shell.h 2014-04-15 05:31:19 +0000
+++ include/test/mir_test_doubles/mock_shell.h 2014-05-09 12:26:43 +0000
@@ -22,6 +22,7 @@
22#include "mir/scene/surface_creation_parameters.h"22#include "mir/scene/surface_creation_parameters.h"
23#include "mir/frontend/shell.h"23#include "mir/frontend/shell.h"
24#include "mir/frontend/surface_id.h"24#include "mir/frontend/surface_id.h"
25#include "mir/scene/trust_session_creation_parameters.h"
2526
26#include <gmock/gmock.h>27#include <gmock/gmock.h>
2728
@@ -43,6 +44,14 @@
4344
44 MOCK_METHOD2(create_surface_for, frontend::SurfaceId(std::shared_ptr<frontend::Session> const&, scene::SurfaceCreationParameters const&));45 MOCK_METHOD2(create_surface_for, frontend::SurfaceId(std::shared_ptr<frontend::Session> const&, scene::SurfaceCreationParameters const&));
45 MOCK_METHOD1(handle_surface_created, void(std::shared_ptr<frontend::Session> const&));46 MOCK_METHOD1(handle_surface_created, void(std::shared_ptr<frontend::Session> const&));
47
48 MOCK_METHOD2(start_trust_session_for, std::shared_ptr<frontend::TrustSession>(
49 std::shared_ptr<frontend::Session> const&,
50 scene::TrustSessionCreationParameters const&));
51 MOCK_METHOD2(add_trusted_session_for, MirTrustSessionAddTrustResult(
52 std::shared_ptr<frontend::TrustSession> const&,
53 pid_t));
54 MOCK_METHOD1(stop_trust_session, void(std::shared_ptr<frontend::TrustSession> const&));
46};55};
4756
48}57}
4958
=== added file 'include/test/mir_test_doubles/mock_trust_session_listener.h'
--- include/test/mir_test_doubles/mock_trust_session_listener.h 1970-01-01 00:00:00 +0000
+++ include/test/mir_test_doubles/mock_trust_session_listener.h 2014-05-09 12:26:43 +0000
@@ -0,0 +1,48 @@
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: Nick Dedekind <nick.dedekind@canonical.com>
17 */
18
19#ifndef MIR_TEST_DOUBLES_MOCK_TRUST_SESSION_LISTENER_H_
20#define MIR_TEST_DOUBLES_MOCK_TRUST_SESSION_LISTENER_H_
21
22#include "mir/scene/trust_session_listener.h"
23
24#include <gmock/gmock.h>
25
26namespace mir
27{
28namespace test
29{
30namespace doubles
31{
32
33struct MockTrustSessionListener : public scene::TrustSessionListener
34{
35 virtual ~MockTrustSessionListener() noexcept(true) {}
36
37 MOCK_METHOD1(starting, void(scene::TrustSession const&));
38 MOCK_METHOD1(stopping, void(scene::TrustSession const&));
39
40 MOCK_METHOD2(trusted_session_beginning, void(scene::TrustSession&, scene::Session const&));
41 MOCK_METHOD2(trusted_session_ending, void(scene::TrustSession&, scene::Session const&));
42};
43
44}
45}
46} // namespace mir
47
48#endif // MIR_TEST_DOUBLES_MOCK_TRUST_SESSION_LISTENER_H_
049
=== added file 'include/test/mir_test_doubles/null_trust_session.h'
--- include/test/mir_test_doubles/null_trust_session.h 1970-01-01 00:00:00 +0000
+++ include/test/mir_test_doubles/null_trust_session.h 2014-05-09 12:26:43 +0000
@@ -0,0 +1,70 @@
1/*
2 * Copyright © 2013 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: Alexandros Frantzis <alexandros.frantzis@canonical.com>
17 */
18
19#ifndef MIR_TEST_DOUBLES_NULL_TRUST_SESSION_H_
20#define MIR_TEST_DOUBLES_NULL_TRUST_SESSION_H_
21
22#include "mir/scene/trust_session.h"
23
24namespace mir
25{
26namespace test
27{
28namespace doubles
29{
30
31class NullTrustSession : public scene::TrustSession
32{
33 MirTrustSessionState get_state() const override
34 {
35 return mir_trust_session_state_stopped;
36 }
37
38 void start() override
39 {
40 }
41
42 void stop() override
43 {
44 }
45
46 std::weak_ptr<scene::Session> get_trusted_helper() const override
47 {
48 return std::weak_ptr<scene::Session>();
49 }
50
51 bool add_trusted_child(std::shared_ptr<scene::Session> const&) override
52 {
53 return false;
54 }
55
56 void remove_trusted_child(std::shared_ptr<scene::Session> const&) override
57 {
58 }
59
60 void for_each_trusted_child(std::function<void(std::shared_ptr<scene::Session> const&)>,
61 bool) const override
62 {
63 }
64};
65
66}
67}
68}
69
70#endif /* MIR_TEST_DOUBLES_NULL_TRUST_SESSION_H_ */
071
=== modified file 'include/test/mir_test_doubles/stub_scene_session.h'
--- include/test/mir_test_doubles/stub_scene_session.h 2014-05-06 16:54:43 +0000
+++ include/test/mir_test_doubles/stub_scene_session.h 2014-05-09 12:26:43 +0000
@@ -76,6 +76,14 @@
76 void set_lifecycle_state(MirLifecycleState /*state*/)76 void set_lifecycle_state(MirLifecycleState /*state*/)
77 {77 {
78 }78 }
79
80 void begin_trust_session() override
81 {
82 }
83
84 void end_trust_session() override
85 {
86 }
79};87};
8088
81}89}
8290
=== modified file 'include/test/mir_test_doubles/stub_session.h'
--- include/test/mir_test_doubles/stub_session.h 2014-05-06 16:54:43 +0000
+++ include/test/mir_test_doubles/stub_session.h 2014-05-09 12:26:43 +0000
@@ -41,6 +41,10 @@
41 {41 {
42 return std::shared_ptr<frontend::Surface>();42 return std::shared_ptr<frontend::Surface>();
43 }43 }
44 pid_t process_id() const override
45 {
46 return 0;
47 }
44 std::string name() const override48 std::string name() const override
45 {49 {
46 return std::string();50 return std::string();
4751
=== modified file 'include/test/mir_test_doubles/stub_shell.h'
--- include/test/mir_test_doubles/stub_shell.h 2014-04-15 05:31:19 +0000
+++ include/test/mir_test_doubles/stub_shell.h 2014-05-09 12:26:43 +0000
@@ -49,6 +49,21 @@
49 void handle_surface_created(std::shared_ptr<frontend::Session> const& /* session */) override49 void handle_surface_created(std::shared_ptr<frontend::Session> const& /* session */) override
50 {50 {
51 }51 }
52 std::shared_ptr<frontend::TrustSession> start_trust_session_for(std::shared_ptr<frontend::Session> const& /* session */,
53 scene::TrustSessionCreationParameters const& /* params */)
54 {
55 return std::shared_ptr<frontend::TrustSession>();
56 }
57 MirTrustSessionAddTrustResult add_trusted_session_for(
58 std::shared_ptr<frontend::TrustSession> const& /* trust_session */,
59 pid_t /* session_pid */)
60 {
61 return mir_trust_session_add_tust_failed;
62 }
63 void stop_trust_session(std::shared_ptr<frontend::TrustSession> const& /* trust_session */)
64 {
65 }
66
52 std::shared_ptr<StubSession> const stub_session;67 std::shared_ptr<StubSession> const stub_session;
53};68};
5469
5570
=== modified file 'src/client/CMakeLists.txt'
--- src/client/CMakeLists.txt 2014-03-31 14:36:08 +0000
+++ src/client/CMakeLists.txt 2014-05-09 12:26:43 +0000
@@ -47,6 +47,9 @@
47 private.cpp47 private.cpp
48 mir_screencast.cpp48 mir_screencast.cpp
49 mir_screencast_api.cpp49 mir_screencast_api.cpp
50 mir_trust_session.cpp
51 mir_trust_session_api.cpp
52 event_distributor.cpp
50)53)
5154
52add_library(55add_library(
@@ -81,7 +84,7 @@
81 mirclientlttngstatic84 mirclientlttngstatic
8285
83 ${MIR_COMMON_PLATFORM_LIBRARIES}86 ${MIR_COMMON_PLATFORM_LIBRARIES}
84 87
85 3rd_party88 3rd_party
86)89)
8790
8891
=== modified file 'src/client/connection_configuration.h'
--- src/client/connection_configuration.h 2014-03-06 06:05:17 +0000
+++ src/client/connection_configuration.h 2014-05-09 12:26:43 +0000
@@ -47,6 +47,7 @@
47class ClientPlatformFactory;47class ClientPlatformFactory;
48class DisplayConfiguration;48class DisplayConfiguration;
49class LifecycleControl;49class LifecycleControl;
50class EventDistributor;
5051
51class ConnectionConfiguration52class ConnectionConfiguration
52{53{
@@ -60,6 +61,7 @@
60 virtual std::shared_ptr<input::receiver::InputPlatform> the_input_platform() = 0;61 virtual std::shared_ptr<input::receiver::InputPlatform> the_input_platform() = 0;
61 virtual std::shared_ptr<DisplayConfiguration> the_display_configuration() = 0;62 virtual std::shared_ptr<DisplayConfiguration> the_display_configuration() = 0;
62 virtual std::shared_ptr<LifecycleControl> the_lifecycle_control() = 0;63 virtual std::shared_ptr<LifecycleControl> the_lifecycle_control() = 0;
64 virtual std::shared_ptr<EventDistributor> the_event_distributor() = 0;
6365
64protected:66protected:
65 ConnectionConfiguration() = default;67 ConnectionConfiguration() = default;
6668
=== modified file 'src/client/default_connection_configuration.cpp'
--- src/client/default_connection_configuration.cpp 2014-03-26 05:48:59 +0000
+++ src/client/default_connection_configuration.cpp 2014-05-09 12:26:43 +0000
@@ -32,6 +32,7 @@
32#include "lifecycle_control.h"32#include "lifecycle_control.h"
33#include "mir/shared_library.h"33#include "mir/shared_library.h"
34#include "client_platform_factory.h"34#include "client_platform_factory.h"
35#include "event_distributor.h"
3536
36namespace mcl = mir::client;37namespace mcl = mir::client;
3738
@@ -81,7 +82,7 @@
81 [this]82 [this]
82 {83 {
83 return mcl::rpc::make_rpc_channel(84 return mcl::rpc::make_rpc_channel(
84 the_socket_file(), the_surface_map(), the_display_configuration(), the_rpc_report(), the_lifecycle_control());85 the_socket_file(), the_surface_map(), the_display_configuration(), the_rpc_report(), the_lifecycle_control(), the_event_distributor());
85 });86 });
86}87}
8788
@@ -182,3 +183,12 @@
182 return std::make_shared<mcl::LifecycleControl>();183 return std::make_shared<mcl::LifecycleControl>();
183 });184 });
184}185}
186
187std::shared_ptr<mcl::EventDistributor> mcl::DefaultConnectionConfiguration::the_event_distributor()
188{
189 return event_distributor(
190 []
191 {
192 return std::make_shared<mcl::EventDistributor>();
193 });
194}
185195
=== modified file 'src/client/default_connection_configuration.h'
--- src/client/default_connection_configuration.h 2014-03-06 06:05:17 +0000
+++ src/client/default_connection_configuration.h 2014-05-09 12:26:43 +0000
@@ -54,6 +54,7 @@
54 std::shared_ptr<input::receiver::InputPlatform> the_input_platform();54 std::shared_ptr<input::receiver::InputPlatform> the_input_platform();
55 std::shared_ptr<DisplayConfiguration> the_display_configuration();55 std::shared_ptr<DisplayConfiguration> the_display_configuration();
56 std::shared_ptr<LifecycleControl> the_lifecycle_control();56 std::shared_ptr<LifecycleControl> the_lifecycle_control();
57 std::shared_ptr<EventDistributor> the_event_distributor();
5758
58 virtual std::string the_socket_file();59 virtual std::string the_socket_file();
59 virtual std::shared_ptr<rpc::RpcReport> the_rpc_report();60 virtual std::shared_ptr<rpc::RpcReport> the_rpc_report();
@@ -67,6 +68,7 @@
67 CachedPtr<ConnectionSurfaceMap> surface_map;68 CachedPtr<ConnectionSurfaceMap> surface_map;
68 CachedPtr<DisplayConfiguration> display_configuration;69 CachedPtr<DisplayConfiguration> display_configuration;
69 CachedPtr<LifecycleControl> lifecycle_control;70 CachedPtr<LifecycleControl> lifecycle_control;
71 CachedPtr<EventDistributor> event_distributor;
7072
71 CachedPtr<rpc::RpcReport> rpc_report;73 CachedPtr<rpc::RpcReport> rpc_report;
72 CachedPtr<input::receiver::InputReceiverReport> input_receiver_report;74 CachedPtr<input::receiver::InputReceiverReport> input_receiver_report;
7375
=== added file 'src/client/event_distributor.cpp'
--- src/client/event_distributor.cpp 1970-01-01 00:00:00 +0000
+++ src/client/event_distributor.cpp 2014-05-09 12:26:43 +0000
@@ -0,0 +1,57 @@
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 Lesser 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 Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Nick Dedekind <nick.dedekind@gmail.com>
17 */
18
19#include "event_distributor.h"
20
21namespace mcl = mir::client;
22
23mcl::EventDistributor::EventDistributor() :
24 next_fn_id(0)
25{
26}
27
28int mcl::EventDistributor::register_event_handler(std::function<void(MirEvent const&)> const& fn)
29{
30 std::lock_guard<decltype(mutex)> lock(mutex);
31
32 int id = next_id();
33 event_handlers[id] = fn;
34 return id;
35}
36
37void mcl::EventDistributor::unregister_event_handler(int id)
38{
39 std::lock_guard<decltype(mutex)> lock(mutex);
40
41 event_handlers.erase(id);
42}
43
44void mcl::EventDistributor::handle_event(MirEvent const& event)
45{
46 std::lock_guard<decltype(mutex)> lock(mutex);
47
48 for (auto const& fn : event_handlers)
49 {
50 fn.second(event);
51 }
52}
53
54int mcl::EventDistributor::next_id()
55{
56 return ++next_fn_id;
57}
0\ No newline at end of file58\ No newline at end of file
159
=== added file 'src/client/event_distributor.h'
--- src/client/event_distributor.h 1970-01-01 00:00:00 +0000
+++ src/client/event_distributor.h 2014-05-09 12:26:43 +0000
@@ -0,0 +1,52 @@
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 Lesser 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 Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Nick Dedekind <nick.dedekind@gmail.com>
17 */
18
19#ifndef MIR_CLIENT_EVENT_DISTRIBUTOR_H
20
21#include "mir_toolkit/event.h"
22
23#include <functional>
24#include <mutex>
25#include <map>
26
27namespace mir
28{
29namespace client
30{
31class EventDistributor
32{
33public:
34 EventDistributor();
35 ~EventDistributor() = default;
36
37 int register_event_handler(std::function<void(MirEvent const&)> const&);
38 void unregister_event_handler(int id);
39
40 void handle_event(MirEvent const& event);
41
42private:
43 int next_id();
44
45 mutable std::mutex mutex;
46 std::map<int, std::function<void(MirEvent const&)>> event_handlers;
47 int next_fn_id;
48};
49}
50}
51
52#endif /* MIR_CLIENT_EVENT_DISTRIBUTOR_H */
053
=== modified file 'src/client/mir_connection.cpp'
--- src/client/mir_connection.cpp 2014-05-07 13:51:38 +0000
+++ src/client/mir_connection.cpp 2014-05-09 12:26:43 +0000
@@ -18,6 +18,7 @@
1818
19#include "mir_connection.h"19#include "mir_connection.h"
20#include "mir_surface.h"20#include "mir_surface.h"
21#include "mir_trust_session.h"
21#include "client_platform.h"22#include "client_platform.h"
22#include "client_platform_factory.h"23#include "client_platform_factory.h"
23#include "rpc/mir_basic_rpc_channel.h"24#include "rpc/mir_basic_rpc_channel.h"
@@ -82,7 +83,8 @@
82 input_platform(conf.the_input_platform()),83 input_platform(conf.the_input_platform()),
83 display_configuration(conf.the_display_configuration()),84 display_configuration(conf.the_display_configuration()),
84 lifecycle_control(conf.the_lifecycle_control()),85 lifecycle_control(conf.the_lifecycle_control()),
85 surface_map(conf.the_surface_map())86 surface_map(conf.the_surface_map()),
87 event_distributor(conf.the_event_distributor())
86{88{
87 connect_result.set_error("connect not called");89 connect_result.set_error("connect not called");
88 {90 {
@@ -193,6 +195,11 @@
193 return new_wait_handle;195 return new_wait_handle;
194}196}
195197
198MirTrustSession* MirConnection::create_trust_session()
199{
200 return new MirTrustSession(display_server(), event_distributor);
201}
202
196namespace203namespace
197{204{
198void default_lifecycle_event_handler(MirLifecycleState transition)205void default_lifecycle_event_handler(MirLifecycleState transition)
@@ -522,6 +529,6 @@
522}529}
523530
524mir::protobuf::DisplayServer& MirConnection::display_server()531mir::protobuf::DisplayServer& MirConnection::display_server()
525{ 532{
526 return server;533 return server;
527}534}
528535
=== modified file 'src/client/mir_connection.h'
--- src/client/mir_connection.h 2014-05-07 13:51:38 +0000
+++ src/client/mir_connection.h 2014-05-09 12:26:43 +0000
@@ -45,6 +45,7 @@
45class ConnectionSurfaceMap;45class ConnectionSurfaceMap;
46class DisplayConfiguration;46class DisplayConfiguration;
47class LifecycleControl;47class LifecycleControl;
48class EventDistributor;
4849
49namespace rpc50namespace rpc
50{51{
@@ -86,6 +87,8 @@
86 mir_surface_callback callback,87 mir_surface_callback callback,
87 void *context);88 void *context);
8889
90 MirTrustSession* create_trust_session();
91
89 char const * get_error_message();92 char const * get_error_message();
9093
91 MirWaitHandle* connect(94 MirWaitHandle* connect(
@@ -172,6 +175,8 @@
172175
173 std::shared_ptr<mir::client::ConnectionSurfaceMap> const surface_map;176 std::shared_ptr<mir::client::ConnectionSurfaceMap> const surface_map;
174177
178 std::shared_ptr<mir::client::EventDistributor> const event_distributor;
179
175 std::vector<int> extra_platform_data;180 std::vector<int> extra_platform_data;
176181
177 struct SurfaceRelease;182 struct SurfaceRelease;
178183
=== added file 'src/client/mir_trust_session.cpp'
--- src/client/mir_trust_session.cpp 1970-01-01 00:00:00 +0000
+++ src/client/mir_trust_session.cpp 2014-05-09 12:26:43 +0000
@@ -0,0 +1,182 @@
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 Lesser 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 Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Nick Dedekind <nick.dedekind@gmail.com>
17 */
18
19#include "mir_trust_session.h"
20#include "event_distributor.h"
21
22namespace mp = mir::protobuf;
23namespace mcl = mir::client;
24
25MirTrustSession::MirTrustSession(
26 mp::DisplayServer& server,
27 std::shared_ptr<mcl::EventDistributor> const& event_distributor)
28 : server(server),
29 event_distributor(event_distributor),
30 state(mir_trust_session_state_stopped)
31{
32 event_distributor_fn_id = event_distributor->register_event_handler(
33 [this](MirEvent const& event)
34 {
35 if (event.type != mir_event_type_trust_session_state_change)
36 return;
37
38 std::lock_guard<decltype(mutex_event_handler)> lock(mutex_event_handler);
39
40 set_state(event.trust_session.new_state);
41 if (handle_trust_session_event) {
42 handle_trust_session_event(event.trust_session.new_state);
43 }
44 }
45 );
46}
47
48MirTrustSession::~MirTrustSession()
49{
50 event_distributor->unregister_event_handler(event_distributor_fn_id);
51}
52
53MirTrustSessionState MirTrustSession::get_state() const
54{
55 std::lock_guard<decltype(mutex)> lock(mutex);
56
57 return state;
58}
59
60void MirTrustSession::set_state(MirTrustSessionState new_state)
61{
62 std::lock_guard<decltype(mutex)> lock(mutex);
63
64 state = new_state;
65}
66
67MirWaitHandle* MirTrustSession::start(pid_t pid, mir_trust_session_callback callback, void* context)
68{
69 mir::protobuf::TrustSessionParameters parameters;
70 parameters.mutable_base_trusted_session()->set_pid(pid);
71
72 server.start_trust_session(
73 0,
74 &parameters,
75 &session,
76 google::protobuf::NewCallback(this, &MirTrustSession::done_start,
77 callback, context));
78
79 return &start_wait_handle;
80}
81
82MirWaitHandle* MirTrustSession::stop(mir_trust_session_callback callback, void* context)
83{
84 server.stop_trust_session(
85 0,
86 &protobuf_void,
87 &protobuf_void,
88 google::protobuf::NewCallback(this, &MirTrustSession::done_stop,
89 callback, context));
90
91 return &stop_wait_handle;
92}
93
94MirWaitHandle* MirTrustSession::add_trusted_session(pid_t pid,
95 mir_trust_session_add_trusted_session_callback callback,
96 void* context)
97{
98 mir::protobuf::TrustedSession trusted_session;
99 trusted_session.set_pid(pid);
100
101 server.add_trusted_session(
102 0,
103 &trusted_session,
104 &add_result,
105 google::protobuf::NewCallback(this, &MirTrustSession::done_add_trusted_session,
106 callback, context));
107
108 return &add_result_wait_handle;
109}
110
111void MirTrustSession::register_trust_session_event_callback(
112 mir_trust_session_event_callback callback,
113 void* context)
114{
115 std::lock_guard<decltype(mutex_event_handler)> lock(mutex_event_handler);
116
117 handle_trust_session_event =
118 [this, callback, context](MirTrustSessionState new_state)
119 {
120 callback(this, new_state, context);
121 };
122}
123
124void MirTrustSession::done_start(mir_trust_session_callback callback, void* context)
125{
126 std::string error;
127 MirTrustSessionState new_state = mir_trust_session_state_stopped;
128 {
129 std::lock_guard<decltype(mutex)> lock(mutex);
130
131 if (session.has_state())
132 new_state = (MirTrustSessionState)session.state();
133
134 error = session.error();
135 }
136 set_error_message(error);
137 set_state(new_state);
138
139 callback(this, context);
140 start_wait_handle.result_received();
141}
142
143void MirTrustSession::done_stop(mir_trust_session_callback callback, void* context)
144{
145 set_state(mir_trust_session_state_stopped);
146
147 callback(this, context);
148 stop_wait_handle.result_received();
149}
150
151void MirTrustSession::done_add_trusted_session(mir_trust_session_add_trusted_session_callback callback, void* context)
152{
153 MirTrustSessionAddTrustResult result = static_cast<MirTrustSessionAddTrustResult>(add_result.result());
154 if (add_result.has_error())
155 {
156 set_error_message(add_result.error());
157 result = mir_trust_session_add_tust_failed;
158 }
159 callback(this, result, context);
160 add_result_wait_handle.result_received();
161}
162
163char const* MirTrustSession::get_error_message()
164{
165 std::lock_guard<decltype(mutex)> lock(mutex);
166
167 if (session.has_error())
168 {
169 return session.error().c_str();
170 }
171 else
172 {
173 return error_message.c_str();
174 }
175}
176
177void MirTrustSession::set_error_message(std::string const& error)
178{
179 std::lock_guard<decltype(mutex)> lock(mutex);
180
181 error_message = error;
182}
0183
=== added file 'src/client/mir_trust_session.h'
--- src/client/mir_trust_session.h 1970-01-01 00:00:00 +0000
+++ src/client/mir_trust_session.h 2014-05-09 12:26:43 +0000
@@ -0,0 +1,88 @@
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 Lesser 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 Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Nick Dedekind <nick.dedekind@gmail.com>
17 */
18
19#ifndef MIR_CLIENT_MIR_TRUST_SESSION_H_
20#define MIR_CLIENT_MIR_TRUST_SESSION_H_
21
22#include "mir_toolkit/mir_client_library.h"
23
24#include "mir_protobuf.pb.h"
25#include "mir_wait_handle.h"
26
27#include <mutex>
28#include <memory>
29#include <atomic>
30
31namespace mir
32{
33/// The client-side library implementation namespace
34namespace client
35{
36class EventDistributor;
37}
38}
39
40struct MirTrustSession
41{
42public:
43 MirTrustSession(mir::protobuf::DisplayServer& server,
44 std::shared_ptr<mir::client::EventDistributor> const& event_distributor);
45
46 ~MirTrustSession();
47
48 MirTrustSession(MirTrustSession const&) = delete;
49 MirTrustSession& operator=(MirTrustSession const&) = delete;
50
51 MirWaitHandle* start(pid_t pid, mir_trust_session_callback callback, void* context);
52 MirWaitHandle* stop(mir_trust_session_callback callback, void* context);
53 MirWaitHandle* add_trusted_session(pid_t pid, mir_trust_session_add_trusted_session_callback callback, void* context);
54
55 void register_trust_session_event_callback(mir_trust_session_event_callback callback, void* context);
56
57 char const* get_error_message();
58 void set_error_message(std::string const& error);
59
60 MirTrustSessionState get_state() const;
61 void set_state(MirTrustSessionState new_state);
62
63private:
64 mutable std::mutex mutex; // Protects members of *this
65 mutable std::mutex mutex_event_handler; // Need another mutex for callback access to members
66
67 mir::protobuf::DisplayServer& server;
68 mir::protobuf::TrustSession session;
69 mir::protobuf::TrustSessionAddResult add_result;
70 mir::protobuf::Void protobuf_void;
71 std::string error_message;
72
73 std::shared_ptr<mir::client::EventDistributor> const event_distributor;
74 std::function<void(MirTrustSessionState)> handle_trust_session_event;
75 int event_distributor_fn_id;
76
77 MirWaitHandle start_wait_handle;
78 MirWaitHandle stop_wait_handle;
79 MirWaitHandle add_result_wait_handle;
80 MirTrustSessionState state;
81
82 void done_start(mir_trust_session_callback callback, void* context);
83 void done_stop(mir_trust_session_callback callback, void* context);
84 void done_add_trusted_session(mir_trust_session_add_trusted_session_callback callback, void* context);
85};
86
87#endif /* MIR_CLIENT_MIR_TRUST_SESSION_H_ */
88
089
=== added file 'src/client/mir_trust_session_api.cpp'
--- src/client/mir_trust_session_api.cpp 1970-01-01 00:00:00 +0000
+++ src/client/mir_trust_session_api.cpp 2014-05-09 12:26:43 +0000
@@ -0,0 +1,133 @@
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 Lesser 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 Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include "mir_toolkit/mir_trust_session.h"
18#include "mir_trust_session.h"
19#include "mir_connection.h"
20
21#include <stdexcept>
22#include <boost/throw_exception.hpp>
23
24namespace
25{
26
27// assign_result is compatible with all 2-parameter callbacks
28void assign_result(void *result, void **context)
29{
30 if (context)
31 *context = result;
32}
33
34void add_trusted_session_callback(MirTrustSession*,
35 MirTrustSessionAddTrustResult result,
36 void* context)
37{
38 if (context)
39 *(MirTrustSessionAddTrustResult*)context = result;
40}
41
42}
43
44MirWaitHandle *mir_connection_start_trust_session(MirConnection* connection,
45 pid_t base_session_pid,
46 mir_trust_session_callback start_callback,
47 mir_trust_session_event_callback event_callback,
48 void* context)
49{
50 auto trust_session = connection->create_trust_session();
51 if (event_callback)
52 trust_session->register_trust_session_event_callback(event_callback, context);
53 return trust_session->start(base_session_pid, start_callback, context);
54}
55
56MirTrustSession *mir_connection_start_trust_session_sync(MirConnection* connection,
57 pid_t base_session_pid,
58 mir_trust_session_event_callback event_callback,
59 void* context)
60{
61 auto trust_session = connection->create_trust_session();
62 if (event_callback)
63 trust_session->register_trust_session_event_callback(event_callback, context);
64
65 mir_wait_for(trust_session->start(base_session_pid,
66 reinterpret_cast<mir_trust_session_callback>(assign_result),
67 nullptr));
68 return trust_session;
69}
70
71MirTrustSession* mir_connection_create_trust_session(MirConnection* connection)
72{
73 return connection->create_trust_session();
74}
75
76MirWaitHandle *mir_trust_session_add_trusted_session(MirTrustSession *trust_session,
77 pid_t session_pid,
78 mir_trust_session_add_trusted_session_callback callback,
79 void* context)
80{
81 try
82 {
83 return trust_session->add_trusted_session(session_pid, callback, context);
84 }
85 catch (std::exception const&)
86 {
87 // TODO callback with an error
88 return nullptr;
89 }
90}
91
92MirTrustSessionAddTrustResult mir_trust_session_add_trusted_session_sync(MirTrustSession *trust_session, pid_t base_session_pid)
93{
94 MirTrustSessionAddTrustResult result;
95 mir_wait_for(mir_trust_session_add_trusted_session(trust_session,
96 base_session_pid,
97 add_trusted_session_callback,
98 &result));
99 return result;
100}
101
102MirWaitHandle *mir_trust_session_stop(MirTrustSession *trust_session,
103 mir_trust_session_callback callback,
104 void* context)
105{
106 try
107 {
108 return trust_session->stop(callback, context);
109 }
110 catch (std::exception const&)
111 {
112 // TODO callback with an error
113 return nullptr;
114 }
115}
116
117MirBool mir_trust_session_stop_sync(MirTrustSession *trust_session)
118{
119 mir_wait_for(mir_trust_session_stop(trust_session,
120 reinterpret_cast<mir_trust_session_callback>(assign_result),
121 NULL));
122 return trust_session->get_state() == mir_trust_session_state_stopped ? mir_true : mir_false;
123}
124
125MirTrustSessionState mir_trust_session_get_state(MirTrustSession *trust_session)
126{
127 return trust_session->get_state();
128}
129
130void mir_trust_session_release(MirTrustSession* trust_session)
131{
132 delete trust_session;
133}
0134
=== modified file 'src/client/rpc/make_rpc_channel.h'
--- src/client/rpc/make_rpc_channel.h 2014-03-06 06:05:17 +0000
+++ src/client/rpc/make_rpc_channel.h 2014-05-09 12:26:43 +0000
@@ -29,6 +29,7 @@
29class SurfaceMap;29class SurfaceMap;
30class DisplayConfiguration;30class DisplayConfiguration;
31class LifecycleControl;31class LifecycleControl;
32class EventDistributor;
3233
33namespace rpc34namespace rpc
34{35{
@@ -39,7 +40,8 @@
39 std::shared_ptr<SurfaceMap> const& map,40 std::shared_ptr<SurfaceMap> const& map,
40 std::shared_ptr<DisplayConfiguration> const& disp_conf,41 std::shared_ptr<DisplayConfiguration> const& disp_conf,
41 std::shared_ptr<RpcReport> const& rpc_report,42 std::shared_ptr<RpcReport> const& rpc_report,
42 std::shared_ptr<LifecycleControl> const& lifecycle_control);43 std::shared_ptr<LifecycleControl> const& lifecycle_control,
44 std::shared_ptr<EventDistributor> const& event_distributor);
43}45}
44}46}
45}47}
4648
=== modified file 'src/client/rpc/make_socket_rpc_channel.cpp'
--- src/client/rpc/make_socket_rpc_channel.cpp 2014-03-06 06:05:17 +0000
+++ src/client/rpc/make_socket_rpc_channel.cpp 2014-05-09 12:26:43 +0000
@@ -44,13 +44,14 @@
44 std::shared_ptr<mcl::SurfaceMap> const& map,44 std::shared_ptr<mcl::SurfaceMap> const& map,
45 std::shared_ptr<mcl::DisplayConfiguration> const& disp_conf,45 std::shared_ptr<mcl::DisplayConfiguration> const& disp_conf,
46 std::shared_ptr<RpcReport> const& rpc_report,46 std::shared_ptr<RpcReport> const& rpc_report,
47 std::shared_ptr<mcl::LifecycleControl> const& lifecycle_control)47 std::shared_ptr<mcl::LifecycleControl> const& lifecycle_control,
48 std::shared_ptr<mcl::EventDistributor> const& event_distributor)
48{49{
49 if (fd_prefix.is_start_of(name))50 if (fd_prefix.is_start_of(name))
50 {51 {
51 auto const fd = atoi(name.c_str()+fd_prefix.size);52 auto const fd = atoi(name.c_str()+fd_prefix.size);
52 return std::make_shared<MirSocketRpcChannel>(fd, map, disp_conf, rpc_report, lifecycle_control);53 return std::make_shared<MirSocketRpcChannel>(fd, map, disp_conf, rpc_report, lifecycle_control, event_distributor);
53 }54 }
5455
55 return std::make_shared<MirSocketRpcChannel>(name, map, disp_conf, rpc_report, lifecycle_control);56 return std::make_shared<MirSocketRpcChannel>(name, map, disp_conf, rpc_report, lifecycle_control, event_distributor);
56}57}
5758
=== modified file 'src/client/rpc/mir_socket_rpc_channel.cpp'
--- src/client/rpc/mir_socket_rpc_channel.cpp 2014-05-06 14:53:36 +0000
+++ src/client/rpc/mir_socket_rpc_channel.cpp 2014-05-09 12:26:43 +0000
@@ -24,6 +24,7 @@
24#include "../mir_surface.h"24#include "../mir_surface.h"
25#include "../display_configuration.h"25#include "../display_configuration.h"
26#include "../lifecycle_control.h"26#include "../lifecycle_control.h"
27#include "../event_distributor.h"
2728
28#include "mir_protobuf.pb.h" // For Buffer frig29#include "mir_protobuf.pb.h" // For Buffer frig
29#include "mir_protobuf_wire.pb.h"30#include "mir_protobuf_wire.pb.h"
@@ -49,7 +50,8 @@
49 std::shared_ptr<mcl::SurfaceMap> const& surface_map,50 std::shared_ptr<mcl::SurfaceMap> const& surface_map,
50 std::shared_ptr<DisplayConfiguration> const& disp_config,51 std::shared_ptr<DisplayConfiguration> const& disp_config,
51 std::shared_ptr<RpcReport> const& rpc_report,52 std::shared_ptr<RpcReport> const& rpc_report,
52 std::shared_ptr<LifecycleControl> const& lifecycle_control) :53 std::shared_ptr<LifecycleControl> const& lifecycle_control,
54 std::shared_ptr<EventDistributor> const& event_distributor) :
53 rpc_report(rpc_report),55 rpc_report(rpc_report),
54 pending_calls(rpc_report),56 pending_calls(rpc_report),
55 work(io_service),57 work(io_service),
@@ -57,6 +59,7 @@
57 surface_map(surface_map),59 surface_map(surface_map),
58 display_configuration(disp_config),60 display_configuration(disp_config),
59 lifecycle_control(lifecycle_control),61 lifecycle_control(lifecycle_control),
62 event_distributor(event_distributor),
60 disconnected(false)63 disconnected(false)
61{64{
62 socket.connect(endpoint);65 socket.connect(endpoint);
@@ -68,7 +71,8 @@
68 std::shared_ptr<mcl::SurfaceMap> const& surface_map,71 std::shared_ptr<mcl::SurfaceMap> const& surface_map,
69 std::shared_ptr<DisplayConfiguration> const& disp_config,72 std::shared_ptr<DisplayConfiguration> const& disp_config,
70 std::shared_ptr<RpcReport> const& rpc_report,73 std::shared_ptr<RpcReport> const& rpc_report,
71 std::shared_ptr<LifecycleControl> const& lifecycle_control) :74 std::shared_ptr<LifecycleControl> const& lifecycle_control,
75 std::shared_ptr<EventDistributor> const& event_distributor) :
72 rpc_report(rpc_report),76 rpc_report(rpc_report),
73 pending_calls(rpc_report),77 pending_calls(rpc_report),
74 work(io_service),78 work(io_service),
@@ -76,6 +80,7 @@
76 surface_map(surface_map),80 surface_map(surface_map),
77 display_configuration(disp_config),81 display_configuration(disp_config),
78 lifecycle_control(lifecycle_control),82 lifecycle_control(lifecycle_control),
83 event_distributor(event_distributor),
79 disconnected(false)84 disconnected(false)
80{85{
81 socket.assign(boost::asio::local::stream_protocol(), native_socket);86 socket.assign(boost::asio::local::stream_protocol(), native_socket);
@@ -405,11 +410,25 @@
405410
406 rpc_report->event_parsing_succeeded(e);411 rpc_report->event_parsing_succeeded(e);
407412
408 surface_map->with_surface_do(e.surface.id,413 event_distributor->handle_event(e);
409 [&e](MirSurface* surface)414
410 {415 // todo - surfaces should register with the event distributor.
411 surface->handle_event(e);416 if (e.type == mir_event_type_surface)
412 });417 {
418 surface_map->with_surface_do(e.surface.id,
419 [&e](MirSurface* surface)
420 {
421 surface->handle_event(e);
422 });
423 }
424 else if (e.type == mir_event_type_resize)
425 {
426 surface_map->with_surface_do(e.resize.surface_id,
427 [&e](MirSurface* surface)
428 {
429 surface->handle_event(e);
430 });
431 }
413 }432 }
414 else433 else
415 {434 {
416435
=== modified file 'src/client/rpc/mir_socket_rpc_channel.h'
--- src/client/rpc/mir_socket_rpc_channel.h 2014-05-05 03:36:45 +0000
+++ src/client/rpc/mir_socket_rpc_channel.h 2014-05-09 12:26:43 +0000
@@ -44,6 +44,7 @@
44class DisplayConfiguration;44class DisplayConfiguration;
45class SurfaceMap;45class SurfaceMap;
46class LifecycleControl;46class LifecycleControl;
47class EventDistributor;
47namespace rpc48namespace rpc
48{49{
4950
@@ -56,13 +57,15 @@
56 std::shared_ptr<SurfaceMap> const& surface_map,57 std::shared_ptr<SurfaceMap> const& surface_map,
57 std::shared_ptr<DisplayConfiguration> const& disp_config,58 std::shared_ptr<DisplayConfiguration> const& disp_config,
58 std::shared_ptr<RpcReport> const& rpc_report,59 std::shared_ptr<RpcReport> const& rpc_report,
59 std::shared_ptr<LifecycleControl> const& lifecycle_control);60 std::shared_ptr<LifecycleControl> const& lifecycle_control,
61 std::shared_ptr<EventDistributor> const& event_distributor);
6062
61 MirSocketRpcChannel(int native_socket,63 MirSocketRpcChannel(int native_socket,
62 std::shared_ptr<SurfaceMap> const& surface_map,64 std::shared_ptr<SurfaceMap> const& surface_map,
63 std::shared_ptr<DisplayConfiguration> const& disp_config,65 std::shared_ptr<DisplayConfiguration> const& disp_config,
64 std::shared_ptr<RpcReport> const& rpc_report,66 std::shared_ptr<RpcReport> const& rpc_report,
65 std::shared_ptr<LifecycleControl> const& lifecycle_control);67 std::shared_ptr<LifecycleControl> const& lifecycle_control,
68 std::shared_ptr<EventDistributor> const& event_distributor);
66 ~MirSocketRpcChannel();69 ~MirSocketRpcChannel();
6770
68private:71private:
@@ -102,6 +105,7 @@
102 std::shared_ptr<SurfaceMap> surface_map;105 std::shared_ptr<SurfaceMap> surface_map;
103 std::shared_ptr<DisplayConfiguration> display_configuration;106 std::shared_ptr<DisplayConfiguration> display_configuration;
104 std::shared_ptr<LifecycleControl> lifecycle_control;107 std::shared_ptr<LifecycleControl> lifecycle_control;
108 std::shared_ptr<EventDistributor> event_distributor;
105 std::atomic<bool> disconnected;109 std::atomic<bool> disconnected;
106};110};
107111
108112
=== modified file 'src/server/default_server_configuration.cpp'
--- src/server/default_server_configuration.cpp 2014-05-05 03:36:45 +0000
+++ src/server/default_server_configuration.cpp 2014-05-09 12:26:43 +0000
@@ -36,6 +36,7 @@
36#include "mir/time/high_resolution_clock.h"36#include "mir/time/high_resolution_clock.h"
37#include "mir/geometry/rectangles.h"37#include "mir/geometry/rectangles.h"
38#include "mir/default_configuration.h"38#include "mir/default_configuration.h"
39#include "mir/scene/null_trust_session_listener.h"
3940
40#include <map>41#include <map>
4142
@@ -87,6 +88,16 @@
87 });88 });
88}89}
8990
91std::shared_ptr<ms::TrustSessionListener>
92mir::DefaultServerConfiguration::the_trust_session_listener()
93{
94 return trust_session_listener(
95 [this]
96 {
97 return std::make_shared<ms::NullTrustSessionListener>();
98 });
99}
100
90std::shared_ptr<mi::CursorListener>101std::shared_ptr<mi::CursorListener>
91mir::DefaultServerConfiguration::the_cursor_listener()102mir::DefaultServerConfiguration::the_cursor_listener()
92{103{
93104
=== modified file 'src/server/frontend/protobuf_connection_creator.cpp'
=== modified file 'src/server/frontend/protobuf_message_processor.cpp'
--- src/server/frontend/protobuf_message_processor.cpp 2014-05-06 16:54:43 +0000
+++ src/server/frontend/protobuf_message_processor.cpp 2014-05-09 12:26:43 +0000
@@ -174,10 +174,29 @@
174 {174 {
175 invoke(this, display_server.get(), &protobuf::DisplayServer::release_screencast, invocation);175 invoke(this, display_server.get(), &protobuf::DisplayServer::release_screencast, invocation);
176 }176 }
177 else if ("new_fds_for_trusted_clients" == invocation.method_name())177<<<<<<< TREE
178 {178 else if ("new_fds_for_trusted_clients" == invocation.method_name())
179 invoke(this, display_server.get(), &protobuf::DisplayServer::new_fds_for_trusted_clients, invocation);179 {
180 }180 invoke(this, display_server.get(), &protobuf::DisplayServer::new_fds_for_trusted_clients, invocation);
181 }
182=======
183 else if ("new_fds_for_trusted_clients" == invocation.method_name())
184 {
185 invoke(this, display_server.get(), &protobuf::DisplayServer::new_fds_for_trusted_clients, invocation);
186 }
187 else if ("start_trust_session" == invocation.method_name())
188 {
189 invoke(this, display_server.get(), &protobuf::DisplayServer::start_trust_session, invocation);
190 }
191 else if ("add_trusted_session" == invocation.method_name())
192 {
193 invoke(this, display_server.get(), &protobuf::DisplayServer::add_trusted_session, invocation);
194 }
195 else if ("stop_trust_session" == invocation.method_name())
196 {
197 invoke(this, display_server.get(), &protobuf::DisplayServer::stop_trust_session, invocation);
198 }
199>>>>>>> MERGE-SOURCE
181 else if ("disconnect" == invocation.method_name())200 else if ("disconnect" == invocation.method_name())
182 {201 {
183 invoke(this, display_server.get(), &protobuf::DisplayServer::disconnect, invocation);202 invoke(this, display_server.get(), &protobuf::DisplayServer::disconnect, invocation);
184203
=== modified file 'src/server/frontend/session_mediator.cpp'
--- src/server/frontend/session_mediator.cpp 2014-05-09 11:01:53 +0000
+++ src/server/frontend/session_mediator.cpp 2014-05-09 12:26:43 +0000
@@ -40,6 +40,8 @@
40#include "mir/frontend/client_constants.h"40#include "mir/frontend/client_constants.h"
41#include "mir/frontend/event_sink.h"41#include "mir/frontend/event_sink.h"
42#include "mir/frontend/screencast.h"42#include "mir/frontend/screencast.h"
43#include "mir/frontend/trust_session.h"
44#include "mir/scene/trust_session_creation_parameters.h"
4345
44#include "mir/geometry/rectangles.h"46#include "mir/geometry/rectangles.h"
45#include "client_buffer_tracker.h"47#include "client_buffer_tracker.h"
@@ -416,6 +418,7 @@
416 done->Run();418 done->Run();
417}419}
418420
421<<<<<<< TREE
419void mf::SessionMediator::new_fds_for_trusted_clients(422void mf::SessionMediator::new_fds_for_trusted_clients(
420 ::google::protobuf::RpcController* ,423 ::google::protobuf::RpcController* ,
421 ::mir::protobuf::SocketFDRequest const* parameters,424 ::mir::protobuf::SocketFDRequest const* parameters,
@@ -448,6 +451,51 @@
448 done->Run();451 done->Run();
449}452}
450453
454=======
455void mf::SessionMediator::new_fds_for_trusted_clients(
456 ::google::protobuf::RpcController* ,
457 ::mir::protobuf::SocketFDRequest const* parameters,
458 ::mir::protobuf::SocketFD* response,
459 ::google::protobuf::Closure* done)
460{
461 {
462 std::unique_lock<std::mutex> lock(session_mutex);
463 auto session = weak_session.lock();
464
465 if (session.get() == nullptr)
466 BOOST_THROW_EXCEPTION(std::logic_error("Invalid application session"));
467
468 auto trust_session = weak_trust_session.lock();
469 if (trust_session.get() == nullptr)
470 BOOST_THROW_EXCEPTION(std::logic_error("Invalid trust session"));
471
472 // TODO write a handler that connects the new session to our trust session
473 auto const connect_handler = [this](std::shared_ptr<frontend::Session> const& session)
474 {
475 auto trust_session = weak_trust_session.lock();
476 if (trust_session.get() == nullptr)
477 BOOST_THROW_EXCEPTION(std::logic_error("Invalid trust session"));
478
479 shell->add_trusted_session_for(trust_session, session->process_id());
480 };
481
482 auto const fds_requested = parameters->number();
483
484 // < 1 is illogical, > 42 is unreasonable
485 if (fds_requested < 1 || fds_requested > 42)
486 BOOST_THROW_EXCEPTION(std::runtime_error("number of fds requested out of range"));
487
488 for (auto i = 0; i != fds_requested; ++i)
489 {
490 auto const fd = connection_context.fd_for_new_client(connect_handler);
491 response->add_fd(fd);
492 }
493 }
494
495 done->Run();
496}
497
498>>>>>>> MERGE-SOURCE
451void mf::SessionMediator::drm_auth_magic(499void mf::SessionMediator::drm_auth_magic(
452 google::protobuf::RpcController* /*controller*/,500 google::protobuf::RpcController* /*controller*/,
453 const mir::protobuf::DRMMagic* request,501 const mir::protobuf::DRMMagic* request,
@@ -487,6 +535,91 @@
487 done->Run();535 done->Run();
488}536}
489537
538void mf::SessionMediator::start_trust_session(::google::protobuf::RpcController*,
539 const ::mir::protobuf::TrustSessionParameters* request,
540 ::mir::protobuf::TrustSession* response,
541 ::google::protobuf::Closure* done)
542{
543 {
544 std::unique_lock<std::mutex> lock(session_mutex);
545 auto session = weak_session.lock();
546
547 if (session.get() == nullptr)
548 BOOST_THROW_EXCEPTION(std::logic_error("Invalid application session"));
549
550 ms::TrustSessionCreationParameters parameters;
551 parameters.set_base_process_id(request->base_trusted_session().pid());
552
553 std::ostringstream stream;
554 stream << "process id: " << parameters.base_process_id;
555 report->session_start_trust_session_called(session->name(), stream.str());
556
557 auto current_trust_session = weak_trust_session.lock();
558 if (current_trust_session.get() != nullptr)
559 BOOST_THROW_EXCEPTION(std::runtime_error("Cannot start another trust session"));
560
561 auto trust_session = shell->start_trust_session_for(session, parameters);
562 weak_trust_session = trust_session;
563
564 if (trust_session)
565 {
566 response->set_state(trust_session->get_state());
567 }
568 }
569 done->Run();
570}
571
572void mf::SessionMediator::add_trusted_session(::google::protobuf::RpcController*,
573 const ::mir::protobuf::TrustedSession* request,
574 ::mir::protobuf::TrustSessionAddResult* response,
575 ::google::protobuf::Closure* done)
576{
577 {
578 std::unique_lock<std::mutex> lock(session_mutex);
579 auto session = weak_session.lock();
580
581 if (session.get() == nullptr)
582 BOOST_THROW_EXCEPTION(std::logic_error("Invalid application session"));
583
584 auto trust_session = weak_trust_session.lock();
585
586 if (trust_session.get() == nullptr)
587 BOOST_THROW_EXCEPTION(std::logic_error("Invalid trust session"));
588
589 std::ostringstream stream;
590 stream << "process id: " << request->pid();
591 report->session_add_trusted_session_called(session->name(), stream.str());
592
593 response->set_result(shell->add_trusted_session_for(trust_session, request->pid()));
594 }
595 done->Run();
596}
597
598void mf::SessionMediator::stop_trust_session(::google::protobuf::RpcController*,
599 const ::mir::protobuf::Void*,
600 ::mir::protobuf::Void*,
601 ::google::protobuf::Closure* done)
602{
603 {
604 std::unique_lock<std::mutex> lock(session_mutex);
605 auto session = weak_session.lock();
606
607 if (session.get() == nullptr)
608 BOOST_THROW_EXCEPTION(std::logic_error("Invalid application session"));
609
610 auto trust_session = weak_trust_session.lock();
611 weak_trust_session.reset();
612
613 if (trust_session.get() == nullptr)
614 BOOST_THROW_EXCEPTION(std::logic_error("Invalid trusted session"));
615
616 report->session_stop_trust_session_called(session->name());
617
618 shell->stop_trust_session(trust_session);
619 }
620 done->Run();
621}
622
490void mf::SessionMediator::pack_protobuf_buffer(623void mf::SessionMediator::pack_protobuf_buffer(
491 protobuf::Buffer& protobuf_buffer,624 protobuf::Buffer& protobuf_buffer,
492 graphics::Buffer* graphics_buffer,625 graphics::Buffer* graphics_buffer,
493626
=== modified file 'src/server/frontend/session_mediator.h'
--- src/server/frontend/session_mediator.h 2014-05-06 16:54:43 +0000
+++ src/server/frontend/session_mediator.h 2014-05-09 12:26:43 +0000
@@ -53,6 +53,7 @@
53class EventSink;53class EventSink;
54class DisplayChanger;54class DisplayChanger;
55class Screencast;55class Screencast;
56class TrustSession;
5657
57// SessionMediator relays requests from the client process into the server.58// SessionMediator relays requests from the client process into the server.
58class SessionMediator : public mir::protobuf::DisplayServer59class SessionMediator : public mir::protobuf::DisplayServer
@@ -123,7 +124,26 @@
123 void screencast_buffer(google::protobuf::RpcController*,124 void screencast_buffer(google::protobuf::RpcController*,
124 const mir::protobuf::ScreencastId*,125 const mir::protobuf::ScreencastId*,
125 mir::protobuf::Buffer*,126 mir::protobuf::Buffer*,
126 google::protobuf::Closure* done) override;127<<<<<<< TREE
128 google::protobuf::Closure* done) override;
129=======
130 google::protobuf::Closure* done) override;
131
132 void start_trust_session(::google::protobuf::RpcController* controller,
133 const ::mir::protobuf::TrustSessionParameters* request,
134 ::mir::protobuf::TrustSession* response,
135 ::google::protobuf::Closure* done);
136
137 void add_trusted_session(::google::protobuf::RpcController* controller,
138 const ::mir::protobuf::TrustedSession* request,
139 ::mir::protobuf::TrustSessionAddResult* response,
140 ::google::protobuf::Closure* done);
141
142 void stop_trust_session(::google::protobuf::RpcController* controller,
143 const ::mir::protobuf::Void* request,
144 ::mir::protobuf::Void* response,
145 ::google::protobuf::Closure* done);
146>>>>>>> MERGE-SOURCE
127147
128 /* Platform specific requests */148 /* Platform specific requests */
129 void drm_auth_magic(google::protobuf::RpcController* controller,149 void drm_auth_magic(google::protobuf::RpcController* controller,
@@ -160,8 +180,14 @@
160180
161 std::mutex session_mutex;181 std::mutex session_mutex;
162 std::weak_ptr<Session> weak_session;182 std::weak_ptr<Session> weak_session;
163183<<<<<<< TREE
164 ConnectionContext const connection_context;184
185 ConnectionContext const connection_context;
186=======
187 std::weak_ptr<TrustSession> weak_trust_session;
188
189 ConnectionContext const connection_context;
190>>>>>>> MERGE-SOURCE
165};191};
166192
167}193}
168194
=== modified file 'src/server/report/logging/session_mediator_report.cpp'
--- src/server/report/logging/session_mediator_report.cpp 2014-03-06 06:05:17 +0000
+++ src/server/report/logging/session_mediator_report.cpp 2014-05-09 12:26:43 +0000
@@ -73,6 +73,21 @@
73 log->log(ml::Logger::informational, "session_configure_display_called(\"" + app_name + "\")", component);73 log->log(ml::Logger::informational, "session_configure_display_called(\"" + app_name + "\")", component);
74}74}
7575
76void mrl::SessionMediatorReport::session_start_trust_session_called(std::string const& app_name, std::string const& trust_info)
77{
78 log->log(ml::Logger::informational, "session_start_trust_session_called(\"" + app_name + "\"):\n" + trust_info, component);
79}
80
81void mrl::SessionMediatorReport::session_add_trusted_session_called(std::string const& app_name, std::string const& trust_info)
82{
83 log->log(ml::Logger::informational, "session_add_trusted_session_called(\"" + app_name + "\"):\n" + trust_info, component);
84}
85
86void mrl::SessionMediatorReport::session_stop_trust_session_called(std::string const& app_name)
87{
88 log->log(ml::Logger::informational, "session_stop_trust_session_called(\"" + app_name + "\")", component);
89}
90
76void mrl::SessionMediatorReport::session_error(91void mrl::SessionMediatorReport::session_error(
77 std::string const& app_name,92 std::string const& app_name,
78 char const* method,93 char const* method,
7994
=== modified file 'src/server/report/logging/session_mediator_report.h'
--- src/server/report/logging/session_mediator_report.h 2014-03-06 06:05:17 +0000
+++ src/server/report/logging/session_mediator_report.h 2014-05-09 12:26:43 +0000
@@ -57,6 +57,12 @@
5757
58 virtual void session_configure_display_called(std::string const& app_name);58 virtual void session_configure_display_called(std::string const& app_name);
5959
60 virtual void session_start_trust_session_called(std::string const& app_name, std::string const& trust_info);
61
62 virtual void session_add_trusted_session_called(std::string const& app_name, std::string const& trust_info);
63
64 virtual void session_stop_trust_session_called(std::string const& app_name);
65
60 virtual void session_error(66 virtual void session_error(
61 std::string const& app_name,67 std::string const& app_name,
62 char const* method,68 char const* method,
6369
=== modified file 'src/server/report/lttng/session_mediator_report.cpp'
--- src/server/report/lttng/session_mediator_report.cpp 2014-02-09 16:18:16 +0000
+++ src/server/report/lttng/session_mediator_report.cpp 2014-05-09 12:26:43 +0000
@@ -38,6 +38,17 @@
38MIR_SESSION_MEDIATOR_EVENT_METHOD(session_drm_auth_magic_called)38MIR_SESSION_MEDIATOR_EVENT_METHOD(session_drm_auth_magic_called)
39MIR_SESSION_MEDIATOR_EVENT_METHOD(session_configure_surface_called)39MIR_SESSION_MEDIATOR_EVENT_METHOD(session_configure_surface_called)
40MIR_SESSION_MEDIATOR_EVENT_METHOD(session_configure_display_called)40MIR_SESSION_MEDIATOR_EVENT_METHOD(session_configure_display_called)
41MIR_SESSION_MEDIATOR_EVENT_METHOD(session_stop_trust_session_called)
42
43void mir::report::lttng::SessionMediatorReport::session_start_trust_session_called(std::string const& app_name, std::string const& trust_info)
44{
45 mir_tracepoint(mir_server_session_mediator, session_start_trust_session_called, app_name.c_str(), trust_info.c_str());
46}
47
48void mir::report::lttng::SessionMediatorReport::session_add_trusted_session_called(std::string const& app_name, std::string const& trust_info)
49{
50 mir_tracepoint(mir_server_session_mediator, session_add_trusted_session_called, app_name.c_str(), trust_info.c_str());
51}
4152
42void mir::report::lttng::SessionMediatorReport::session_error(std::string const& app_name, char const* method, std::string const& what)53void mir::report::lttng::SessionMediatorReport::session_error(std::string const& app_name, char const* method, std::string const& what)
43{54{
4455
=== modified file 'src/server/report/lttng/session_mediator_report.h'
--- src/server/report/lttng/session_mediator_report.h 2014-02-09 16:18:16 +0000
+++ src/server/report/lttng/session_mediator_report.h 2014-05-09 12:26:43 +0000
@@ -41,6 +41,9 @@
41 void session_drm_auth_magic_called(std::string const& app_name) override;41 void session_drm_auth_magic_called(std::string const& app_name) override;
42 void session_configure_surface_called(std::string const& app_name) override;42 void session_configure_surface_called(std::string const& app_name) override;
43 void session_configure_display_called(std::string const& app_name) override;43 void session_configure_display_called(std::string const& app_name) override;
44 void session_start_trust_session_called(std::string const& app_name, std::string const& trust_info) override;
45 void session_add_trusted_session_called(std::string const& app_name, std::string const& trust_info) override;
46 void session_stop_trust_session_called(std::string const& app_name) override;
4447
45 void session_error(std::string const& app_name, char const* method, std::string const& what) override;48 void session_error(std::string const& app_name, char const* method, std::string const& what) override;
46private:49private:
4750
=== modified file 'src/server/report/lttng/session_mediator_report_tp.h'
--- src/server/report/lttng/session_mediator_report_tp.h 2014-02-03 11:44:32 +0000
+++ src/server/report/lttng/session_mediator_report_tp.h 2014-05-09 12:26:43 +0000
@@ -47,6 +47,27 @@
47MIR_SESSION_MEDIATOR_EVENT(session_drm_auth_magic_called)47MIR_SESSION_MEDIATOR_EVENT(session_drm_auth_magic_called)
48MIR_SESSION_MEDIATOR_EVENT(session_configure_surface_called)48MIR_SESSION_MEDIATOR_EVENT(session_configure_surface_called)
49MIR_SESSION_MEDIATOR_EVENT(session_configure_display_called)49MIR_SESSION_MEDIATOR_EVENT(session_configure_display_called)
50MIR_SESSION_MEDIATOR_EVENT(session_stop_trust_session_called)
51
52TRACEPOINT_EVENT(
53 mir_server_session_mediator,
54 session_start_trust_session_called,
55 TP_ARGS(char const*, application, char const*, trust_info),
56 TP_FIELDS(
57 ctf_string(application, application)
58 ctf_string(trust_info, trust_info)
59 )
60 )
61
62TRACEPOINT_EVENT(
63 mir_server_session_mediator,
64 session_add_trusted_session_called,
65 TP_ARGS(char const*, application, char const*, trust_info),
66 TP_FIELDS(
67 ctf_string(application, application)
68 ctf_string(trust_info, trust_info)
69 )
70 )
5071
51TRACEPOINT_EVENT(72TRACEPOINT_EVENT(
52 mir_server_session_mediator,73 mir_server_session_mediator,
5374
=== modified file 'src/server/report/null/session_mediator_report.cpp'
--- src/server/report/null/session_mediator_report.cpp 2014-03-06 06:05:17 +0000
+++ src/server/report/null/session_mediator_report.cpp 2014-05-09 12:26:43 +0000
@@ -50,6 +50,18 @@
50{50{
51}51}
5252
53void mir::report::null::SessionMediatorReport::session_start_trust_session_called(std::string const&, std::string const&)
54{
55}
56
57void mir::report::null::SessionMediatorReport::session_add_trusted_session_called(std::string const&, std::string const&)
58{
59}
60
61void mir::report::null::SessionMediatorReport::session_stop_trust_session_called(std::string const&)
62{
63}
64
53void mir::report::null::SessionMediatorReport::session_error(65void mir::report::null::SessionMediatorReport::session_error(
54 std::string const&,66 std::string const&,
55 char const* ,67 char const* ,
5668
=== modified file 'src/server/report/null/session_mediator_report.h'
--- src/server/report/null/session_mediator_report.h 2014-02-09 16:18:16 +0000
+++ src/server/report/null/session_mediator_report.h 2014-05-09 12:26:43 +0000
@@ -51,6 +51,12 @@
5151
52 void session_configure_display_called(std::string const& app_name) override;52 void session_configure_display_called(std::string const& app_name) override;
5353
54 void session_start_trust_session_called(std::string const& app_name, std::string const& trust_info) override;
55
56 void session_add_trusted_session_called(std::string const& app_name, std::string const& trust_info) override;
57
58 void session_stop_trust_session_called(std::string const& app_name) override;
59
54 void session_error(60 void session_error(
55 std::string const& app_name,61 std::string const& app_name,
56 char const* method,62 char const* method,
5763
=== modified file 'src/server/scene/CMakeLists.txt'
--- src/server/scene/CMakeLists.txt 2014-05-06 03:33:05 +0000
+++ src/server/scene/CMakeLists.txt 2014-05-09 12:26:43 +0000
@@ -20,4 +20,7 @@
20 threaded_snapshot_strategy.cpp20 threaded_snapshot_strategy.cpp
21 legacy_scene_change_notification.cpp21 legacy_scene_change_notification.cpp
22 legacy_surface_change_notification.cpp22 legacy_surface_change_notification.cpp
23 trust_session_impl.cpp
24 trust_session_container.cpp
25 trust_session_creation_parameters.cpp
23)26)
2427
=== modified file 'src/server/scene/application_session.cpp'
--- src/server/scene/application_session.cpp 2014-05-06 16:54:43 +0000
+++ src/server/scene/application_session.cpp 2014-05-09 12:26:43 +0000
@@ -23,6 +23,7 @@
23#include "snapshot_strategy.h"23#include "snapshot_strategy.h"
24#include "mir/scene/session_listener.h"24#include "mir/scene/session_listener.h"
25#include "mir/frontend/event_sink.h"25#include "mir/frontend/event_sink.h"
26#include "default_session_container.h"
2627
27#include <boost/throw_exception.hpp>28#include <boost/throw_exception.hpp>
2829
@@ -30,6 +31,7 @@
30#include <memory>31#include <memory>
31#include <cassert>32#include <cassert>
32#include <algorithm>33#include <algorithm>
34#include <cstring>
3335
34namespace mf = mir::frontend;36namespace mf = mir::frontend;
35namespace ms = mir::scene;37namespace ms = mir::scene;
@@ -181,3 +183,22 @@
181{183{
182 event_sink->handle_lifecycle_event(state);184 event_sink->handle_lifecycle_event(state);
183}185}
186
187void ms::ApplicationSession::begin_trust_session()
188{
189 // All sessions which are part of the trust session get this event.
190 MirEvent start_event;
191 memset(&start_event, 0, sizeof start_event);
192 start_event.type = mir_event_type_trust_session_state_change;
193 start_event.trust_session.new_state = mir_trust_session_state_started;
194 event_sink->handle_event(start_event);
195}
196
197void ms::ApplicationSession::end_trust_session()
198{
199 MirEvent stop_event;
200 memset(&stop_event, 0, sizeof stop_event);
201 stop_event.type = mir_event_type_trust_session_state_change;
202 stop_event.trust_session.new_state = mir_trust_session_state_stopped;
203 event_sink->handle_event(stop_event);
204}
184205
=== modified file 'src/server/scene/application_session.h'
--- src/server/scene/application_session.h 2014-05-06 16:54:43 +0000
+++ src/server/scene/application_session.h 2014-05-09 12:26:43 +0000
@@ -71,6 +71,9 @@
7171
72 void set_lifecycle_state(MirLifecycleState state);72 void set_lifecycle_state(MirLifecycleState state);
7373
74 void begin_trust_session() override;
75 void end_trust_session() override;
76
74protected:77protected:
75 ApplicationSession(ApplicationSession const&) = delete;78 ApplicationSession(ApplicationSession const&) = delete;
76 ApplicationSession& operator=(ApplicationSession const&) = delete;79 ApplicationSession& operator=(ApplicationSession const&) = delete;
7780
=== modified file 'src/server/scene/default_configuration.cpp'
--- src/server/scene/default_configuration.cpp 2014-05-09 03:00:20 +0000
+++ src/server/scene/default_configuration.cpp 2014-05-09 12:26:43 +0000
@@ -25,12 +25,12 @@
25#include "mir/abnormal_exit.h"25#include "mir/abnormal_exit.h"
26#include "mir/scene/session.h"26#include "mir/scene/session.h"
2727
28#include "session_container.h"
28#include "broadcasting_session_event_sink.h"29#include "broadcasting_session_event_sink.h"
29#include "default_session_container.h"30#include "default_session_container.h"
30#include "gl_pixel_buffer.h"31#include "gl_pixel_buffer.h"
31#include "global_event_sender.h"32#include "global_event_sender.h"
32#include "mediating_display_changer.h"33#include "mediating_display_changer.h"
33#include "session_container.h"
34#include "session_manager.h"34#include "session_manager.h"
35#include "surface_allocator.h"35#include "surface_allocator.h"
36#include "surface_controller.h"36#include "surface_controller.h"
@@ -184,7 +184,8 @@
184 the_shell_focus_setter(),184 the_shell_focus_setter(),
185 the_snapshot_strategy(),185 the_snapshot_strategy(),
186 the_session_event_sink(),186 the_session_event_sink(),
187 the_session_listener());187 the_session_listener(),
188 the_trust_session_listener());
188 });189 });
189}190}
190191
191192
=== modified file 'src/server/scene/session_manager.cpp'
--- src/server/scene/session_manager.cpp 2014-04-15 05:31:19 +0000
+++ src/server/scene/session_manager.cpp 2014-05-09 12:26:43 +0000
@@ -24,6 +24,12 @@
24#include "mir/scene/session.h"24#include "mir/scene/session.h"
25#include "mir/scene/session_listener.h"25#include "mir/scene/session_listener.h"
26#include "session_event_sink.h"26#include "session_event_sink.h"
27#include "mir/scene/trust_session_creation_parameters.h"
28#include "trust_session_impl.h"
29#include "trust_session_container.h"
30#include "mir/scene/trust_session_listener.h"
31
32#include <boost/throw_exception.hpp>
2733
28#include <memory>34#include <memory>
29#include <cassert>35#include <cassert>
@@ -38,13 +44,16 @@
38 std::shared_ptr<msh::FocusSetter> const& focus_setter,44 std::shared_ptr<msh::FocusSetter> const& focus_setter,
39 std::shared_ptr<SnapshotStrategy> const& snapshot_strategy,45 std::shared_ptr<SnapshotStrategy> const& snapshot_strategy,
40 std::shared_ptr<SessionEventSink> const& session_event_sink,46 std::shared_ptr<SessionEventSink> const& session_event_sink,
41 std::shared_ptr<SessionListener> const& session_listener) :47 std::shared_ptr<SessionListener> const& session_listener,
48 std::shared_ptr<TrustSessionListener> const& trust_session_listener) :
42 surface_coordinator(surface_factory),49 surface_coordinator(surface_factory),
43 app_container(container),50 app_container(container),
44 focus_setter(focus_setter),51 focus_setter(focus_setter),
45 snapshot_strategy(snapshot_strategy),52 snapshot_strategy(snapshot_strategy),
46 session_event_sink(session_event_sink),53 session_event_sink(session_event_sink),
47 session_listener(session_listener)54 session_listener(session_listener),
55 trust_session_listener(trust_session_listener),
56 trust_session_container(std::make_shared<TrustSessionContainer>())
48{57{
49 assert(surface_factory);58 assert(surface_factory);
50 assert(container);59 assert(container);
@@ -85,6 +94,16 @@
8594
86 session_listener->starting(new_session);95 session_listener->starting(new_session);
8796
97 {
98 trust_session_container->for_each_trust_session_for_process(client_pid,
99 [client_pid, new_session](std::shared_ptr<frontend::TrustSession> const& trust_session)
100 {
101 auto scene_trust_session = std::dynamic_pointer_cast<ms::TrustSession>(trust_session);
102
103 scene_trust_session->add_trusted_child(new_session);
104 });
105 }
106
88 set_focus_to(new_session);107 set_focus_to(new_session);
89108
90 return new_session;109 return new_session;
@@ -122,12 +141,45 @@
122 scene_session->force_requests_to_complete();141 scene_session->force_requests_to_complete();
123142
124 session_event_sink->handle_session_stopping(scene_session);143 session_event_sink->handle_session_stopping(scene_session);
144
145 {
146 std::unique_lock<std::mutex> lock(trust_sessions_mutex);
147
148 std::vector<std::shared_ptr<frontend::TrustSession>> trust_sessions;
149 trust_session_container->for_each_trust_session_for_process(scene_session->process_id(),
150 [&](std::shared_ptr<frontend::TrustSession> const& trust_session)
151 {
152 trust_sessions.push_back(trust_session);
153 });
154
155 for(auto trust_session : trust_sessions)
156 {
157 auto scene_trust_session = std::dynamic_pointer_cast<ms::TrustSession>(trust_session);
158
159 if (scene_trust_session->get_trusted_helper().lock() == scene_session)
160 {
161 stop_trust_session_locked(lock, scene_trust_session);
162 }
163 else
164 {
165 scene_trust_session->remove_trusted_child(scene_session);
166
167 trust_session_container->remove_process(scene_session->process_id());
168 }
169 }
170 }
171
125 session_listener->stopping(scene_session);172 session_listener->stopping(scene_session);
126173
127 app_container->remove_session(scene_session);174 app_container->remove_session(scene_session);
128175
129 std::unique_lock<std::mutex> lock(mutex);176 std::unique_lock<std::mutex> lock(mutex);
130 set_focus_to_locked(lock, app_container->successor_of(std::shared_ptr<Session>()));177 auto old_focus = focus_application.lock();
178 if (old_focus == scene_session)
179 {
180 // only reset the focus if this session had focus
181 set_focus_to_locked(lock, app_container->successor_of(std::shared_ptr<ms::Session>()));
182 }
131}183}
132184
133void ms::SessionManager::focus_next()185void ms::SessionManager::focus_next()
@@ -169,3 +221,73 @@
169{221{
170 set_focus_to(std::dynamic_pointer_cast<Session>(session));222 set_focus_to(std::dynamic_pointer_cast<Session>(session));
171}223}
224
225std::shared_ptr<mf::TrustSession> ms::SessionManager::start_trust_session_for(std::shared_ptr<mf::Session> const& session,
226 TrustSessionCreationParameters const& params)
227{
228 std::unique_lock<std::mutex> lock(trust_sessions_mutex);
229
230 auto shell_session = std::dynamic_pointer_cast<ms::Session>(session);
231
232 auto const trust_session = std::make_shared<TrustSessionImpl>(shell_session, params, trust_session_listener);
233
234 trust_session_container->insert(trust_session, shell_session->process_id());
235
236 trust_session->start();
237 trust_session_listener->starting(*(trust_session.get()));
238
239 add_trusted_session_for_locked(lock, trust_session, params.base_process_id);
240 return trust_session;
241}
242
243MirTrustSessionAddTrustResult ms::SessionManager::add_trusted_session_for(std::shared_ptr<mf::TrustSession> const& trust_session,
244 pid_t session_pid)
245{
246 std::unique_lock<std::mutex> lock(trust_sessions_mutex);
247
248 return add_trusted_session_for_locked(lock, trust_session, session_pid);
249}
250
251MirTrustSessionAddTrustResult ms::SessionManager::add_trusted_session_for_locked(std::unique_lock<std::mutex> const&,
252 std::shared_ptr<mf::TrustSession> const& trust_session,
253 pid_t session_pid)
254{
255 auto scene_trust_session = std::dynamic_pointer_cast<ms::TrustSession>(trust_session);
256
257 trust_session_container->insert(trust_session, session_pid);
258
259 bool added = false;
260 app_container->for_each(
261 [&](std::shared_ptr<ms::Session> const& container_session)
262 {
263 if (container_session->process_id() == session_pid)
264 {
265 added |= scene_trust_session->add_trusted_child(container_session);
266 }
267 });
268
269 if (!added)
270 BOOST_THROW_EXCEPTION(std::runtime_error("failed to add trusted session"));
271
272 return mir_trust_session_add_tust_succeeded;
273}
274
275void ms::SessionManager::stop_trust_session(std::shared_ptr<mf::TrustSession> const& trust_session)
276{
277 std::unique_lock<std::mutex> lock(trust_sessions_mutex);
278
279 stop_trust_session_locked(lock, trust_session);
280}
281
282void ms::SessionManager::stop_trust_session_locked(std::unique_lock<std::mutex> const&,
283 std::shared_ptr<mf::TrustSession> const& trust_session)
284{
285 auto scene_trust_session = std::dynamic_pointer_cast<ms::TrustSession>(trust_session);
286
287 trust_session->stop();
288
289 trust_session_container->remove_trust_session(trust_session);
290
291 trust_session_listener->stopping(*(scene_trust_session).get());
292}
293
172294
=== modified file 'src/server/scene/session_manager.h'
--- src/server/scene/session_manager.h 2014-04-15 05:31:19 +0000
+++ src/server/scene/session_manager.h 2014-05-09 12:26:43 +0000
@@ -26,6 +26,7 @@
26#include <mutex>26#include <mutex>
27#include <memory>27#include <memory>
28#include <vector>28#include <vector>
29#include <map>
2930
30namespace mir31namespace mir
31{32{
@@ -42,6 +43,8 @@
42class SessionListener;43class SessionListener;
43class SnapshotStrategy;44class SnapshotStrategy;
44class SurfaceCoordinator;45class SurfaceCoordinator;
46class TrustSessionContainer;
47class TrustSessionListener;
4548
46class SessionManager : public frontend::Shell, public shell::FocusController49class SessionManager : public frontend::Shell, public shell::FocusController
47{50{
@@ -51,7 +54,8 @@
51 std::shared_ptr<shell::FocusSetter> const& focus_setter,54 std::shared_ptr<shell::FocusSetter> const& focus_setter,
52 std::shared_ptr<SnapshotStrategy> const& snapshot_strategy,55 std::shared_ptr<SnapshotStrategy> const& snapshot_strategy,
53 std::shared_ptr<SessionEventSink> const& session_event_sink,56 std::shared_ptr<SessionEventSink> const& session_event_sink,
54 std::shared_ptr<SessionListener> const& session_listener);57 std::shared_ptr<SessionListener> const& session_listener,
58 std::shared_ptr<TrustSessionListener> const& trust_session_listener);
55 virtual ~SessionManager();59 virtual ~SessionManager();
5660
57 virtual std::shared_ptr<frontend::Session> open_session(61 virtual std::shared_ptr<frontend::Session> open_session(
@@ -71,6 +75,12 @@
7175
72 void handle_surface_created(std::shared_ptr<frontend::Session> const& session) override;76 void handle_surface_created(std::shared_ptr<frontend::Session> const& session) override;
7377
78 std::shared_ptr<frontend::TrustSession> start_trust_session_for(std::shared_ptr<frontend::Session> const& session,
79 TrustSessionCreationParameters const& params) override;
80 MirTrustSessionAddTrustResult add_trusted_session_for(std::shared_ptr<frontend::TrustSession> const& trust_session,
81 pid_t session_pid) override;
82 void stop_trust_session(std::shared_ptr<frontend::TrustSession> const& trust_session) override;
83
74protected:84protected:
75 SessionManager(const SessionManager&) = delete;85 SessionManager(const SessionManager&) = delete;
76 SessionManager& operator=(const SessionManager&) = delete;86 SessionManager& operator=(const SessionManager&) = delete;
@@ -82,11 +92,20 @@
82 std::shared_ptr<SnapshotStrategy> const snapshot_strategy;92 std::shared_ptr<SnapshotStrategy> const snapshot_strategy;
83 std::shared_ptr<SessionEventSink> const session_event_sink;93 std::shared_ptr<SessionEventSink> const session_event_sink;
84 std::shared_ptr<SessionListener> const session_listener;94 std::shared_ptr<SessionListener> const session_listener;
95 std::shared_ptr<TrustSessionListener> const trust_session_listener;
96 std::shared_ptr<TrustSessionContainer> trust_session_container;
8597
86 std::mutex mutex;98 std::mutex mutex;
87 std::weak_ptr<Session> focus_application;99 std::weak_ptr<Session> focus_application;
88100
89 void set_focus_to_locked(std::unique_lock<std::mutex> const& lock, std::shared_ptr<Session> const& next_focus);101 void set_focus_to_locked(std::unique_lock<std::mutex> const& lock, std::shared_ptr<Session> const& next_focus);
102
103 MirTrustSessionAddTrustResult add_trusted_session_for_locked(std::unique_lock<std::mutex> const&,
104 std::shared_ptr<frontend::TrustSession> const& trust_session,
105 pid_t session_pid);
106 void stop_trust_session_locked(std::unique_lock<std::mutex> const& lock,
107 std::shared_ptr<frontend::TrustSession> const& trust_session);
108 std::mutex mutable trust_sessions_mutex;
90};109};
91110
92}111}
93112
=== added file 'src/server/scene/trust_session_container.cpp'
--- src/server/scene/trust_session_container.cpp 1970-01-01 00:00:00 +0000
+++ src/server/scene/trust_session_container.cpp 2014-05-09 12:26:43 +0000
@@ -0,0 +1,95 @@
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: Nick Dedekind <nick.dedekind@canonical.com>
17 */
18
19#include "trust_session_container.h"
20
21namespace ms = mir::scene;
22namespace mf = mir::frontend;
23
24uint insertion_order = 0;
25
26ms::TrustSessionContainer::TrustSessionContainer()
27 : trust_session_index(process_map)
28 , process_index(get<1>(process_map))
29{
30}
31
32bool ms::TrustSessionContainer::insert(std::shared_ptr<mf::TrustSession> const& trust_session, ClientProcess const& process)
33{
34 std::unique_lock<std::mutex> lk(mutex);
35
36 object_by_trust_session::iterator it;
37 bool valid = false;
38
39 Object obj{trust_session, process, insertion_order++};
40 boost::tie(it,valid) = process_map.insert(obj);
41
42 return valid;
43}
44
45void ms::TrustSessionContainer::for_each_process_for_trust_session(
46 std::shared_ptr<mf::TrustSession> const& trust_session,
47 std::function<void(ClientProcess const& id)> f)
48{
49 std::unique_lock<std::mutex> lk(mutex);
50
51 object_by_trust_session::iterator it,end;
52 boost::tie(it,end) = trust_session_index.equal_range(trust_session);
53
54 for (; it != end; ++it)
55 {
56 Object const& obj = *it;
57 f(obj.client_process);
58 }
59}
60
61void ms::TrustSessionContainer::for_each_trust_session_for_process(
62 ClientProcess const& process,
63 std::function<void(std::shared_ptr<mf::TrustSession> const&)> f)
64{
65 std::unique_lock<std::mutex> lk(mutex);
66
67 object_by_process::iterator it,end;
68 boost::tie(it,end) = process_index.equal_range(process);
69
70 for (; it != end; ++it)
71 {
72 Object const& obj = *it;
73 f(obj.trust_session);
74 }
75}
76
77void ms::TrustSessionContainer::remove_trust_session(std::shared_ptr<frontend::TrustSession> const& trust_session)
78{
79 std::unique_lock<std::mutex> lk(mutex);
80
81 object_by_trust_session::iterator it,end;
82 boost::tie(it,end) = trust_session_index.equal_range(trust_session);
83
84 trust_session_index.erase(it, end);
85}
86
87void ms::TrustSessionContainer::remove_process(ClientProcess const& process)
88{
89 std::unique_lock<std::mutex> lk(mutex);
90
91 object_by_process::iterator it,end;
92 boost::tie(it,end) = process_index.equal_range(process);
93
94 process_index.erase(it, end);
95}
096
=== added file 'src/server/scene/trust_session_container.h'
--- src/server/scene/trust_session_container.h 1970-01-01 00:00:00 +0000
+++ src/server/scene/trust_session_container.h 2014-05-09 12:26:43 +0000
@@ -0,0 +1,103 @@
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: Nick Dedekind <nick.dedekind@canonical.com>
17 */
18
19#ifndef MIR_SCENE_TRUST_SESSION_CONTAINER_H_
20#define MIR_SCENE_TRUST_SESSION_CONTAINER_H_
21
22#include <sys/types.h>
23#include <mutex>
24#include <map>
25
26#include <boost/multi_index_container.hpp>
27#include <boost/multi_index/member.hpp>
28#include <boost/multi_index/ordered_index.hpp>
29#include <boost/multi_index/hashed_index.hpp>
30#include <boost/multi_index/composite_key.hpp>
31
32namespace mir
33{
34namespace frontend
35{
36class TrustSession;
37class Session;
38}
39
40using boost::multi_index_container;
41using namespace boost::multi_index;
42
43namespace scene
44{
45
46class TrustSessionContainer
47{
48public:
49 TrustSessionContainer();
50 virtual ~TrustSessionContainer() = default;
51
52 typedef pid_t ClientProcess;
53
54 bool insert(std::shared_ptr<frontend::TrustSession> const& trust_session, ClientProcess const& process);
55
56 void for_each_process_for_trust_session(std::shared_ptr<frontend::TrustSession> const& trust_session, std::function<void(ClientProcess const&)> f);
57 void for_each_trust_session_for_process(ClientProcess const& process, std::function<void(std::shared_ptr<frontend::TrustSession> const&)> f);
58
59 void remove_trust_session(std::shared_ptr<frontend::TrustSession> const& trust_session);
60 void remove_process(ClientProcess const& process);
61
62private:
63 std::mutex mutable mutex;
64
65 typedef struct {
66 std::shared_ptr<frontend::TrustSession> trust_session;
67 ClientProcess client_process;
68 uint insert_order;
69 } Object;
70
71 typedef multi_index_container<
72 Object,
73 indexed_by<
74 ordered_non_unique<
75 composite_key<
76 Object,
77 member<Object, std::shared_ptr<frontend::TrustSession>, &Object::trust_session>,
78 member<Object, uint, &Object::insert_order>
79 >
80 >,
81 ordered_unique<
82 composite_key<
83 Object,
84 member<Object, ClientProcess, &Object::client_process>,
85 member<Object, std::shared_ptr<frontend::TrustSession>, &Object::trust_session>
86 >
87 >
88 >
89 > TrustSessionsProcesses;
90
91 typedef nth_index<TrustSessionsProcesses,0>::type object_by_trust_session;
92 typedef nth_index<TrustSessionsProcesses,1>::type object_by_process;
93
94
95 TrustSessionsProcesses process_map;
96 object_by_trust_session& trust_session_index;
97 object_by_process& process_index;
98};
99
100}
101}
102
103#endif // MIR_SCENE_TRUST_SESSION_CONTAINER_H_
0104
=== added file 'src/server/scene/trust_session_creation_parameters.cpp'
--- src/server/scene/trust_session_creation_parameters.cpp 1970-01-01 00:00:00 +0000
+++ src/server/scene/trust_session_creation_parameters.cpp 2014-05-09 12:26:43 +0000
@@ -0,0 +1,51 @@
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: Nick Dedekind <nick.dedekind@canonical.com>
17 */
18
19#include "mir/scene/trust_session_creation_parameters.h"
20
21namespace ms = mir::scene;
22
23ms::TrustSessionCreationParameters::TrustSessionCreationParameters()
24 : base_process_id(0)
25{
26}
27
28ms::TrustSessionCreationParameters& ms::TrustSessionCreationParameters::set_base_process_id(pid_t process_id)
29{
30 base_process_id = process_id;
31 return *this;
32}
33
34bool ms::operator==(
35 const TrustSessionCreationParameters& lhs,
36 const TrustSessionCreationParameters& rhs)
37{
38 return lhs.base_process_id == rhs.base_process_id;
39}
40
41bool ms::operator!=(
42 const TrustSessionCreationParameters& lhs,
43 const TrustSessionCreationParameters& rhs)
44{
45 return !(lhs == rhs);
46}
47
48ms::TrustSessionCreationParameters ms::a_trust_session()
49{
50 return TrustSessionCreationParameters();
51}
052
=== added file 'src/server/scene/trust_session_impl.cpp'
--- src/server/scene/trust_session_impl.cpp 1970-01-01 00:00:00 +0000
+++ src/server/scene/trust_session_impl.cpp 2014-05-09 12:26:43 +0000
@@ -0,0 +1,187 @@
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: Nick Dedekind <nick.dedekind@canonical.com>
17 */
18
19#include "trust_session_impl.h"
20#include "mir/scene/session.h"
21#include "mir/scene/trust_session_creation_parameters.h"
22#include "mir/scene/trust_session_listener.h"
23#include "session_container.h"
24
25#include <sstream>
26#include <algorithm>
27
28namespace ms = mir::scene;
29
30int next_unique_id = 0;
31
32ms::TrustSessionImpl::TrustSessionImpl(
33 std::weak_ptr<ms::Session> const& session,
34 TrustSessionCreationParameters const&,
35 std::shared_ptr<TrustSessionListener> const& trust_session_listener) :
36 trusted_helper(session),
37 trust_session_listener(trust_session_listener),
38 state(mir_trust_session_state_stopped)
39{
40}
41
42ms::TrustSessionImpl::~TrustSessionImpl()
43{
44 TrustSessionImpl::stop();
45}
46
47MirTrustSessionState ms::TrustSessionImpl::get_state() const
48{
49 std::lock_guard<decltype(mutex)> lock(mutex);
50
51 return state;
52}
53
54std::weak_ptr<ms::Session> ms::TrustSessionImpl::get_trusted_helper() const
55{
56 std::lock_guard<decltype(mutex)> lock(mutex);
57
58 return trusted_helper;
59}
60
61void ms::TrustSessionImpl::start()
62{
63 std::lock_guard<decltype(mutex)> lock(mutex);
64
65 if (state == mir_trust_session_state_started)
66 return;
67
68 state = mir_trust_session_state_started;
69
70 auto helper = trusted_helper.lock();
71 if (helper) {
72 helper->begin_trust_session();
73 }
74}
75
76void ms::TrustSessionImpl::stop()
77{
78 std::lock_guard<decltype(mutex)> lock(mutex);
79
80 if (state == mir_trust_session_state_stopped)
81 return;
82
83 state = mir_trust_session_state_stopped;
84
85 auto helper = trusted_helper.lock();
86 if (helper) {
87 helper->end_trust_session();
88 }
89
90 std::vector<std::shared_ptr<ms::Session>> children;
91 {
92 std::lock_guard<decltype(mutex_children)> child_lock(mutex_children);
93
94 for (auto rit = trusted_children.rbegin(); rit != trusted_children.rend(); ++rit)
95 {
96 auto session = (*rit).lock();
97 if (session)
98 {
99 children.push_back(session);
100 }
101 }
102 trusted_children.clear();
103 }
104
105 for (auto session : children)
106 {
107 trust_session_listener->trusted_session_ending(*this, *(session).get());
108 }
109}
110
111bool ms::TrustSessionImpl::add_trusted_child(std::shared_ptr<ms::Session> const& session)
112{
113 std::lock_guard<decltype(mutex)> lock(mutex);
114
115 if (state == mir_trust_session_state_stopped)
116 return false;
117
118 {
119 std::lock_guard<decltype(mutex_children)> child_lock(mutex_children);
120
121 if (std::find_if(trusted_children.begin(), trusted_children.end(),
122 [session](std::weak_ptr<ms::Session> const& child)
123 {
124 return child.lock() == session;
125 }) != trusted_children.end())
126 {
127 return false;
128 }
129
130 trusted_children.push_back(session);
131 }
132
133 trust_session_listener->trusted_session_beginning(*this, *(session).get());
134 return true;
135}
136
137void ms::TrustSessionImpl::remove_trusted_child(std::shared_ptr<ms::Session> const& session)
138{
139 std::lock_guard<decltype(mutex)> lock(mutex);
140
141 if (state == mir_trust_session_state_stopped)
142 return;
143
144 bool found = false;
145 {
146 std::lock_guard<decltype(mutex_children)> child_lock(mutex_children);
147
148 for (auto it = trusted_children.begin(); it != trusted_children.end(); ++it)
149 {
150 auto trusted_child = (*it).lock();
151 if (trusted_child && trusted_child == session) {
152 found = true;
153 trusted_children.erase(it);
154 break;
155 }
156 }
157 }
158
159 if (found)
160 {
161 trust_session_listener->trusted_session_ending(*this, *(session).get());
162 }
163}
164
165void ms::TrustSessionImpl::for_each_trusted_child(
166 std::function<void(std::shared_ptr<ms::Session> const&)> f,
167 bool reverse) const
168{
169 std::lock_guard<decltype(mutex_children)> child_lock(mutex_children);
170
171 if (reverse)
172 {
173 for (auto rit = trusted_children.rbegin(); rit != trusted_children.rend(); ++rit)
174 {
175 if (auto trusted_child = (*rit).lock())
176 f(trusted_child);
177 }
178 }
179 else
180 {
181 for (auto it = trusted_children.begin(); it != trusted_children.end(); ++it)
182 {
183 if (auto trusted_child = (*it).lock())
184 f(trusted_child);
185 }
186 }
187}
0188
=== added file 'src/server/scene/trust_session_impl.h'
--- src/server/scene/trust_session_impl.h 1970-01-01 00:00:00 +0000
+++ src/server/scene/trust_session_impl.h 2014-05-09 12:26:43 +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: Nick Dedekind <nick.dedekind@canonical.com>
17 */
18
19#ifndef MIR_SCENE_TRUST_SESSION_IMPL_H_
20#define MIR_SCENE_TRUST_SESSION_IMPL_H_
21
22#include "mir/scene/trust_session.h"
23
24#include <vector>
25#include <atomic>
26#include <mutex>
27
28namespace mir
29{
30
31namespace scene
32{
33class SessionContainer;
34class TrustSessionCreationParameters;
35class TrustSessionListener;
36
37class TrustSessionImpl : public TrustSession
38{
39public:
40 TrustSessionImpl(std::weak_ptr<Session> const& session,
41 TrustSessionCreationParameters const& parameters,
42 std::shared_ptr<TrustSessionListener> const& trust_session_listener);
43 ~TrustSessionImpl();
44
45 MirTrustSessionState get_state() const override;
46 std::weak_ptr<Session> get_trusted_helper() const override;
47
48 void start() override;
49 void stop() override;
50
51 bool add_trusted_child(std::shared_ptr<Session> const& session);
52 void remove_trusted_child(std::shared_ptr<Session> const& session);
53 void for_each_trusted_child(std::function<void(std::shared_ptr<Session> const&)> f, bool reverse) const;
54
55protected:
56 TrustSessionImpl(const TrustSessionImpl&) = delete;
57 TrustSessionImpl& operator=(const TrustSessionImpl&) = delete;
58
59private:
60 std::weak_ptr<Session> const trusted_helper;
61 std::shared_ptr<TrustSessionListener> const trust_session_listener;
62 MirTrustSessionState state;
63 std::string cookie;
64 std::mutex mutable mutex;
65
66 std::mutex mutable mutex_children;
67 std::vector<pid_t> client_processes;
68 std::vector<std::weak_ptr<Session>> trusted_children;
69};
70
71}
72}
73
74#endif // MIR_SCENE_TRUST_SESSION_H_
075
=== modified file 'src/shared/protobuf/mir_protobuf.proto'
--- src/shared/protobuf/mir_protobuf.proto 2014-05-06 16:54:43 +0000
+++ src/shared/protobuf/mir_protobuf.proto 2014-05-09 12:26:43 +0000
@@ -100,7 +100,7 @@
100 optional int32 pixel_format = 4;100 optional int32 pixel_format = 4;
101 optional int32 buffer_usage = 5;101 optional int32 buffer_usage = 5;
102 optional Buffer buffer = 6;102 optional Buffer buffer = 6;
103 103
104 repeated sint32 fd = 7;104 repeated sint32 fd = 7;
105 optional int32 fds_on_side_channel = 8;105 optional int32 fds_on_side_channel = 8;
106106
@@ -175,18 +175,50 @@
175 optional string error = 127;175 optional string error = 127;
176}176}
177177
178message SocketFDRequest {178<<<<<<< TREE
179 required int32 number = 1;179message SocketFDRequest {
180}180 required int32 number = 1;
181181}
182182
183message SocketFD {183
184 repeated sint32 fd = 1;184message SocketFD {
185 optional int32 fds_on_side_channel = 2;185 repeated sint32 fd = 1;
186186 optional int32 fds_on_side_channel = 2;
187 optional string error = 127;187
188}188 optional string error = 127;
189189}
190
191=======
192message SocketFDRequest {
193 required int32 number = 1;
194}
195
196message SocketFD {
197 repeated sint32 fd = 1;
198 optional int32 fds_on_side_channel = 2;
199
200 optional string error = 127;
201}
202
203message TrustedSession {
204 required int32 pid = 1;
205}
206
207message TrustSessionParameters {
208 required TrustedSession base_trusted_session = 1;
209}
210
211message TrustSession {
212 optional uint32 state = 1;
213 optional string error = 127;
214}
215
216message TrustSessionAddResult {
217 required int32 result = 1;
218 optional string error = 127;
219}
220
221>>>>>>> MERGE-SOURCE
190service DisplayServer {222service DisplayServer {
191 // Platform independent requests223 // Platform independent requests
192 rpc connect(ConnectParameters) returns (Connection);224 rpc connect(ConnectParameters) returns (Connection);
@@ -206,5 +238,13 @@
206 rpc create_screencast(ScreencastParameters) returns (Screencast);238 rpc create_screencast(ScreencastParameters) returns (Screencast);
207 rpc screencast_buffer(ScreencastId) returns (Buffer);239 rpc screencast_buffer(ScreencastId) returns (Buffer);
208 rpc release_screencast(ScreencastId) returns (Void);240 rpc release_screencast(ScreencastId) returns (Void);
209 rpc new_fds_for_trusted_clients(SocketFDRequest) returns (SocketFD);241<<<<<<< TREE
242 rpc new_fds_for_trusted_clients(SocketFDRequest) returns (SocketFD);
243=======
244 rpc new_fds_for_trusted_clients(SocketFDRequest) returns (SocketFD);
245
246 rpc start_trust_session(TrustSessionParameters) returns (TrustSession);
247 rpc add_trusted_session(TrustedSession) returns (TrustSessionAddResult);
248 rpc stop_trust_session(Void) returns (Void);
249>>>>>>> MERGE-SOURCE
210}250}
211251
=== modified file 'tests/acceptance-tests/CMakeLists.txt'
--- tests/acceptance-tests/CMakeLists.txt 2014-05-07 14:00:57 +0000
+++ tests/acceptance-tests/CMakeLists.txt 2014-05-09 12:26:43 +0000
@@ -28,6 +28,7 @@
28 test_surfaces_with_output_id.cpp28 test_surfaces_with_output_id.cpp
29 test_server_disconnect.cpp29 test_server_disconnect.cpp
30 test_client_library_drm.cpp30 test_client_library_drm.cpp
31 test_client_trust_session_api.cpp
31 test_protobuf.cpp32 test_protobuf.cpp
32 test_client_screencast.cpp33 test_client_screencast.cpp
33 test_client_surface_swap_buffers.cpp34 test_client_surface_swap_buffers.cpp
3435
=== added file 'tests/acceptance-tests/test_client_trust_session_api.cpp'
--- tests/acceptance-tests/test_client_trust_session_api.cpp 1970-01-01 00:00:00 +0000
+++ tests/acceptance-tests/test_client_trust_session_api.cpp 2014-05-09 12:26:43 +0000
@@ -0,0 +1,106 @@
1/*
2 * Copyright © 2013 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: Nick Dedekind <nick.dedekind@canonical.com>
17 */
18
19#include "mir_test_framework/display_server_test_fixture.h"
20
21#include "mir_toolkit/mir_client_library.h"
22#include "mir_toolkit/mir_trust_session.h"
23
24#include <gtest/gtest.h>
25
26namespace mtf = mir_test_framework;
27
28namespace
29{
30 char const* const mir_test_socket = mtf::test_socket_file().c_str();
31}
32
33using MirClientTrustSessionAPITest = DefaultDisplayServerTestFixture;
34
35namespace mir
36{
37namespace
38{
39struct ClientConfigCommon : TestingClientConfiguration
40{
41 ClientConfigCommon()
42 : connection(0)
43 , trust_session(0)
44 , started(0)
45 , stopped(0)
46 {
47 }
48
49 static void connection_callback(MirConnection * connection, void * context)
50 {
51 ClientConfigCommon * config = reinterpret_cast<ClientConfigCommon *>(context);
52 config->connection = connection;
53 }
54
55 virtual void connected(MirConnection * new_connection)
56 {
57 connection = new_connection;
58 }
59
60 static void trust_session_start_callback(MirTrustSession * session, void * context)
61 {
62 ClientConfigCommon * config = reinterpret_cast<ClientConfigCommon *>(context);
63 config->trust_session = session;
64 config->started++;
65 }
66
67 static void trust_session_stop_callback(MirTrustSession * /* session */, void * context)
68 {
69 ClientConfigCommon * config = reinterpret_cast<ClientConfigCommon *>(context);
70 config->stopped++;
71 }
72
73 MirConnection* connection;
74 MirTrustSession* trust_session;
75 int started;
76 int stopped;
77};
78}
79
80TEST_F(MirClientTrustSessionAPITest, client_trust_session_api)
81{
82 struct ClientConfig : ClientConfigCommon
83 {
84 void exec()
85 {
86 mir_wait_for(mir_connect(mir_test_socket, __PRETTY_FUNCTION__, connection_callback, this));
87
88 ASSERT_TRUE(connection != NULL);
89 EXPECT_TRUE(mir_connection_is_valid(connection));
90 EXPECT_STREQ("", mir_connection_get_error_message(connection));
91
92 mir_wait_for(mir_connection_start_trust_session(connection, __LINE__, trust_session_start_callback, NULL, this));
93 ASSERT_TRUE(trust_session != NULL);
94 EXPECT_EQ(started, 1);
95
96 mir_wait_for(mir_trust_session_stop(trust_session, trust_session_stop_callback, this));
97 EXPECT_EQ(stopped, 1);
98
99 mir_connection_release(connection);
100 }
101 } client_config;
102
103 launch_client_process(client_config);
104}
105
106}
0107
=== modified file 'tests/acceptance-tests/test_nested_mir.cpp'
--- tests/acceptance-tests/test_nested_mir.cpp 2014-03-06 06:05:17 +0000
+++ tests/acceptance-tests/test_nested_mir.cpp 2014-05-09 12:26:43 +0000
@@ -56,6 +56,9 @@
56 MOCK_METHOD1(session_next_buffer_called, void (std::string const&));56 MOCK_METHOD1(session_next_buffer_called, void (std::string const&));
57 MOCK_METHOD1(session_release_surface_called, void (std::string const&));57 MOCK_METHOD1(session_release_surface_called, void (std::string const&));
58 MOCK_METHOD1(session_disconnect_called, void (std::string const&));58 MOCK_METHOD1(session_disconnect_called, void (std::string const&));
59 MOCK_METHOD2(session_start_trust_session_called, void (std::string const&, std::string const&));
60 MOCK_METHOD2(session_add_trusted_session_called, void (std::string const&, std::string const&));
61 MOCK_METHOD1(session_stop_trust_session_called, void (std::string const&));
5962
60 void session_drm_auth_magic_called(const std::string&) override {};63 void session_drm_auth_magic_called(const std::string&) override {};
61 void session_configure_surface_called(std::string const&) override {};64 void session_configure_surface_called(std::string const&) override {};
6265
=== modified file 'tests/acceptance-tests/test_server_shutdown.cpp'
--- tests/acceptance-tests/test_server_shutdown.cpp 2014-05-09 03:00:20 +0000
+++ tests/acceptance-tests/test_server_shutdown.cpp 2014-05-09 12:26:43 +0000
@@ -117,6 +117,7 @@
117 std::string const flag_file;117 std::string const flag_file;
118};118};
119119
120<<<<<<< TREE
120struct FakeEventHubServerConfig : TestingServerConfiguration121struct FakeEventHubServerConfig : TestingServerConfiguration
121{122{
122 std::shared_ptr<mi::InputConfiguration> the_input_configuration() override123 std::shared_ptr<mi::InputConfiguration> the_input_configuration() override
@@ -157,6 +158,48 @@
157 std::shared_ptr<mtd::FakeEventHubInputConfiguration> input_configuration;158 std::shared_ptr<mtd::FakeEventHubInputConfiguration> input_configuration;
158};159};
159160
161=======
162struct FakeEventHubServerConfig : TestingServerConfiguration
163{
164 std::shared_ptr<mi::InputConfiguration> the_input_configuration() override
165 {
166 if (!input_configuration)
167 {
168 input_configuration =
169 std::make_shared<mtd::FakeEventHubInputConfiguration>(
170 the_composite_event_filter(),
171 the_input_region(),
172 std::shared_ptr<mi::CursorListener>(),
173 the_input_report());
174 }
175
176 return input_configuration;
177 }
178
179 std::shared_ptr<mi::InputManager> the_input_manager() override
180 {
181 return DefaultServerConfiguration::the_input_manager();
182 }
183
184 std::shared_ptr<mir::shell::InputTargeter> the_input_targeter() override
185 {
186 return DefaultServerConfiguration::the_input_targeter();
187 }
188 std::shared_ptr<mir::scene::InputRegistrar> the_input_registrar() override
189 {
190 return DefaultServerConfiguration::the_input_registrar();
191 }
192
193 mia::FakeEventHub* the_fake_event_hub()
194 {
195 the_input_configuration();
196 return input_configuration->the_fake_event_hub();
197 }
198
199 std::shared_ptr<mtd::FakeEventHubInputConfiguration> input_configuration;
200};
201
202>>>>>>> MERGE-SOURCE
160}203}
161204
162using ServerShutdown = BespokeDisplayServerTestFixture;205using ServerShutdown = BespokeDisplayServerTestFixture;
163206
=== modified file 'tests/integration-tests/frontend/test_application_mediator_report.cpp'
--- tests/integration-tests/frontend/test_application_mediator_report.cpp 2014-03-06 06:05:17 +0000
+++ tests/integration-tests/frontend/test_application_mediator_report.cpp 2014-05-09 12:26:43 +0000
@@ -50,6 +50,12 @@
5050
51 EXPECT_CALL(*this, session_disconnect_called(testing::_)).51 EXPECT_CALL(*this, session_disconnect_called(testing::_)).
52 Times(testing::AtLeast(0));52 Times(testing::AtLeast(0));
53
54 EXPECT_CALL(*this, session_start_trust_session_called(testing::_, testing::_)).
55 Times(testing::AtLeast(0));
56
57 EXPECT_CALL(*this, session_stop_trust_session_called(testing::_)).
58 Times(testing::AtLeast(0));
53 }59 }
5460
55 MOCK_METHOD1(session_connect_called, void (std::string const&));61 MOCK_METHOD1(session_connect_called, void (std::string const&));
@@ -57,6 +63,9 @@
57 MOCK_METHOD1(session_next_buffer_called, void (std::string const&));63 MOCK_METHOD1(session_next_buffer_called, void (std::string const&));
58 MOCK_METHOD1(session_release_surface_called, void (std::string const&));64 MOCK_METHOD1(session_release_surface_called, void (std::string const&));
59 MOCK_METHOD1(session_disconnect_called, void (std::string const&));65 MOCK_METHOD1(session_disconnect_called, void (std::string const&));
66 MOCK_METHOD2(session_start_trust_session_called, void (std::string const&, std::string const&));
67 MOCK_METHOD2(session_add_trusted_session_called, void (std::string const&, std::string const&));
68 MOCK_METHOD1(session_stop_trust_session_called, void (std::string const&));
6069
61 void session_drm_auth_magic_called(const std::string&) override {};70 void session_drm_auth_magic_called(const std::string&) override {};
62 void session_configure_surface_called(std::string const&) override {};71 void session_configure_surface_called(std::string const&) override {};
@@ -358,3 +367,175 @@
358367
359 launch_client_process(client_process);368 launch_client_process(client_process);
360}369}
370
371TEST_F(ApplicationMediatorReport, trust_session_start_called)
372{
373 struct Server : TestingServerConfiguration
374 {
375 std::shared_ptr<mf::SessionMediatorReport>
376 the_application_mediator_report()
377 {
378 auto result = std::make_shared<MockApplicationMediatorReport>();
379
380 EXPECT_CALL(*result, session_start_trust_session_called(testing::_, testing::_)).
381 Times(1);
382
383 return result;
384 }
385 } server_processing;
386
387 launch_server_process(server_processing);
388
389 struct Client: TestingClientConfiguration
390 {
391 void exec()
392 {
393 mt::TestProtobufClient client(mtf::test_socket_file(), rpc_timeout_ms);
394
395 client.connect_parameters.set_application_name(__PRETTY_FUNCTION__);
396 EXPECT_CALL(client, connect_done()).
397 Times(testing::AtLeast(0));
398 EXPECT_CALL(client, trust_session_start_done()).
399 Times(testing::AtLeast(0));
400
401 client.display_server.connect(
402 0,
403 &client.connect_parameters,
404 &client.connection,
405 google::protobuf::NewCallback(&client, &mt::TestProtobufClient::connect_done));
406
407 client.wait_for_connect_done();
408
409 client.display_server.start_trust_session(
410 0,
411 &client.trust_session_parameters,
412 &client.trust_session,
413 google::protobuf::NewCallback(&client, &mt::TestProtobufClient::trust_session_start_done));
414 client.wait_for_trust_session_start_done();
415
416 }
417 } client_process;
418
419 launch_client_process(client_process);
420}
421
422TEST_F(ApplicationMediatorReport, trust_session_add_trusted_session_called)
423{
424 struct Server : TestingServerConfiguration
425 {
426 std::shared_ptr<mf::SessionMediatorReport>
427 the_application_mediator_report()
428 {
429 auto result = std::make_shared<MockApplicationMediatorReport>();
430
431 EXPECT_CALL(*result, session_start_trust_session_called(testing::_, testing::_)).
432 Times(1);
433
434 return result;
435 }
436 } server_processing;
437
438 launch_server_process(server_processing);
439
440 struct Client: TestingClientConfiguration
441 {
442 void exec()
443 {
444 mt::TestProtobufClient client(mtf::test_socket_file(), rpc_timeout_ms);
445
446 client.connect_parameters.set_application_name(__PRETTY_FUNCTION__);
447 EXPECT_CALL(client, connect_done()).
448 Times(testing::AtLeast(0));
449 EXPECT_CALL(client, trust_session_start_done()).
450 Times(testing::AtLeast(0));
451 EXPECT_CALL(client, trust_session_add_trusted_session_done()).
452 Times(testing::AtLeast(0));
453
454 client.display_server.connect(
455 0,
456 &client.connect_parameters,
457 &client.connection,
458 google::protobuf::NewCallback(&client, &mt::TestProtobufClient::connect_done));
459
460 client.wait_for_connect_done();
461
462 client.display_server.start_trust_session(
463 0,
464 &client.trust_session_parameters,
465 &client.trust_session,
466 google::protobuf::NewCallback(&client, &mt::TestProtobufClient::trust_session_start_done));
467 client.wait_for_trust_session_start_done();
468
469 client.display_server.add_trusted_session(
470 0,
471 &client.trusted_session,
472 &client.add_trust_result,
473 google::protobuf::NewCallback(&client, &mt::TestProtobufClient::trust_session_add_trusted_session_done));
474 client.wait_for_trust_session_add_trusted_session_done();
475
476 }
477 } client_process;
478
479 launch_client_process(client_process);
480}
481
482TEST_F(ApplicationMediatorReport, trust_session_stop_called)
483{
484 struct Server : TestingServerConfiguration
485 {
486 std::shared_ptr<mf::SessionMediatorReport>
487 the_application_mediator_report()
488 {
489 auto result = std::make_shared<MockApplicationMediatorReport>();
490
491 EXPECT_CALL(*result, session_stop_trust_session_called(testing::_)).
492 Times(1);
493
494 return result;
495 }
496 } server_processing;
497
498 launch_server_process(server_processing);
499
500 struct Client: TestingClientConfiguration
501 {
502 void exec()
503 {
504 mt::TestProtobufClient client(mtf::test_socket_file(), rpc_timeout_ms);
505
506 client.connect_parameters.set_application_name(__PRETTY_FUNCTION__);
507 EXPECT_CALL(client, connect_done()).
508 Times(testing::AtLeast(0));
509 EXPECT_CALL(client, trust_session_start_done()).
510 Times(testing::AtLeast(0));
511 EXPECT_CALL(client, trust_session_stop_done()).
512 Times(testing::AtLeast(0));
513
514 client.display_server.connect(
515 0,
516 &client.connect_parameters,
517 &client.connection,
518 google::protobuf::NewCallback(&client, &mt::TestProtobufClient::connect_done));
519
520 client.wait_for_connect_done();
521
522 client.display_server.start_trust_session(
523 0,
524 &client.trust_session_parameters,
525 &client.trust_session,
526 google::protobuf::NewCallback(&client, &mt::TestProtobufClient::trust_session_start_done));
527 client.wait_for_trust_session_start_done();
528
529 client.display_server.stop_trust_session(
530 0,
531 &client.ignored,
532 &client.ignored,
533 google::protobuf::NewCallback(&client, &mt::TestProtobufClient::trust_session_stop_done));
534 client.wait_for_trust_session_stop_done();
535 }
536 } client_process;
537
538 launch_client_process(client_process);
539}
540
541
361542
=== modified file 'tests/integration-tests/test_display_server_main_loop_events.cpp'
=== modified file 'tests/integration-tests/test_session_manager.cpp'
--- tests/integration-tests/test_session_manager.cpp 2014-04-15 05:31:19 +0000
+++ tests/integration-tests/test_session_manager.cpp 2014-05-09 12:26:43 +0000
@@ -24,6 +24,7 @@
24#include "mir/compositor/buffer_stream.h"24#include "mir/compositor/buffer_stream.h"
25#include "src/server/scene/basic_surface.h"25#include "src/server/scene/basic_surface.h"
26#include "mir/scene/surface_creation_parameters.h"26#include "mir/scene/surface_creation_parameters.h"
27#include "mir/scene/null_trust_session_listener.h"
2728
28#include "mir_test/gmock_fixes.h"29#include "mir_test/gmock_fixes.h"
29#include "mir_test/fake_shared.h"30#include "mir_test/fake_shared.h"
@@ -55,7 +56,8 @@
55 mt::fake_shared(focus_setter),56 mt::fake_shared(focus_setter),
56 std::make_shared<mtd::NullSnapshotStrategy>(),57 std::make_shared<mtd::NullSnapshotStrategy>(),
57 std::make_shared<mtd::NullSessionEventSink>(),58 std::make_shared<mtd::NullSessionEventSink>(),
58 mt::fake_shared(session_listener))59 mt::fake_shared(session_listener),
60 std::make_shared<ms::NullTrustSessionListener>())
59 {61 {
6062
61 }63 }
6264
=== modified file 'tests/mir_test_doubles/test_protobuf_client.cpp'
--- tests/mir_test_doubles/test_protobuf_client.cpp 2014-03-06 06:05:17 +0000
+++ tests/mir_test_doubles/test_protobuf_client.cpp 2014-05-09 12:26:43 +0000
@@ -22,6 +22,7 @@
22#include "src/client/connection_surface_map.h"22#include "src/client/connection_surface_map.h"
23#include "src/client/display_configuration.h"23#include "src/client/display_configuration.h"
24#include "src/client/lifecycle_control.h"24#include "src/client/lifecycle_control.h"
25#include "src/client/event_distributor.h"
25#include "src/client/rpc/make_rpc_channel.h"26#include "src/client/rpc/make_rpc_channel.h"
26#include "src/client/rpc/mir_basic_rpc_channel.h"27#include "src/client/rpc/mir_basic_rpc_channel.h"
2728
@@ -38,7 +39,8 @@
38 std::make_shared<mir::client::ConnectionSurfaceMap>(),39 std::make_shared<mir::client::ConnectionSurfaceMap>(),
39 std::make_shared<mir::client::DisplayConfiguration>(),40 std::make_shared<mir::client::DisplayConfiguration>(),
40 rpc_report,41 rpc_report,
41 std::make_shared<mir::client::LifecycleControl>())),42 std::make_shared<mir::client::LifecycleControl>(),
43 std::make_shared<mir::client::EventDistributor>())),
42 display_server(channel.get(), ::google::protobuf::Service::STUB_DOESNT_OWN_CHANNEL),44 display_server(channel.get(), ::google::protobuf::Service::STUB_DOESNT_OWN_CHANNEL),
43 maxwait(timeout_ms),45 maxwait(timeout_ms),
44 connect_done_called(false),46 connect_done_called(false),
@@ -59,6 +61,9 @@
59 surface_parameters.set_buffer_usage(0);61 surface_parameters.set_buffer_usage(0);
60 surface_parameters.set_output_id(mir_display_output_id_invalid);62 surface_parameters.set_output_id(mir_display_output_id_invalid);
6163
64 trusted_session.set_pid(__LINE__);
65 trust_session_parameters.mutable_base_trusted_session()->set_pid(__LINE__);
66
62 ON_CALL(*this, connect_done())67 ON_CALL(*this, connect_done())
63 .WillByDefault(testing::Invoke(this, &TestProtobufClient::on_connect_done));68 .WillByDefault(testing::Invoke(this, &TestProtobufClient::on_connect_done));
64 ON_CALL(*this, create_surface_done())69 ON_CALL(*this, create_surface_done())
@@ -73,6 +78,12 @@
73 .WillByDefault(testing::Invoke(this, &TestProtobufClient::on_drm_auth_magic_done));78 .WillByDefault(testing::Invoke(this, &TestProtobufClient::on_drm_auth_magic_done));
74 ON_CALL(*this, display_configure_done())79 ON_CALL(*this, display_configure_done())
75 .WillByDefault(testing::Invoke(this, &TestProtobufClient::on_configure_display_done));80 .WillByDefault(testing::Invoke(this, &TestProtobufClient::on_configure_display_done));
81 ON_CALL(*this, trust_session_start_done())
82 .WillByDefault(testing::Invoke(&wc_trust_session_start, &WaitCondition::wake_up_everyone));
83 ON_CALL(*this, trust_session_add_trusted_session_done())
84 .WillByDefault(testing::Invoke(&wc_trust_session_add, &WaitCondition::wake_up_everyone));
85 ON_CALL(*this, trust_session_stop_done())
86 .WillByDefault(testing::Invoke(&wc_trust_session_stop, &WaitCondition::wake_up_everyone));
76}87}
7788
78void mir::test::TestProtobufClient::on_connect_done()89void mir::test::TestProtobufClient::on_connect_done()
@@ -225,3 +236,18 @@
225 }236 }
226 tfd_done_called.store(false);237 tfd_done_called.store(false);
227}238}
239
240void mir::test::TestProtobufClient::wait_for_trust_session_start_done()
241{
242 wc_trust_session_start.wait_for_at_most_seconds(maxwait);
243}
244
245void mir::test::TestProtobufClient::wait_for_trust_session_add_trusted_session_done()
246{
247 wc_trust_session_add.wait_for_at_most_seconds(maxwait);
248}
249
250void mir::test::TestProtobufClient::wait_for_trust_session_stop_done()
251{
252 wc_trust_session_stop.wait_for_at_most_seconds(maxwait);
253}
228254
=== modified file 'tests/unit-tests/client/CMakeLists.txt'
--- tests/unit-tests/client/CMakeLists.txt 2014-03-06 06:05:17 +0000
+++ tests/unit-tests/client/CMakeLists.txt 2014-05-09 12:26:43 +0000
@@ -8,6 +8,7 @@
8 ${CMAKE_CURRENT_SOURCE_DIR}/test_wait_handle.cpp8 ${CMAKE_CURRENT_SOURCE_DIR}/test_wait_handle.cpp
9 ${CMAKE_CURRENT_SOURCE_DIR}/test_client_display_conf.cpp9 ${CMAKE_CURRENT_SOURCE_DIR}/test_client_display_conf.cpp
10 ${CMAKE_CURRENT_SOURCE_DIR}/test_mir_screencast.cpp10 ${CMAKE_CURRENT_SOURCE_DIR}/test_mir_screencast.cpp
11 ${CMAKE_CURRENT_SOURCE_DIR}/test_mir_trust_session.cpp
11)12)
1213
13if(MIR_TEST_PLATFORM STREQUAL "android")14if(MIR_TEST_PLATFORM STREQUAL "android")
1415
=== added file 'tests/unit-tests/client/test_mir_trust_session.cpp'
--- tests/unit-tests/client/test_mir_trust_session.cpp 1970-01-01 00:00:00 +0000
+++ tests/unit-tests/client/test_mir_trust_session.cpp 2014-05-09 12:26:43 +0000
@@ -0,0 +1,244 @@
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: Nick Dedekind <nick.dedekind <nick.dedekind@canonical.com>
17 */
18
19#include "src/client/mir_trust_session.h"
20#include "src/client/event_distributor.h"
21
22#include <gtest/gtest.h>
23#include <gmock/gmock.h>
24
25#include <thread>
26
27namespace mcl = mir::client;
28
29namespace google
30{
31namespace protobuf
32{
33class RpcController;
34}
35}
36
37namespace
38{
39
40struct MockProtobufServer : mir::protobuf::DisplayServer
41{
42
43 MOCK_METHOD4(start_trust_session,
44 void(::google::protobuf::RpcController* /*controller*/,
45 ::mir::protobuf::TrustSessionParameters const* /*request*/,
46 ::mir::protobuf::TrustSession* /*response*/,
47 ::google::protobuf::Closure* /*done*/));
48
49 MOCK_METHOD4(add_trusted_session,
50 void(::google::protobuf::RpcController* /*controller*/,
51 const ::mir::protobuf::TrustedSession* /*request*/,
52 ::mir::protobuf::TrustSessionAddResult* /*response*/,
53 ::google::protobuf::Closure* /*done*/));
54
55 MOCK_METHOD4(stop_trust_session,
56 void(::google::protobuf::RpcController* /*controller*/,
57 ::mir::protobuf::Void const* /*request*/,
58 ::mir::protobuf::Void* /*response*/,
59 ::google::protobuf::Closure* /*done*/));
60};
61
62class StubProtobufServer : public mir::protobuf::DisplayServer
63{
64public:
65 void start_trust_session(::google::protobuf::RpcController* /*controller*/,
66 ::mir::protobuf::TrustSessionParameters const* /*request*/,
67 ::mir::protobuf::TrustSession* response,
68 ::google::protobuf::Closure* done) override
69 {
70 if (server_thread.joinable())
71 server_thread.join();
72 server_thread = std::thread{
73 [response, done, this]
74 {
75 response->clear_error();
76 done->Run();
77 }};
78 }
79
80 void add_trusted_session(::google::protobuf::RpcController* /*controller*/,
81 const ::mir::protobuf::TrustedSession* /*request*/,
82 ::mir::protobuf::TrustSessionAddResult* /*response*/,
83 ::google::protobuf::Closure* done)
84 {
85 if (server_thread.joinable())
86 server_thread.join();
87 server_thread = std::thread{[done, this] { done->Run(); }};
88 }
89
90 void stop_trust_session(::google::protobuf::RpcController* /*controller*/,
91 mir::protobuf::Void const* /*request*/,
92 ::mir::protobuf::Void* /*response*/,
93 ::google::protobuf::Closure* done) override
94 {
95 if (server_thread.joinable())
96 server_thread.join();
97 server_thread = std::thread{[done, this] { done->Run(); }};
98 }
99
100 StubProtobufServer()
101 {
102 }
103
104 ~StubProtobufServer()
105 {
106 if (server_thread.joinable())
107 server_thread.join();
108 }
109
110private:
111 std::thread server_thread;
112};
113
114class MirTrustSessionTest : public testing::Test
115{
116public:
117 MirTrustSessionTest()
118 : event_distributor{std::make_shared<mcl::EventDistributor>()}
119 {
120 }
121
122 static void trust_session_event(MirTrustSession*, MirTrustSessionState new_state, void* context)
123 {
124 MirTrustSessionTest* test = static_cast<MirTrustSessionTest*>(context);
125 test->state_updated(new_state);
126 }
127
128 MOCK_METHOD1(state_updated, void(MirTrustSessionState));
129
130 testing::NiceMock<MockProtobufServer> mock_server;
131 StubProtobufServer stub_server;
132 std::shared_ptr<mcl::EventDistributor> event_distributor;
133};
134
135struct MockCallback
136{
137 MOCK_METHOD2(call, void(void*, void*));
138};
139
140void mock_callback_func(MirTrustSession* trust_session, void* context)
141{
142 auto mock_cb = static_cast<MockCallback*>(context);
143 mock_cb->call(trust_session, context);
144}
145
146void null_callback_func(MirTrustSession*, void*)
147{
148}
149
150ACTION(RunClosure)
151{
152 arg3->Run();
153}
154
155}
156
157TEST_F(MirTrustSessionTest, start_trust_session)
158{
159 using namespace testing;
160
161 EXPECT_CALL(mock_server,
162 start_trust_session(_,_,_,_))
163 .WillOnce(RunClosure());
164
165 MirTrustSession trust_session{
166 mock_server,
167 event_distributor};
168 trust_session.start(__LINE__, null_callback_func, nullptr);
169}
170
171TEST_F(MirTrustSessionTest, stop_trust_session)
172{
173 using namespace testing;
174
175 EXPECT_CALL(mock_server,
176 stop_trust_session(_,_,_,_))
177 .WillOnce(RunClosure());
178
179 MirTrustSession trust_session{
180 mock_server,
181 event_distributor};
182 trust_session.stop(null_callback_func, nullptr);
183}
184
185TEST_F(MirTrustSessionTest, executes_callback_on_start)
186{
187 using namespace testing;
188
189 MockCallback mock_cb;
190 EXPECT_CALL(mock_cb, call(_, &mock_cb));
191
192 MirTrustSession trust_session{
193 stub_server,
194 event_distributor};
195 trust_session.start(__LINE__, mock_callback_func, &mock_cb)->wait_for_all();
196}
197
198TEST_F(MirTrustSessionTest, executes_callback_on_stop)
199{
200 using namespace testing;
201
202 MockCallback mock_cb;
203 EXPECT_CALL(mock_cb, call(_, &mock_cb));
204
205 MirTrustSession trust_session{
206 stub_server,
207 event_distributor};
208 trust_session.stop(mock_callback_func, &mock_cb)->wait_for_all();
209}
210
211TEST_F(MirTrustSessionTest, state_change_event_handler_started)
212{
213 using namespace testing;
214
215 MirTrustSession trust_session{
216 mock_server,
217 event_distributor};
218 trust_session.register_trust_session_event_callback(&MirTrustSessionTest::trust_session_event, this);
219
220 EXPECT_CALL(*this, state_updated(mir_trust_session_state_started)).Times(1);
221
222 MirEvent e;
223 e.type = mir_event_type_trust_session_state_change;
224 e.trust_session.new_state = mir_trust_session_state_started;
225 event_distributor->handle_event(e);
226}
227
228TEST_F(MirTrustSessionTest, state_change_event_handler_stopped)
229{
230 using namespace testing;
231
232 MirTrustSession trust_session{
233 mock_server,
234 event_distributor};
235 trust_session.register_trust_session_event_callback(&MirTrustSessionTest::trust_session_event, this);
236
237 EXPECT_CALL(*this, state_updated(mir_trust_session_state_stopped)).Times(1);
238
239 MirEvent e;
240 e.type = mir_event_type_trust_session_state_change;
241 e.trust_session.new_state = mir_trust_session_state_stopped;
242 event_distributor->handle_event(e);
243}
244
0245
=== modified file 'tests/unit-tests/frontend/stress_protobuf_communicator.cpp'
--- tests/unit-tests/frontend/stress_protobuf_communicator.cpp 2014-03-06 06:05:17 +0000
+++ tests/unit-tests/frontend/stress_protobuf_communicator.cpp 2014-05-09 12:26:43 +0000
@@ -28,6 +28,7 @@
28#include "src/client/connection_surface_map.h"28#include "src/client/connection_surface_map.h"
29#include "src/client/display_configuration.h"29#include "src/client/display_configuration.h"
30#include "src/client/lifecycle_control.h"30#include "src/client/lifecycle_control.h"
31#include "src/client/event_distributor.h"
31#include "src/client/rpc/null_rpc_report.h"32#include "src/client/rpc/null_rpc_report.h"
32#include "src/client/rpc/make_rpc_channel.h"33#include "src/client/rpc/make_rpc_channel.h"
33#include "src/client/rpc/mir_basic_rpc_channel.h"34#include "src/client/rpc/mir_basic_rpc_channel.h"
@@ -178,7 +179,8 @@
178 std::make_shared<mir::client::ConnectionSurfaceMap>(),179 std::make_shared<mir::client::ConnectionSurfaceMap>(),
179 std::make_shared<mir::client::DisplayConfiguration>(),180 std::make_shared<mir::client::DisplayConfiguration>(),
180 rpc_report,181 rpc_report,
181 std::make_shared<mir::client::LifecycleControl>())),182 std::make_shared<mir::client::LifecycleControl>(),
183 std::make_shared<mir::client::EventDistributor>())),
182 display_server(channel.get(), ::google::protobuf::Service::STUB_DOESNT_OWN_CHANNEL),184 display_server(channel.get(), ::google::protobuf::Service::STUB_DOESNT_OWN_CHANNEL),
183 maxwait(timeout_ms),185 maxwait(timeout_ms),
184 connect_done_called(false),186 connect_done_called(false),
185187
=== modified file 'tests/unit-tests/frontend/test_session_mediator.cpp'
--- tests/unit-tests/frontend/test_session_mediator.cpp 2014-05-09 11:01:53 +0000
+++ tests/unit-tests/frontend/test_session_mediator.cpp 2014-05-09 12:26:43 +0000
@@ -713,6 +713,7 @@
713 EXPECT_EQ(stub_buffer.id().as_uint32_t(),713 EXPECT_EQ(stub_buffer.id().as_uint32_t(),
714 protobuf_buffer.buffer_id());714 protobuf_buffer.buffer_id());
715}715}
716<<<<<<< TREE
716717
717TEST_F(SessionMediatorTest, client_socket_fd_calls_connector_client_socket_fd)718TEST_F(SessionMediatorTest, client_socket_fd_calls_connector_client_socket_fd)
718{719{
@@ -762,3 +763,54 @@
762763
763 mediator.disconnect(nullptr, nullptr, nullptr, null_callback.get());764 mediator.disconnect(nullptr, nullptr, nullptr, null_callback.get());
764}765}
766=======
767
768TEST_F(SessionMediatorTest, client_socket_fd_calls_connector_client_socket_fd)
769{
770 const int fd_count = 1;
771 const int dummy_fd = __LINE__;
772
773 mp::ConnectParameters connect_parameters;
774 mp::Connection connection;
775
776 mediator.connect(nullptr, &connect_parameters, &connection, null_callback.get());
777
778 ::mir::protobuf::SocketFDRequest request;
779 ::mir::protobuf::SocketFD response;
780 request.set_number(1);
781
782 using namespace ::testing;
783
784 EXPECT_CALL(connector, client_socket_fd(_)).Times(1).WillOnce(Return(dummy_fd));
785 mediator.new_fds_for_trusted_clients(nullptr, &request, &response, null_callback.get());
786
787 EXPECT_THAT(response.fd_size(), Eq(fd_count));
788 EXPECT_THAT(response.fd(0), Eq(dummy_fd));
789
790 mediator.disconnect(nullptr, nullptr, nullptr, null_callback.get());
791}
792
793TEST_F(SessionMediatorTest, client_socket_fd_allocates_requested_number_of_fds)
794{
795 const int fd_count = 11;
796 const int dummy_fd = __LINE__;
797
798 mp::ConnectParameters connect_parameters;
799 mp::Connection connection;
800
801 mediator.connect(nullptr, &connect_parameters, &connection, null_callback.get());
802
803 ::mir::protobuf::SocketFDRequest request;
804 ::mir::protobuf::SocketFD response;
805 request.set_number(fd_count);
806
807 using namespace ::testing;
808
809 EXPECT_CALL(connector, client_socket_fd(_)).Times(fd_count).WillRepeatedly(Return(dummy_fd));
810 mediator.new_fds_for_trusted_clients(nullptr, &request, &response, null_callback.get());
811
812 EXPECT_THAT(response.fd_size(), Eq(fd_count));
813
814 mediator.disconnect(nullptr, nullptr, nullptr, null_callback.get());
815}
816>>>>>>> MERGE-SOURCE
765817
=== added file 'tests/unit-tests/graphics/mesa/test_drm_helper.cpp.moved'
--- tests/unit-tests/graphics/mesa/test_drm_helper.cpp.moved 1970-01-01 00:00:00 +0000
+++ tests/unit-tests/graphics/mesa/test_drm_helper.cpp.moved 2014-05-09 12:26:43 +0000
@@ -0,0 +1,65 @@
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: Alexandros Frantzis <alexandros.frantzis@canonical.com>
17 */
18
19#include "src/platform/graphics/mesa/display_helpers.h"
20#include "mir/udev/wrapper.h"
21
22#include "mir_test_framework/udev_environment.h"
23#include "mir_test_doubles/mock_drm.h"
24
25#include <fcntl.h>
26
27#include <gtest/gtest.h>
28#include <gmock/gmock.h>
29
30namespace mgm = mir::graphics::mesa;
31namespace mtf = mir::mir_test_framework;
32namespace mtd = mir::test::doubles;
33
34namespace
35{
36
37MATCHER_P(FlagSet, flag, "")
38{
39 return (arg & flag);
40}
41
42class DRMHelperTest : public ::testing::Test
43{
44public:
45 DRMHelperTest()
46 {
47 fake_devices.add_standard_device("standard-drm-devices");
48 }
49
50protected:
51 ::testing::NiceMock<mtd::MockDRM> mock_drm;
52 mtf::UdevEnvironment fake_devices;
53};
54
55}
56
57TEST_F(DRMHelperTest, closes_drm_fd_on_exec)
58{
59 using namespace testing;
60
61 EXPECT_CALL(mock_drm, open(_, FlagSet(O_CLOEXEC), _));
62
63 mgm::helpers::DRMHelper drm_helper;
64 drm_helper.setup(std::make_shared<mir::udev::Context>());
65}
066
=== modified file 'tests/unit-tests/scene/CMakeLists.txt'
--- tests/unit-tests/scene/CMakeLists.txt 2014-05-06 06:16:13 +0000
+++ tests/unit-tests/scene/CMakeLists.txt 2014-05-09 12:26:43 +0000
@@ -9,6 +9,7 @@
9 ${CMAKE_CURRENT_SOURCE_DIR}/test_the_session_container_implementation.cpp9 ${CMAKE_CURRENT_SOURCE_DIR}/test_the_session_container_implementation.cpp
10 ${CMAKE_CURRENT_SOURCE_DIR}/test_threaded_snapshot_strategy.cpp10 ${CMAKE_CURRENT_SOURCE_DIR}/test_threaded_snapshot_strategy.cpp
11 ${CMAKE_CURRENT_SOURCE_DIR}/test_mediating_display_changer.cpp11 ${CMAKE_CURRENT_SOURCE_DIR}/test_mediating_display_changer.cpp
12 ${CMAKE_CURRENT_SOURCE_DIR}/test_trust_session.cpp
1213
13 ${CMAKE_CURRENT_SOURCE_DIR}/test_surface.cpp14 ${CMAKE_CURRENT_SOURCE_DIR}/test_surface.cpp
14 ${CMAKE_CURRENT_SOURCE_DIR}/test_surface_impl.cpp15 ${CMAKE_CURRENT_SOURCE_DIR}/test_surface_impl.cpp
1516
=== modified file 'tests/unit-tests/scene/test_application_session.cpp'
--- tests/unit-tests/scene/test_application_session.cpp 2014-04-15 10:19:19 +0000
+++ tests/unit-tests/scene/test_application_session.cpp 2014-05-09 12:26:43 +0000
@@ -27,6 +27,7 @@
27#include "mir_test_doubles/stub_display_configuration.h"27#include "mir_test_doubles/stub_display_configuration.h"
28#include "mir_test_doubles/null_snapshot_strategy.h"28#include "mir_test_doubles/null_snapshot_strategy.h"
29#include "mir_test_doubles/null_event_sink.h"29#include "mir_test_doubles/null_event_sink.h"
30#include "mir_test_doubles/null_trust_session.h"
3031
31#include <gmock/gmock.h>32#include <gmock/gmock.h>
32#include <gtest/gtest.h>33#include <gtest/gtest.h>
@@ -70,6 +71,10 @@
70 arg.stride == mir::geometry::Stride{} &&71 arg.stride == mir::geometry::Stride{} &&
71 arg.pixels == nullptr;72 arg.pixels == nullptr;
72}73}
74
75MATCHER_P(EqTrustedEventState, state, "") {
76 return arg.type == mir_event_type_trust_session_state_change && arg.trust_session.new_state == state;
77}
73}78}
7479
75TEST(ApplicationSession, create_and_destroy_surface)80TEST(ApplicationSession, create_and_destroy_surface)
@@ -380,3 +385,43 @@
380385
381 EXPECT_THAT(app_session.process_id(), Eq(pid));386 EXPECT_THAT(app_session.process_id(), Eq(pid));
382}387}
388
389TEST(ApplicationSession, begin_trust_session)
390{
391 using namespace ::testing;
392
393 mtd::MockSurfaceCoordinator surface_coordinator;
394 MockEventSink sender;
395
396 ms::ApplicationSession app_session(
397 mt::fake_shared(surface_coordinator),
398 __LINE__,
399 "Foo",
400 std::make_shared<mtd::NullSnapshotStrategy>(),
401 std::make_shared<ms::NullSessionListener>(),
402 mt::fake_shared(sender));
403
404 EXPECT_CALL(sender, handle_event(EqTrustedEventState(mir_trust_session_state_started))).Times(1);
405
406 app_session.begin_trust_session();
407}
408
409TEST(ApplicationSession, end_trust_session)
410{
411 using namespace ::testing;
412
413 mtd::MockSurfaceCoordinator surface_coordinator;
414 MockEventSink sender;
415
416 ms::ApplicationSession app_session(
417 mt::fake_shared(surface_coordinator),
418 __LINE__,
419 "Foo",
420 std::make_shared<mtd::NullSnapshotStrategy>(),
421 std::make_shared<ms::NullSessionListener>(),
422 mt::fake_shared(sender));
423
424 EXPECT_CALL(sender, handle_event(EqTrustedEventState(mir_trust_session_state_stopped))).Times(1);
425
426 app_session.end_trust_session();
427}
383428
=== modified file 'tests/unit-tests/scene/test_session_manager.cpp'
--- tests/unit-tests/scene/test_session_manager.cpp 2014-04-15 10:19:19 +0000
+++ tests/unit-tests/scene/test_session_manager.cpp 2014-05-09 12:26:43 +0000
@@ -27,6 +27,9 @@
27#include "src/server/scene/session_event_sink.h"27#include "src/server/scene/session_event_sink.h"
28#include "src/server/scene/basic_surface.h"28#include "src/server/scene/basic_surface.h"
29#include "src/server/report/null_report_factory.h"29#include "src/server/report/null_report_factory.h"
30#include "mir/scene/trust_session_creation_parameters.h"
31#include "mir/scene/null_trust_session_listener.h"
32#include "mir/scene/trust_session.h"
3033
31#include "mir_test/fake_shared.h"34#include "mir_test/fake_shared.h"
32#include "mir_test_doubles/mock_buffer_stream.h"35#include "mir_test_doubles/mock_buffer_stream.h"
@@ -37,6 +40,8 @@
37#include "mir_test_doubles/null_snapshot_strategy.h"40#include "mir_test_doubles/null_snapshot_strategy.h"
38#include "mir_test_doubles/null_surface_configurator.h"41#include "mir_test_doubles/null_surface_configurator.h"
39#include "mir_test_doubles/null_session_event_sink.h"42#include "mir_test_doubles/null_session_event_sink.h"
43#include "mir_test_doubles/mock_trust_session_listener.h"
44#include "mir_test_doubles/null_event_sink.h"
4045
41#include <gmock/gmock.h>46#include <gmock/gmock.h>
42#include <gtest/gtest.h>47#include <gtest/gtest.h>
@@ -44,7 +49,6 @@
44namespace mc = mir::compositor;49namespace mc = mir::compositor;
45namespace mf = mir::frontend;50namespace mf = mir::frontend;
46namespace mi = mir::input;51namespace mi = mir::input;
47namespace msh = mir::shell;
48namespace ms = mir::scene;52namespace ms = mir::scene;
49namespace geom = mir::geometry;53namespace geom = mir::geometry;
50namespace mt = mir::test;54namespace mt = mir::test;
@@ -78,7 +82,8 @@
78 mt::fake_shared(focus_setter),82 mt::fake_shared(focus_setter),
79 std::make_shared<mtd::NullSnapshotStrategy>(),83 std::make_shared<mtd::NullSnapshotStrategy>(),
80 std::make_shared<mtd::NullSessionEventSink>(),84 std::make_shared<mtd::NullSessionEventSink>(),
81 mt::fake_shared(session_listener))85 mt::fake_shared(session_listener),
86 std::make_shared<ms::NullTrustSessionListener>())
82 {87 {
83 using namespace ::testing;88 using namespace ::testing;
84 ON_CALL(container, successor_of(_)).WillByDefault(Return((std::shared_ptr<ms::Session>())));89 ON_CALL(container, successor_of(_)).WillByDefault(Return((std::shared_ptr<ms::Session>())));
@@ -178,7 +183,8 @@
178 mt::fake_shared(focus_setter),183 mt::fake_shared(focus_setter),
179 std::make_shared<mtd::NullSnapshotStrategy>(),184 std::make_shared<mtd::NullSnapshotStrategy>(),
180 std::make_shared<mtd::NullSessionEventSink>(),185 std::make_shared<mtd::NullSessionEventSink>(),
181 mt::fake_shared(session_listener))186 mt::fake_shared(session_listener),
187 std::make_shared<ms::NullTrustSessionListener>())
182 {188 {
183 using namespace ::testing;189 using namespace ::testing;
184 ON_CALL(container, successor_of(_)).WillByDefault(Return((std::shared_ptr<ms::Session>())));190 ON_CALL(container, successor_of(_)).WillByDefault(Return((std::shared_ptr<ms::Session>())));
@@ -187,7 +193,7 @@
187 mtd::MockSurfaceCoordinator surface_coordinator;193 mtd::MockSurfaceCoordinator surface_coordinator;
188 testing::NiceMock<MockSessionContainer> container; // Inelegant but some tests need a stub194 testing::NiceMock<MockSessionContainer> container; // Inelegant but some tests need a stub
189 testing::NiceMock<mtd::MockFocusSetter> focus_setter; // Inelegant but some tests need a stub195 testing::NiceMock<mtd::MockFocusSetter> focus_setter; // Inelegant but some tests need a stub
190 mtd::MockSessionListener session_listener;196 testing::NiceMock<mtd::MockSessionListener> session_listener;
191197
192 ms::SessionManager session_manager;198 ms::SessionManager session_manager;
193};199};
@@ -217,7 +223,8 @@
217 mt::fake_shared(focus_setter),223 mt::fake_shared(focus_setter),
218 std::make_shared<mtd::NullSnapshotStrategy>(),224 std::make_shared<mtd::NullSnapshotStrategy>(),
219 mt::fake_shared(session_event_sink),225 mt::fake_shared(session_event_sink),
220 std::make_shared<ms::NullSessionListener>())226 std::make_shared<ms::NullSessionListener>(),
227 std::make_shared<ms::NullTrustSessionListener>())
221 {228 {
222 using namespace ::testing;229 using namespace ::testing;
223 ON_CALL(container, successor_of(_)).WillByDefault(Return((std::shared_ptr<ms::Session>())));230 ON_CALL(container, successor_of(_)).WillByDefault(Return((std::shared_ptr<ms::Session>())));
@@ -257,3 +264,46 @@
257 session_manager.close_session(session1);264 session_manager.close_session(session1);
258 session_manager.close_session(session);265 session_manager.close_session(session);
259}266}
267
268namespace
269{
270
271struct SessionManagerTrustSessionListenerSetup : public testing::Test
272{
273 SessionManagerTrustSessionListenerSetup()
274 : session_manager(mt::fake_shared(surface_coordinator),
275 mt::fake_shared(container),
276 mt::fake_shared(focus_setter),
277 std::make_shared<mtd::NullSnapshotStrategy>(),
278 std::make_shared<mtd::NullSessionEventSink>(),
279 std::make_shared<ms::NullSessionListener>(),
280 mt::fake_shared(trust_session_listener))
281 {
282 using namespace ::testing;
283 ON_CALL(container, successor_of(_)).WillByDefault(Return((std::shared_ptr<ms::Session>())));
284 }
285
286 mtd::MockSurfaceCoordinator surface_coordinator;
287 testing::NiceMock<MockSessionContainer> container; // Inelegant but some tests need a stub
288 testing::NiceMock<mtd::MockFocusSetter> focus_setter; // Inelegant but some tests need a stub
289 testing::NiceMock<mtd::MockTrustSessionListener> trust_session_listener;
290 mtd::NullEventSink event_sink;
291
292 ms::SessionManager session_manager;
293};
294}
295
296TEST_F(SessionManagerTrustSessionListenerSetup, trust_session_listener_is_notified_of_trust_session_start_and_stop)
297{
298 using namespace ::testing;
299
300 EXPECT_CALL(trust_session_listener, starting(_)).Times(1);
301 EXPECT_CALL(trust_session_listener, stopping(_)).Times(1);
302
303 auto helper = session_manager.open_session(__LINE__, "XPlane", mt::fake_shared(event_sink));
304
305 ms::TrustSessionCreationParameters parameters;
306
307 auto trust_session = session_manager.start_trust_session_for(helper, parameters);
308 session_manager.stop_trust_session(trust_session);
309}
260310
=== added file 'tests/unit-tests/scene/test_trust_session.cpp'
--- tests/unit-tests/scene/test_trust_session.cpp 1970-01-01 00:00:00 +0000
+++ tests/unit-tests/scene/test_trust_session.cpp 2014-05-09 12:26:43 +0000
@@ -0,0 +1,73 @@
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: Nick Dedekind <nick.dedekind@canonical.com>
17 */
18
19#include "mir/frontend/event_sink.h"
20#include "mir/scene/trust_session_creation_parameters.h"
21#include "src/server/scene/trust_session_impl.h"
22#include "mir_test/fake_shared.h"
23#include "mir_test_doubles/mock_scene_session.h"
24#include "mir_test_doubles/mock_trust_session_listener.h"
25
26#include <gmock/gmock.h>
27#include <gtest/gtest.h>
28
29namespace mf = mir::frontend;
30namespace ms = mir::scene;
31namespace mt = mir::test;
32namespace mtd = mir::test::doubles;
33
34
35namespace
36{
37
38struct TrustSession : public testing::Test
39{
40 TrustSession()
41 {
42 }
43
44 testing::NiceMock<mtd::MockTrustSessionListener> trust_session_listener;
45 testing::NiceMock<mtd::MockSceneSession> trusted_helper;
46 testing::NiceMock<mtd::MockSceneSession> trusted_app1;
47};
48}
49
50TEST_F(TrustSession, start_and_stop)
51{
52 using namespace testing;
53
54 EXPECT_CALL(trusted_helper, begin_trust_session()).Times(1);
55 EXPECT_CALL(trusted_helper, end_trust_session()).Times(1);
56
57 EXPECT_CALL(trusted_app1, begin_trust_session()).Times(0);
58 EXPECT_CALL(trusted_app1, end_trust_session()).Times(0);
59
60 EXPECT_CALL(trust_session_listener, trusted_session_beginning(_,_)).Times(1);
61 EXPECT_CALL(trust_session_listener, trusted_session_ending(_,_)).Times(1);
62
63 auto shared_helper = mt::fake_shared(trusted_helper);
64 auto shared_app1 = mt::fake_shared(trusted_app1);
65
66 ms::TrustSessionImpl trust_session(shared_helper,
67 ms::a_trust_session(),
68 mt::fake_shared(trust_session_listener));
69
70 trust_session.start();
71 trust_session.add_trusted_child(shared_app1);
72 trust_session.stop();
73}

Subscribers

People subscribed via source and target branches