Merge lp:~nick-dedekind/mir/trusted_sessions into lp:mir
- trusted_sessions
- Merge into development-branch
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 |
Related bugs: |
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".
Alan Griffiths (alan-griffiths) wrote : | # |
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1397
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:/
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Daniel van Vugt (vanvugt) wrote : | # |
Wow, so much code. This will take a while...
(1) One quick note:
1196 +MirTrustedSession* mir_trusted_
The pattern we use is "NAMESPACE_
MirTrustedS
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.
Daniel van Vugt (vanvugt) wrote : | # |
(2) Quick requirements/
Nick Dedekind (nick-dedekind) wrote : | # |
> Wow, so much code. This will take a while...
>
> (1) One quick note:
> 1196 +MirTrustedSession* mir_trusted_
> connection)
> The pattern we use is "NAMESPACE_
> MirTrustedSession* mir_connection_
> 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:/
Nick Dedekind (nick-dedekind) wrote : | # |
> (2) Quick requirements/
> 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.
Nick Dedekind (nick-dedekind) wrote : | # |
> > Wow, so much code. This will take a while...
> >
> > (1) One quick note:
> > 1196 +MirTrustedSession* mir_trusted_
> > connection)
> > The pattern we use is "NAMESPACE_
> > MirTrustedSession* mir_connection_
> > 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:/
In retrospect, it's actually a "trust session". I'll change that.
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:/
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
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:/
>
> Accordingly, I get bogged down in details like:
>
> @SessionId - why is this useful (compared to, say,
> std::[shared|
:/ 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_
>
> @TrustedSession
> 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/
>
> 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.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1401
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1403
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
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_
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_
becomes:
MirTrustSession* mir_connection_
(2) Please put the details/
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_
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_
renamed to mir_trust_
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1405
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
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_
should be renamed to follow the existing convention:
MirTrustSession* mir_connection_
(2) Please expand on the commit message/description further. It's still too brief for a large enhancement.
(3) Please remove "handle_
(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_
(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/
(10) frontend/
(11) MirTrustSession
(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:
But now I notice how simple mir::client:
(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_
(17) test_trust_
Alexandros Frantzis (afrantzis) wrote : | # |
A first pass...
Since mir_client_
1. Public header file goes in mir_toolkit/
2. C API implementation goes in src/client/
3. Internal classes as usual, src/client/
148 +///\page trust_session.c trust_session.c: A mir client which starts a trust session and trusted client app.
149 +/// mir_demo_
150 +/// This program opens a mir connection and creates a trust session.
...
519 + virtual std::shared_
520 + std::shared_
Since this is a C file, the C(/Javadoc) format is preferred, like in the public files.
519 + virtual std::shared_
520 + std::shared_
...
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_
1256 + void* context)
1272 + reinterpret_
1273 + (assign_result),
1274 + NULL));
1279 + mir_trust_
1280 + void* context)
1296 + reinterpret_
1297 + (assign_result),
1298 + NULL));
1308 + mir_trust_
1309 + void* context)
Either use a 4-space indentation or align with char after '(' on previous line.
1427 + [this]
1428 + (MirTrustSessio
1501 + [this, callback, context]
1502 + (MirTrustSessio
2771 + [this]
2772 + (std::shared_
We tend to prefer to keep the parameter list on the same line as the capture list:
[this] (MirTrustSessio
1430 + std::lock_
Why do we need a recursive mutex?
1595 + MirTrustSession
1600 + MirTrustSession
1601 + MirTrustSession& operator=
... and others in the class
* and & go with the type (or 'const' if there is one).
1820 + std::unique_
Since the lock is not used with condition variables or moved, we could use the simpler std::lock_guard<>.
1814 +mcl::TrustSess
1815 +{
1816 +}
Is this needed?
2737 + TrustSession* impl = new TrustSession(
2738 + std::shared_
auto const trust_session = std::make_
Nick Dedekind (nick-dedekind) 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_
> connection);
> should be renamed to follow the existing convention:
> MirTrustSession* mir_connection_
> 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_
> 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::EventDistr
>
> (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_
> is "mir_demo_
> 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/
> 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/
> 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/
Which essentially is implicit start on creation. Can't do what we need from a member start.
>
> (11) MirTrustSession
> 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 ...
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1416
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Nick Dedekind (nick-dedekind) wrote : | # |
> A first pass...
>
> Since mir_client_
> follow the convention mir_screencast is using, i.e.:
>
> 1. Public header file goes in mir_toolkit/
> 2. C API implementation goes in src/client/
> 3. Internal classes as usual, src/client/
Done
>
> 148 +///\page trust_session.c trust_session.c: A mir client which starts a
> trust session and trusted client app.
> 149 +/// mir_demo_
> API.
> 150 +/// This program opens a mir connection and creates a trust session.
> ...
>
> 519 + virtual std::shared_
> start_trust_
> 520 + std::shared_
>
> 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_
> start_trust_
> 520 + std::shared_
> ...
>
> 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_
> 1256 + void* context)
>
> 1272 + reinterpret_
> 1273 + (assign_result),
> 1274 + NULL));
>
> 1279 + mir_trust_
> 1280 + void* context)
>
> 1296 + reinterpret_
> 1297 + (assign_result),
> 1298 + NULL));
>
> 1308 + mir_trust_
> 1309 + void* context)
>
> Either use a 4-space indentation or align with char after '(' on previous
> line.
>
> 1427 + [this]
> 1428 + (MirTrustSessio
>
> 1501 + [this, callback, context]
> 1502 + (MirTrustSessio
>
> 2771 + [this]
> 2772 + (std::shared_
>
> We tend to prefer to keep the parameter list on the same line as the capture
> list:
> [this] (MirTrustSessio
> AFAIK.
Must have picked it up on some other project. Switched to single line
>
> 1430 + std::lock_
>
> Why do we need a recursive mutex?
Changed already
>
> 1595 + MirTrustSession
> 1600 + MirTrustSession
> 1601 + MirTrustSession& operator=
> ... and others in the class
>
> * and & go with the type (or 'const' if there is one).
Done
>
> 1820 + std::unique_
>
> Since the lock is not used with condition...
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1417
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1418
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1419
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1420
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1420
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Alan Griffiths (alan-griffiths) wrote : | # |
2919 + * Copyright © 2013 Canonical Ltd.
Surely 2014 deserves a mention?
~~~~
534 === renamed file 'src/server/
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::
Oh, I see: it has an entirely new use with shell::
In this instance, for example, in TrustSession:
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.
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.
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:/
(I myself would have preferred a different approach, where an app could add itself to an existing session)
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:
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:/
>
> (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.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1421
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
FAILURE: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1422
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
FAILURE: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1422
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
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_
...
stop_trust_
...
start_trust_
...
stop_trust_
Alan Griffiths (alan-griffiths) wrote : | # |
532 === renamed file 'src/server/
[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_
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_
1906 + [&e](MirSurface* surface)
1907 + {
1908 + surface-
1909 + });
1910 + }
1911 + catch (std::exception const& x)
1912 + {
1913 + rpc_report-
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_
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.
Nick Dedekind (nick-dedekind) wrote : | # |
Moved the relationship information to the trust session, rather than being a property of the session itself.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1426
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
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/
Text conflict in src/client/
Text conflict in src/client/
Text conflict in src/client/
Text conflict in src/server/
Text conflict in src/server/
Text conflict in tests/unit-
Text conflict in tests/unit-
Text conflict in tests/unit-
11 conflicts encountered.
Nick Dedekind (nick-dedekind) wrote : | # |
Fixed conflicts.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1427
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Daniel van Vugt (vanvugt) wrote : | # |
(18) Spurious (old) changes to debian/changelog have now crept in.
Daniel van Vugt (vanvugt) wrote : | # |
(19) Conflict:
Text conflict in tests/unit-
1 conflicts encountered.
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:
void Window:
The first one for actually doing the reparenting work, and the latter to decide who can do that (besides unconfined apps).
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.
Nick Dedekind (nick-dedekind) 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:
> void Window:
> 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...
Nick Dedekind (nick-dedekind) wrote : | # |
Maybe quite a few changes.
1) The mir_trust_
use case:
Gallery -> ContentHub -> Facebook/
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 TrustSessionLis
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.
Alan Griffiths (alan-griffiths) wrote : | # |
Looking at the client API:
MirTrustSes
I would expect "create_
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_
Is there any reason to separate out these create/
~~~~
mir_trust_
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_
~~~~
mir_trust_
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?
Alan Griffiths (alan-griffiths) wrote : | # |
std::shared_
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.
Alan Griffiths (alan-griffiths) wrote : | # |
bool shell::
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.
Alan Griffiths (alan-griffiths) wrote : | # |
In TrustSession:
But AIUI the child isn't the "helper" process that created the trust session and can't have registered a mir_trust_
Alan Griffiths (alan-griffiths) wrote : | # |
+class TrustSession
+{
+public:
+ virtual ~TrustSession() = default;
+
+ virtual void for_each_
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::TrustSessio
+{
+}
Alan Griffiths (alan-griffiths) wrote : | # |
+class TrustSessionLis
+{
+public:
+ virtual void starting(
+ virtual void stopping(
+
+ virtual void trusted_
+ virtual void trusted_
The listener shouldn't be given any ownership of the referenced objects. So the prototypes should be:
virtual void starting(
virtual void stopping(
virtual void trusted_
virtual void trusted_
Nick Dedekind (nick-dedekind) wrote : | # |
> Looking at the client API:
>
> MirTrustSession* mir_connection_
> connection);
>
> I would expect "create_
> 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_
>
> Is there any reason to separate out these create/
> 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_
Not sure if the stop/release should be separate now. Left as is for now.
>
> ~~~~
>
> mir_trust_
>
> 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_
> 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_
>
> 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.
Nick Dedekind (nick-dedekind) wrote : | # |
> std::shared_
> error,
> std::shared_
> shell::
>
> 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.
Nick Dedekind (nick-dedekind) wrote : | # |
> In TrustSession:
> "session-
> mir_event_
>
> But AIUI the child isn't the "helper" process that created the trust session
> and can't have registered a mir_trust_
> 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.
Nick Dedekind (nick-dedekind) wrote : | # |
> +class TrustSession
> +{
> +public:
> + virtual ~TrustSession() = default;
> +
> + virtual void for_each_
> 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::TrustSessio
> pid)>, bool) const
> +{
> +}
old code from before the process<
removed.
Nick Dedekind (nick-dedekind) wrote : | # |
> +class TrustSessionLis
> +{
> +public:
> + virtual void starting(
> = 0;
> + virtual void stopping(
> = 0;
> +
> + virtual void trusted_
> std::shared_
> + virtual void trusted_
> std::shared_
>
> The listener shouldn't be given any ownership of the referenced objects. So
> the prototypes should be:
>
> virtual void starting(
> virtual void stopping(
>
> virtual void trusted_
> Session const& session) = 0;
> virtual void trusted_
> const& session) = 0;
changed.
Preview Diff
1 | === modified file 'examples/CMakeLists.txt' |
2 | --- examples/CMakeLists.txt 2014-05-05 03:36:45 +0000 |
3 | +++ examples/CMakeLists.txt 2014-05-09 12:26:43 +0000 |
4 | @@ -92,6 +92,9 @@ |
5 | |
6 | ) |
7 | |
8 | +add_executable(mir_demo_client_trust_session trust_session.c) |
9 | +target_link_libraries(mir_demo_client_trust_session mirclient) |
10 | + |
11 | add_library(mirdraw STATIC graphics_utils.cpp) |
12 | target_link_libraries(mirdraw ${GLESv2_LIBRARIES}) |
13 | |
14 | @@ -143,7 +146,7 @@ |
15 | server_configuration.cpp |
16 | ) |
17 | |
18 | -target_link_libraries(mir_demo_standalone_input_filter |
19 | +target_link_libraries(mir_demo_standalone_input_filter |
20 | mirserver |
21 | ) |
22 | |
23 | @@ -158,8 +161,9 @@ |
24 | mir_demo_client_multiwin |
25 | mir_demo_client_display_config |
26 | mir_demo_client_progressbar |
27 | + mir_demo_client_trust_session |
28 | mir_demo_standalone_input_filter |
29 | - mir_demo_standalone_render_to_fb |
30 | + mir_demo_standalone_render_to_fb |
31 | mir_demo_standalone_render_surfaces |
32 | ) |
33 | |
34 | |
35 | === modified file 'examples/demo-inprocess-surface-client/inprocess_egl_client.cpp' |
36 | --- examples/demo-inprocess-surface-client/inprocess_egl_client.cpp 2014-04-15 05:31:19 +0000 |
37 | +++ examples/demo-inprocess-surface-client/inprocess_egl_client.cpp 2014-05-09 12:26:43 +0000 |
38 | @@ -102,7 +102,7 @@ |
39 | |
40 | auto input_platform = mircv::InputPlatform::create(); |
41 | input_thread = input_platform->create_input_thread( |
42 | - surface->client_input_fd(), |
43 | + surface->client_input_fd(), |
44 | std::bind(std::mem_fn(&me::InprocessEGLClient::handle_event), this, std::placeholders::_1)); |
45 | input_thread->start(); |
46 | |
47 | |
48 | === modified file 'examples/fingerpaint.c' |
49 | === added file 'examples/trust_session.c' |
50 | --- examples/trust_session.c 1970-01-01 00:00:00 +0000 |
51 | +++ examples/trust_session.c 2014-05-09 12:26:43 +0000 |
52 | @@ -0,0 +1,249 @@ |
53 | +/* |
54 | + * Copyright © 2014 Canonical Ltd. |
55 | + * |
56 | + * This program is free software: you can redistribute it and/or modify |
57 | + * it under the terms of the GNU General Public License version 3 as |
58 | + * published by the Free Software Foundation. |
59 | + * |
60 | + * This program is distributed in the hope that it will be useful, |
61 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
62 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
63 | + * GNU General Public License for more details. |
64 | + * |
65 | + * You should have received a copy of the GNU General Public License |
66 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
67 | + * |
68 | + * Authored by: Nick Dedekind <nick.dedekind <nick.dedekind@canonical.com> |
69 | + */ |
70 | + |
71 | +#define _POSIX_SOURCE |
72 | + |
73 | +#include "mir_toolkit/mir_client_library.h" |
74 | +#include "mir_toolkit/mir_trust_session.h" |
75 | + |
76 | +#include <assert.h> |
77 | +#include <string.h> |
78 | +#include <stdio.h> |
79 | +#include <stdlib.h> |
80 | +#include <getopt.h> |
81 | +#include <unistd.h> |
82 | +#include <errno.h> |
83 | +#include <sys/wait.h> |
84 | +#include <sys/types.h> |
85 | +#include <signal.h> |
86 | + |
87 | +///\page trust_session.c trust_session.c: A mir client which starts a trust session and trusted client app. |
88 | +/// mir_demo_client_trust_session shows the use of mir trust session API. |
89 | +/// This program opens a mir connection and creates a trust session. |
90 | +///\section trusted_helper trusted_helper() |
91 | +/// Opens a mir connection and creates a trust session |
92 | +/// before closing the trust session and connection. |
93 | +///\section trust_session_app trust_session_app() |
94 | +/// Opens a mir connection and creates a surface |
95 | +/// before releasing the surface and closing the connection. |
96 | +///\example trust_session.c A mir client demonstrating trust sessions. |
97 | +///\section MirDemoState MirDemoState |
98 | +/// The handles needs to be accessible both to callbacks and to the control function. |
99 | +///\snippet trust_session.c MirDemoState_tag |
100 | +///\section Callbacks Callbacks |
101 | +///\snippet trust_session.c Callback_tag |
102 | +/// This program creates two processes, both opening a mir connection, one starting |
103 | +/// a trust session with the other process. |
104 | + |
105 | +///\internal [MirDemoState_tag] |
106 | +// Utility structure for the state of a single session. |
107 | +typedef struct MirDemoState |
108 | +{ |
109 | + MirConnection *connection; |
110 | + MirSurface *surface; |
111 | + MirTrustSession *trust_session; |
112 | + pid_t child_pid; |
113 | +} MirDemoState; |
114 | +///\internal [MirDemoState_tag] |
115 | + |
116 | + |
117 | +///\internal [Callback_tag] |
118 | +// Callback to update MirDemoState on trust_session_event |
119 | +static void trust_session_event_callback(MirTrustSession* trust_session, |
120 | + MirTrustSessionState state, |
121 | + void* context) |
122 | +{ |
123 | + (void)trust_session; |
124 | + MirDemoState* demo_state = (MirDemoState*)context; |
125 | + |
126 | + printf("Trust Session state updated to %d\n", state); |
127 | + if (state == mir_trust_session_state_stopped) |
128 | + { |
129 | + kill(demo_state->child_pid, SIGINT); |
130 | + } |
131 | +} |
132 | +///\internal [Callback_tag] |
133 | + |
134 | +void start_session(const char* server, const char* name, MirDemoState* mcd) |
135 | +{ |
136 | + // Call mir_connect synchronously |
137 | + mcd->connection = mir_connect_sync(server, name); |
138 | + |
139 | + // We expect a connection handle; |
140 | + // we expect it to be valid; and, |
141 | + // we don't expect an error description |
142 | + assert(mcd->connection != NULL); |
143 | + assert(mir_connection_is_valid(mcd->connection)); |
144 | + assert(strcmp(mir_connection_get_error_message(mcd->connection), "") == 0); |
145 | + printf("%s: Connected\n", name); |
146 | + |
147 | + // We can query information about the platform we're running on |
148 | + { |
149 | + MirPlatformPackage platform_package; |
150 | + platform_package.data_items = -1; |
151 | + platform_package.fd_items = -1; |
152 | + |
153 | + mir_connection_get_platform(mcd->connection, &platform_package); |
154 | + assert(0 <= platform_package.data_items); |
155 | + assert(0 <= platform_package.fd_items); |
156 | + } |
157 | +} |
158 | + |
159 | +void stop_session(MirDemoState* mcd, const char* name) |
160 | +{ |
161 | + if (mcd->trust_session) |
162 | + { |
163 | + mir_trust_session_release(mcd->trust_session); |
164 | + mcd->trust_session = 0; |
165 | + printf("%s: Trust session released \n", name); |
166 | + } |
167 | + |
168 | + if (mcd->surface) |
169 | + { |
170 | + // We should release our surface |
171 | + mir_surface_release_sync(mcd->surface); |
172 | + mcd->surface = 0; |
173 | + printf("%s: Surface released\n", name); |
174 | + } |
175 | + |
176 | + // We should release our connection |
177 | + mir_connection_release(mcd->connection); |
178 | + printf("%s: Connection released\n", name); |
179 | +} |
180 | + |
181 | +void trusted_helper(const char* server, pid_t child_pid) |
182 | +{ |
183 | + MirDemoState mcd; |
184 | + mcd.connection = 0; |
185 | + mcd.surface = 0; |
186 | + mcd.trust_session = 0; |
187 | + mcd.child_pid = child_pid; |
188 | + start_session(server, "trusted_helper", &mcd); |
189 | + |
190 | + // We create a trust session |
191 | + mcd.trust_session = mir_connection_start_trust_session_sync(mcd.connection, getpid(), trust_session_event_callback, &mcd); |
192 | + assert(mcd.trust_session != NULL); |
193 | + |
194 | + assert(mir_trust_session_get_state(mcd.trust_session) == mir_trust_session_state_started); |
195 | + puts("trusted_helper: Started trust session"); |
196 | + |
197 | + MirTrustSessionAddTrustResult add_result = mir_trust_session_add_trusted_session_sync(mcd.trust_session, child_pid); |
198 | + assert(add_result == mir_trust_session_add_tust_succeeded); |
199 | + printf("trusted_helper: added trusted session pid: %d\n", child_pid); |
200 | + |
201 | + int status; |
202 | + printf("trusted_helper: waiting on child app: %d\n", child_pid); |
203 | + waitpid(child_pid, &status, 0); |
204 | + |
205 | + if (mir_trust_session_get_state(mcd.trust_session) == mir_trust_session_state_started) |
206 | + { |
207 | + mir_trust_session_stop_sync(mcd.trust_session); |
208 | + assert(mir_trust_session_get_state(mcd.trust_session) == mir_trust_session_state_stopped); |
209 | + puts("trusted_helper: Stopped trust session"); |
210 | + } |
211 | + else |
212 | + { |
213 | + puts("trusted_helper: Trusted session stoped by server"); |
214 | + } |
215 | + puts("trusted_helper: Done"); |
216 | + |
217 | + stop_session(&mcd, "trusted_helper"); |
218 | +} |
219 | + |
220 | +void trust_session_app(const char* server) |
221 | +{ |
222 | + MirDemoState mcd; |
223 | + mcd.connection = 0; |
224 | + mcd.surface = 0; |
225 | + mcd.trust_session = 0; |
226 | + start_session(server, "trust_session_app", &mcd); |
227 | + |
228 | + // Identify a supported pixel format |
229 | + MirPixelFormat pixel_format; |
230 | + unsigned int valid_formats; |
231 | + mir_connection_get_available_surface_formats(mcd.connection, &pixel_format, 1, &valid_formats); |
232 | + MirSurfaceParameters const request_params = |
233 | + {__PRETTY_FUNCTION__, 640, 480, pixel_format, |
234 | + mir_buffer_usage_hardware, mir_display_output_id_invalid}; |
235 | + |
236 | + // ...we create a surface using that format and wait for callback to complete. |
237 | + mcd.surface = mir_connection_create_surface_sync(mcd.connection, &request_params); |
238 | + |
239 | + // We expect a surface handle; |
240 | + // we expect it to be valid; and, |
241 | + // we don't expect an error description |
242 | + assert(mcd.surface != NULL); |
243 | + assert(mir_surface_is_valid(mcd.surface)); |
244 | + assert(strcmp(mir_surface_get_error_message(mcd.surface), "") == 0); |
245 | + puts("trust_session_app: Surface created"); |
246 | + |
247 | + puts("trust_session_app: Press any key to exit"); |
248 | + // Wait for stdin |
249 | + getchar(); |
250 | + puts("trust_session_app: Done"); |
251 | + |
252 | + stop_session(&mcd, "trust_session_app"); |
253 | +} |
254 | + |
255 | +// The main() function deals with parsing arguments and defaults |
256 | +int main(int argc, char* argv[]) |
257 | +{ |
258 | + // Some variables for holding command line options |
259 | + char const *server = NULL; |
260 | + |
261 | + // Parse the command line |
262 | + { |
263 | + int arg; |
264 | + opterr = 0; |
265 | + while ((arg = getopt (argc, argv, "c:hm:")) != -1) |
266 | + { |
267 | + switch (arg) |
268 | + { |
269 | + case 'm': |
270 | + server = optarg; |
271 | + break; |
272 | + |
273 | + case '?': |
274 | + case 'h': |
275 | + default: |
276 | + puts(argv[0]); |
277 | + puts("Usage:"); |
278 | + puts(" -m <Mir server socket>"); |
279 | + puts(" -h: this help text"); |
280 | + return -1; |
281 | + } |
282 | + } |
283 | + } |
284 | + |
285 | + // Start a new process. |
286 | + // This simulates the helper starting a new application which it adds to the trusted session. |
287 | + pid_t pid = fork(); |
288 | + |
289 | + if (pid == 0) |
290 | + { |
291 | + sleep(1); |
292 | + trust_session_app(server); |
293 | + } |
294 | + else if (pid > 0) |
295 | + { |
296 | + printf("trusted_helper: pid:%d , child:%d\n", getpid(), pid); |
297 | + trusted_helper(server, pid); |
298 | + } |
299 | + |
300 | + return 0; |
301 | +} |
302 | |
303 | === added file 'include/client/mir_toolkit/mir_trust_session.h' |
304 | --- include/client/mir_toolkit/mir_trust_session.h 1970-01-01 00:00:00 +0000 |
305 | +++ include/client/mir_toolkit/mir_trust_session.h 2014-05-09 12:26:43 +0000 |
306 | @@ -0,0 +1,119 @@ |
307 | +/* |
308 | + * Copyright © 2014 Canonical Ltd. |
309 | + * |
310 | + * This program is free software: you can redistribute it and/or modify it |
311 | + * under the terms of the GNU Lesser General Public License version 3, |
312 | + * as published by the Free Software Foundation. |
313 | + * |
314 | + * This program is distributed in the hope that it will be useful, |
315 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
316 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
317 | + * GNU Lesser General Public License for more details. |
318 | + * |
319 | + * You should have received a copy of the GNU Lesser General Public License |
320 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
321 | + */ |
322 | + |
323 | +#ifndef MIR_TOOLKIT_MIR_TRUST_SESSION_H_ |
324 | +#define MIR_TOOLKIT_MIR_TRUST_SESSION_H_ |
325 | + |
326 | +#include "mir_toolkit/mir_client_library.h" |
327 | + |
328 | +#include <sys/types.h> |
329 | + |
330 | +#ifdef __cplusplus |
331 | +/** |
332 | + * \addtogroup mir_toolkit |
333 | + * @{ |
334 | + */ |
335 | +extern "C" { |
336 | +#endif |
337 | + |
338 | +/** |
339 | + * Create an new trust session |
340 | + * \param [in] connection The connection |
341 | + * \param [in] base_session_pid The process id of the initiating application |
342 | + * \param [in] start_callback Callback function to be invoked when request |
343 | + * completes |
344 | + * \param [in] start_callback The function to be called when the trust session event occurs |
345 | + * \param [in,out] context User data passed to the callback functions |
346 | + * \return A handle that can be passed to mir_wait_for |
347 | + */ |
348 | +MirWaitHandle *mir_connection_start_trust_session(MirConnection* connection, |
349 | + pid_t base_session_pid, |
350 | + mir_trust_session_callback start_callback, |
351 | + mir_trust_session_event_callback event_callback, |
352 | + void* context); |
353 | + |
354 | +/** |
355 | + * Create an new trust session |
356 | + * \param [in] connection The connection |
357 | + * \param [in] base_session_pid The process id of the initiating application |
358 | + * \param [in] callback Callback function to be invoked when request |
359 | + * completes |
360 | + * \param [in,out] context User data passed to the callback function |
361 | + * \param [in] callback The function to be called when the trust session event occurs |
362 | + * \return A handle that can be passed to mir_wait_for |
363 | + */ |
364 | +MirTrustSession *mir_connection_start_trust_session_sync(MirConnection* connection, |
365 | + pid_t base_session_pid, |
366 | + mir_trust_session_event_callback event_callback, |
367 | + void* context); |
368 | + |
369 | +/** |
370 | + * Add a process id to the trust session relationship |
371 | + * \param [in] trust_session The trust session |
372 | + * \param [in] session_pid The process id of the application to add |
373 | + * \param [in] callback Callback function to be invoked when request |
374 | + * completes |
375 | + * \return A MirTrustSessionAddTrustResult result of the call |
376 | + */ |
377 | +MirWaitHandle *mir_trust_session_add_trusted_session(MirTrustSession *trust_session, |
378 | + pid_t session_pid, |
379 | + mir_trust_session_add_trusted_session_callback callback, |
380 | + void* context); |
381 | + |
382 | +/** |
383 | + * Perform a mir_trust_session_add_trusted_pid() but also wait for and return the result. |
384 | + * \param [in] trust_session The trust session |
385 | + * \param [in] pid The process id of the application to add |
386 | + * \return A MirTrustSessionAddTrustResult result of the call |
387 | + */ |
388 | +MirTrustSessionAddTrustResult mir_trust_session_add_trusted_session_sync(MirTrustSession *trust_session, |
389 | + pid_t pid); |
390 | + |
391 | +/** |
392 | + * Request the cancellation of a trust session |
393 | + * \param [in] trust_session The trust session |
394 | + * \return True if the request was made successfully, |
395 | + * false otherwise |
396 | + */ |
397 | +MirWaitHandle *mir_trust_session_stop(MirTrustSession *trust_session, mir_trust_session_callback callback, void* context); |
398 | + |
399 | +/** |
400 | + * Perform a mir_trust_session_stop() but also wait for and return the result. |
401 | + * \param [in] trust_session The trust session |
402 | + * \return True if the request was made successfully, |
403 | + * false otherwise |
404 | + */ |
405 | +MirBool mir_trust_session_stop_sync(MirTrustSession *trust_session); |
406 | + |
407 | +/** |
408 | + * Return the state of trust session |
409 | + * \param [in] trust_session The trust session |
410 | + * \return The state of the trust session |
411 | + */ |
412 | +MirTrustSessionState mir_trust_session_get_state(MirTrustSession *trust_session); |
413 | + |
414 | +/** |
415 | + * Release a trust session |
416 | + * \param [in] trust_session The trust session to release |
417 | + */ |
418 | +void mir_trust_session_release(MirTrustSession* trust_session); |
419 | + |
420 | +#ifdef __cplusplus |
421 | +} |
422 | +/**@}*/ |
423 | +#endif |
424 | + |
425 | +#endif /* MIR_TOOLKIT_MIR_TRUST_SESSION_H_ */ |
426 | |
427 | === modified file 'include/server/mir/default_server_configuration.h' |
428 | --- include/server/mir/default_server_configuration.h 2014-05-09 03:00:20 +0000 |
429 | +++ include/server/mir/default_server_configuration.h 2014-05-09 12:26:43 +0000 |
430 | @@ -83,6 +83,7 @@ |
431 | class SurfaceStack; |
432 | class InputRegistrar; |
433 | class SceneReport; |
434 | +class TrustSessionListener; |
435 | } |
436 | namespace graphics |
437 | { |
438 | @@ -212,6 +213,7 @@ |
439 | virtual std::shared_ptr<scene::PlacementStrategy> the_placement_strategy(); |
440 | virtual std::shared_ptr<scene::SessionListener> the_session_listener(); |
441 | virtual std::shared_ptr<shell::DisplayLayout> the_shell_display_layout(); |
442 | + virtual std::shared_ptr<scene::TrustSessionListener> the_trust_session_listener(); |
443 | /** @} */ |
444 | |
445 | /** @name internal scene configuration |
446 | @@ -322,6 +324,7 @@ |
447 | CachedPtr<scene::MediatingDisplayChanger> mediating_display_changer; |
448 | CachedPtr<graphics::GLProgramFactory> gl_program_factory; |
449 | CachedPtr<graphics::GLConfig> gl_config; |
450 | + CachedPtr<scene::TrustSessionListener> trust_session_listener; |
451 | |
452 | private: |
453 | std::shared_ptr<options::Configuration> const configuration_options; |
454 | |
455 | === modified file 'include/server/mir/frontend/connection_context.h' |
456 | --- include/server/mir/frontend/connection_context.h 2014-05-08 13:07:13 +0000 |
457 | +++ include/server/mir/frontend/connection_context.h 2014-05-09 12:26:43 +0000 |
458 | @@ -1,3 +1,4 @@ |
459 | +<<<<<<< TREE |
460 | /* |
461 | * Copyright © 2014 Canonical Ltd. |
462 | * |
463 | @@ -50,3 +51,60 @@ |
464 | } |
465 | |
466 | #endif /* MIR_FRONTEND_CONNECTION_CONTEXT_H_ */ |
467 | +======= |
468 | +/* |
469 | + * Copyright © 014 Canonical Ltd. |
470 | + * |
471 | + * This program is free software: you can redistribute it and/or modify it |
472 | + * under the terms of the GNU General Public License version 3, |
473 | + * as published by the Free Software Foundation. |
474 | + * |
475 | + * This program is distributed in the hope that it will be useful, |
476 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
477 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
478 | + * GNU General Public License for more details. |
479 | + * |
480 | + * You should have received a copy of the GNU General Public License |
481 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
482 | + * |
483 | + * Authored by: Alan Griffiths <alan@octopull.co.uk> |
484 | + */ |
485 | + |
486 | +#ifndef MIR_FRONTEND_CONNECTION_CONTEXT_H_ |
487 | +#define MIR_FRONTEND_CONNECTION_CONTEXT_H_ |
488 | + |
489 | +#include <functional> |
490 | +#include <memory> |
491 | + |
492 | +namespace mir |
493 | +{ |
494 | +namespace frontend |
495 | +{ |
496 | +class Connector; |
497 | +class Session; |
498 | + |
499 | +class ConnectionContext |
500 | +{ |
501 | +public: |
502 | + ConnectionContext() = delete; |
503 | + ConnectionContext(const ConnectionContext&) = default; |
504 | + ConnectionContext& operator=(const ConnectionContext&) = default; |
505 | + ConnectionContext(Connector const* connector) : |
506 | + ConnectionContext([](std::shared_ptr<Session> const&){}, connector) {} |
507 | + ConnectionContext( |
508 | + std::function<void(std::shared_ptr<Session> const& session)> const connect_handler, |
509 | + Connector const* connector); |
510 | + |
511 | + int fd_for_new_client(std::function<void(std::shared_ptr<Session> const& session)> const& connect_handler) const; |
512 | + |
513 | + void handle_client_connect(std::shared_ptr<Session> const& session) const { connect_handler(session); } |
514 | + |
515 | +private: |
516 | + std::function<void(std::shared_ptr<Session> const& session)> const connect_handler; |
517 | + Connector const* const connector; |
518 | +}; |
519 | +} |
520 | +} |
521 | + |
522 | +#endif /* MIR_FRONTEND_CONNECTION_CONTEXT_H_ */ |
523 | +>>>>>>> MERGE-SOURCE |
524 | |
525 | === modified file 'include/server/mir/frontend/event_sink.h' |
526 | --- include/server/mir/frontend/event_sink.h 2013-08-28 03:41:48 +0000 |
527 | +++ include/server/mir/frontend/event_sink.h 2014-05-09 12:26:43 +0000 |
528 | @@ -35,6 +35,8 @@ |
529 | virtual ~EventSink() = default; |
530 | |
531 | virtual void handle_event(MirEvent const& e) = 0; |
532 | + |
533 | + // TODO - remove these in favour of using handle_event |
534 | virtual void handle_lifecycle_event(MirLifecycleState state) = 0; |
535 | virtual void handle_display_config_change(graphics::DisplayConfiguration const& config) = 0; |
536 | |
537 | |
538 | === modified file 'include/server/mir/frontend/session.h' |
539 | --- include/server/mir/frontend/session.h 2014-05-06 16:54:43 +0000 |
540 | +++ include/server/mir/frontend/session.h 2014-05-09 12:26:43 +0000 |
541 | @@ -50,6 +50,7 @@ |
542 | virtual void destroy_surface(SurfaceId surface) = 0; |
543 | virtual std::shared_ptr<Surface> get_surface(SurfaceId surface) const = 0; |
544 | |
545 | + virtual pid_t process_id() const = 0; |
546 | virtual std::string name() const = 0; |
547 | |
548 | virtual void hide() = 0; |
549 | |
550 | === modified file 'include/server/mir/frontend/session_mediator_report.h' |
551 | --- include/server/mir/frontend/session_mediator_report.h 2014-03-06 06:05:17 +0000 |
552 | +++ include/server/mir/frontend/session_mediator_report.h 2014-05-09 12:26:43 +0000 |
553 | @@ -48,6 +48,12 @@ |
554 | |
555 | virtual void session_configure_display_called(std::string const& app_name) = 0; |
556 | |
557 | + virtual void session_start_trust_session_called(std::string const& app_name, std::string const& trust_info) = 0; |
558 | + |
559 | + virtual void session_add_trusted_session_called(std::string const& app_name, std::string const& trust_info) = 0; |
560 | + |
561 | + virtual void session_stop_trust_session_called(std::string const& app_name) = 0; |
562 | + |
563 | virtual void session_error( |
564 | std::string const& app_name, |
565 | char const* method, |
566 | |
567 | === modified file 'include/server/mir/frontend/shell.h' |
568 | --- include/server/mir/frontend/shell.h 2014-04-15 05:31:19 +0000 |
569 | +++ include/server/mir/frontend/shell.h 2014-05-09 12:26:43 +0000 |
570 | @@ -20,6 +20,7 @@ |
571 | #define MIR_FRONTEND_SHELL_H_ |
572 | |
573 | #include "mir/frontend/surface_id.h" |
574 | +#include "mir_toolkit/common.h" |
575 | |
576 | #include <sys/types.h> |
577 | |
578 | @@ -30,11 +31,13 @@ |
579 | namespace scene |
580 | { |
581 | struct SurfaceCreationParameters; |
582 | +struct TrustSessionCreationParameters; |
583 | } |
584 | namespace frontend |
585 | { |
586 | class EventSink; |
587 | class Session; |
588 | +class TrustSession; |
589 | |
590 | class Shell |
591 | { |
592 | @@ -54,6 +57,12 @@ |
593 | |
594 | virtual void handle_surface_created(std::shared_ptr<Session> const& session) = 0; |
595 | |
596 | + virtual std::shared_ptr<TrustSession> start_trust_session_for(std::shared_ptr<Session> const& session, |
597 | + scene::TrustSessionCreationParameters const& params) = 0; |
598 | + virtual MirTrustSessionAddTrustResult add_trusted_session_for(std::shared_ptr<TrustSession> const& trust_session, |
599 | + pid_t session_pid) = 0; |
600 | + virtual void stop_trust_session(std::shared_ptr<TrustSession> const& trust_session) = 0; |
601 | + |
602 | protected: |
603 | Shell() = default; |
604 | Shell(const Shell&) = delete; |
605 | |
606 | === added file 'include/server/mir/frontend/trust_session.h' |
607 | --- include/server/mir/frontend/trust_session.h 1970-01-01 00:00:00 +0000 |
608 | +++ include/server/mir/frontend/trust_session.h 2014-05-09 12:26:43 +0000 |
609 | @@ -0,0 +1,53 @@ |
610 | +/* |
611 | + * Copyright © 2014 Canonical Ltd. |
612 | + * |
613 | + * This program is free software: you can redistribute it and/or modify it |
614 | + * under the terms of the GNU General Public License version 3, |
615 | + * as published by the Free Software Foundation. |
616 | + * |
617 | + * This program is distributed in the hope that it will be useful, |
618 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
619 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
620 | + * GNU General Public License for more details. |
621 | + * |
622 | + * You should have received a copy of the GNU General Public License |
623 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
624 | + * |
625 | + * Authored By: Nick Dedekind <nick.dedekind@canonical.com> |
626 | + */ |
627 | + |
628 | +#ifndef MIR_FRONTEND_TRUST_SESSION_H_ |
629 | +#define MIR_FRONTEND_TRUST_SESSION_H_ |
630 | + |
631 | +#include "mir_toolkit/common.h" |
632 | + |
633 | +#include <sys/types.h> |
634 | +#include <vector> |
635 | +#include <string> |
636 | +#include <memory> |
637 | + |
638 | +namespace mir |
639 | +{ |
640 | + |
641 | +namespace frontend |
642 | +{ |
643 | +class TrustSession |
644 | +{ |
645 | +public: |
646 | + virtual ~TrustSession() = default; |
647 | + |
648 | + virtual MirTrustSessionState get_state() const = 0; |
649 | + |
650 | + virtual void start() = 0; |
651 | + virtual void stop() = 0; |
652 | + |
653 | +protected: |
654 | + TrustSession() = default; |
655 | + TrustSession(const TrustSession&) = delete; |
656 | + TrustSession& operator=(const TrustSession&) = delete; |
657 | +}; |
658 | + |
659 | +} |
660 | +} |
661 | + |
662 | +#endif // MIR_FRONTEND_TRUST_SESSION_H_ |
663 | |
664 | === added file 'include/server/mir/scene/null_trust_session_listener.h' |
665 | --- include/server/mir/scene/null_trust_session_listener.h 1970-01-01 00:00:00 +0000 |
666 | +++ include/server/mir/scene/null_trust_session_listener.h 2014-05-09 12:26:43 +0000 |
667 | @@ -0,0 +1,50 @@ |
668 | +/* |
669 | + * Copyright © 2014 Canonical Ltd. |
670 | + * |
671 | + * This program is free software: you can redistribute it and/or modify it |
672 | + * under the terms of the GNU General Public License version 3, |
673 | + * as published by the Free Software Foundation. |
674 | + * |
675 | + * This program is distributed in the hope that it will be useful, |
676 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
677 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
678 | + * GNU General Public License for more details. |
679 | + * |
680 | + * You should have received a copy of the GNU General Public License |
681 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
682 | + * |
683 | + * Authored By: Nick Dedekind <nick.dedekind@canonical.com> |
684 | + */ |
685 | + |
686 | +#ifndef MIR_SCENE_NULL_TRUST_SESSION_LISTENER_H_ |
687 | +#define MIR_SCENE_NULL_TRUST_SESSION_LISTENER_H_ |
688 | + |
689 | +#include "mir/scene/trust_session_listener.h" |
690 | + |
691 | +namespace mir |
692 | +{ |
693 | +namespace scene |
694 | +{ |
695 | + |
696 | +class NullTrustSessionListener : public TrustSessionListener |
697 | +{ |
698 | +public: |
699 | + NullTrustSessionListener() = default; |
700 | + virtual ~NullTrustSessionListener() noexcept(true) = default; |
701 | + |
702 | + void starting(TrustSession const&) override {}; |
703 | + void stopping(TrustSession const&) override {}; |
704 | + |
705 | + void trusted_session_beginning(TrustSession&, Session const&) override {}; |
706 | + void trusted_session_ending(TrustSession&, Session const&) override {}; |
707 | + |
708 | +protected: |
709 | + NullTrustSessionListener(const NullTrustSessionListener&) = delete; |
710 | + NullTrustSessionListener& operator=(const NullTrustSessionListener&) = delete; |
711 | +}; |
712 | + |
713 | +} |
714 | +} |
715 | + |
716 | + |
717 | +#endif // MIR_SHELL_NULL_TRUST_SESSION_LISTENER_H_ |
718 | |
719 | === modified file 'include/server/mir/scene/session.h' |
720 | --- include/server/mir/scene/session.h 2014-04-15 05:31:19 +0000 |
721 | +++ include/server/mir/scene/session.h 2014-05-09 12:26:43 +0000 |
722 | @@ -34,12 +34,14 @@ |
723 | { |
724 | public: |
725 | virtual void force_requests_to_complete() = 0; |
726 | - virtual pid_t process_id() const = 0; |
727 | |
728 | virtual void take_snapshot(SnapshotCallback const& snapshot_taken) = 0; |
729 | virtual std::shared_ptr<Surface> default_surface() const = 0; |
730 | virtual void set_lifecycle_state(MirLifecycleState state) = 0; |
731 | virtual void send_display_config(graphics::DisplayConfiguration const&) = 0; |
732 | + |
733 | + virtual void begin_trust_session() = 0; |
734 | + virtual void end_trust_session() = 0; |
735 | }; |
736 | } |
737 | } |
738 | |
739 | === added file 'include/server/mir/scene/trust_session.h' |
740 | --- include/server/mir/scene/trust_session.h 1970-01-01 00:00:00 +0000 |
741 | +++ include/server/mir/scene/trust_session.h 2014-05-09 12:26:43 +0000 |
742 | @@ -0,0 +1,43 @@ |
743 | +/* |
744 | + * Copyright © 2014 Canonical Ltd. |
745 | + * |
746 | + * This program is free software: you can redistribute it and/or modify it |
747 | + * under the terms of the GNU General Public License version 3, |
748 | + * as published by the Free Software Foundation. |
749 | + * |
750 | + * This program is distributed in the hope that it will be useful, |
751 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
752 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
753 | + * GNU General Public License for more details. |
754 | + * |
755 | + * You should have received a copy of the GNU General Public License |
756 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
757 | + * |
758 | + * Authored By: Nick Dedekind <nick.dedekind@canonical.com> |
759 | + */ |
760 | + |
761 | +#ifndef MIR_SCENE_TRUST_SESSION_H_ |
762 | +#define MIR_SCENE_TRUST_SESSION_H_ |
763 | + |
764 | +#include "mir/frontend/trust_session.h" |
765 | + |
766 | +namespace mir |
767 | +{ |
768 | +namespace scene |
769 | +{ |
770 | +class Session; |
771 | + |
772 | +class TrustSession : public frontend::TrustSession |
773 | +{ |
774 | +public: |
775 | + virtual std::weak_ptr<Session> get_trusted_helper() const = 0; |
776 | + |
777 | + virtual bool add_trusted_child(std::shared_ptr<Session> const& session) = 0; |
778 | + virtual void remove_trusted_child(std::shared_ptr<Session> const& session) = 0; |
779 | + virtual void for_each_trusted_child(std::function<void(std::shared_ptr<Session> const&)> f, bool reverse) const = 0; |
780 | +}; |
781 | + |
782 | +} |
783 | +} |
784 | + |
785 | +#endif // MIR_SHELL_TRUST_SESSION_H_ |
786 | |
787 | === added file 'include/server/mir/scene/trust_session_creation_parameters.h' |
788 | --- include/server/mir/scene/trust_session_creation_parameters.h 1970-01-01 00:00:00 +0000 |
789 | +++ include/server/mir/scene/trust_session_creation_parameters.h 2014-05-09 12:26:43 +0000 |
790 | @@ -0,0 +1,46 @@ |
791 | +/* |
792 | + * Copyright © 2014 Canonical Ltd. |
793 | + * |
794 | + * This program is free software: you can redistribute it and/or modify it |
795 | + * under the terms of the GNU General Public License version 3, |
796 | + * as published by the Free Software Foundation. |
797 | + * |
798 | + * This program is distributed in the hope that it will be useful, |
799 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
800 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
801 | + * GNU General Public License for more details. |
802 | + * |
803 | + * You should have received a copy of the GNU General Public License |
804 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
805 | + * |
806 | + * Authored By: Nick Dedekind <nick.dedekind@canonical.com> |
807 | + */ |
808 | + |
809 | +#ifndef MIR_SCENE_TRUSTED_SESSION_CREATION_PARAMETERS_H_ |
810 | +#define MIR_SCENE_TRUSTED_SESSION_CREATION_PARAMETERS_H_ |
811 | + |
812 | +#include <sys/types.h> |
813 | +#include <vector> |
814 | + |
815 | +namespace mir |
816 | +{ |
817 | +namespace scene |
818 | +{ |
819 | + |
820 | +struct TrustSessionCreationParameters |
821 | +{ |
822 | + TrustSessionCreationParameters(); |
823 | + |
824 | + TrustSessionCreationParameters& set_base_process_id(pid_t process_id); |
825 | + |
826 | + pid_t base_process_id; |
827 | +}; |
828 | + |
829 | +bool operator==(const TrustSessionCreationParameters& lhs, const TrustSessionCreationParameters& rhs); |
830 | +bool operator!=(const TrustSessionCreationParameters& lhs, const TrustSessionCreationParameters& rhs); |
831 | + |
832 | +TrustSessionCreationParameters a_trust_session(); |
833 | +} |
834 | +} |
835 | + |
836 | +#endif /* MIR_SCENE_TRUSTED_SESSION_CREATION_PARAMETERS_H_ */ |
837 | |
838 | === added file 'include/server/mir/scene/trust_session_listener.h' |
839 | --- include/server/mir/scene/trust_session_listener.h 1970-01-01 00:00:00 +0000 |
840 | +++ include/server/mir/scene/trust_session_listener.h 2014-05-09 12:26:43 +0000 |
841 | @@ -0,0 +1,52 @@ |
842 | +/* |
843 | + * Copyright © 2014 Canonical Ltd. |
844 | + * |
845 | + * This program is free software: you can redistribute it and/or modify it |
846 | + * under the terms of the GNU General Public License version 3, |
847 | + * as published by the Free Software Foundation. |
848 | + * |
849 | + * This program is distributed in the hope that it will be useful, |
850 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
851 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
852 | + * GNU General Public License for more details. |
853 | + * |
854 | + * You should have received a copy of the GNU General Public License |
855 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
856 | + * |
857 | + * Authored By: Nick Dedekind <nick.dedekind@canonical.com> |
858 | + */ |
859 | + |
860 | +#ifndef MIR_SCENE_TRUST_SESSION_LISTENER_H_ |
861 | +#define MIR_SCENE_TRUST_SESSION_LISTENER_H_ |
862 | + |
863 | +#include <memory> |
864 | + |
865 | +namespace mir |
866 | +{ |
867 | +namespace scene |
868 | +{ |
869 | +class Session; |
870 | +class TrustSession; |
871 | + |
872 | +class TrustSessionListener |
873 | +{ |
874 | +public: |
875 | + virtual void starting(TrustSession const& trust_session) = 0; |
876 | + virtual void stopping(TrustSession const& trust_session) = 0; |
877 | + |
878 | + virtual void trusted_session_beginning(TrustSession& trust_session, Session const& session) = 0; |
879 | + virtual void trusted_session_ending(TrustSession& trust_session, Session const& session) = 0; |
880 | + |
881 | +protected: |
882 | + TrustSessionListener() = default; |
883 | + virtual ~TrustSessionListener() = default; |
884 | + |
885 | + TrustSessionListener(const TrustSessionListener&) = delete; |
886 | + TrustSessionListener& operator=(const TrustSessionListener&) = delete; |
887 | +}; |
888 | + |
889 | +} |
890 | +} |
891 | + |
892 | + |
893 | +#endif // MIR_SCENE_TRUST_SESSION_LISTENER_H_ |
894 | |
895 | === modified file 'include/shared/mir_toolkit/client_types.h' |
896 | --- include/shared/mir_toolkit/client_types.h 2014-05-08 11:48:23 +0000 |
897 | +++ include/shared/mir_toolkit/client_types.h 2014-05-09 12:26:43 +0000 |
898 | @@ -46,6 +46,7 @@ |
899 | typedef struct MirConnection MirConnection; |
900 | typedef struct MirSurface MirSurface; |
901 | typedef struct MirScreencast MirScreencast; |
902 | +typedef struct MirTrustSession MirTrustSession; |
903 | |
904 | /** |
905 | * Returned by asynchronous functions. Must not be free'd by |
906 | @@ -104,6 +105,7 @@ |
907 | MirConnection* connection, void* context); |
908 | |
909 | /** |
910 | +<<<<<<< TREE |
911 | * Callback called when a request for client file descriptors completes |
912 | * \param [in] connection The connection associated with the display change |
913 | * \param [in] count The number of FDs allocated |
914 | @@ -117,6 +119,19 @@ |
915 | MirConnection* connection, size_t count, int const* fds, void* context); |
916 | |
917 | /** |
918 | +======= |
919 | + * Callback called when a request for client file descriptors completes |
920 | + * \param [in] connection The connection associated with the display change |
921 | + * \param [in] count The number of FDs allocated |
922 | + * \param [in] fds Array of FDs |
923 | + * \param [in,out] context The context provided by client |
924 | + */ |
925 | + |
926 | +typedef void (*mir_client_fd_callback)( |
927 | + MirConnection* connection, size_t count, int const* fds, void* context); |
928 | + |
929 | +/** |
930 | +>>>>>>> MERGE-SOURCE |
931 | * MirBufferUsage specifies how a surface can and will be used. A "hardware" |
932 | * surface can be used for OpenGL accelerated rendering. A "software" surface |
933 | * is one that can be addressed in main memory and blitted to directly. |
934 | @@ -319,6 +334,31 @@ |
935 | */ |
936 | typedef void (*mir_screencast_callback)(MirScreencast *screencast, void *client_context); |
937 | |
938 | +/** |
939 | + * Callback member of MirTrustSession for handling of trust sessions. |
940 | + * \param [in] tps The trust session associated with the callback |
941 | + * \param [in,out] context The context provided by the client |
942 | + */ |
943 | +typedef void (*mir_trust_session_callback)(MirTrustSession* tps, void* context); |
944 | + |
945 | +/** |
946 | + * Callback member of MirTrustSession for adding trusted sessions |
947 | + * \param [in] trusted_session The trust session associated with the callback |
948 | + * \param [in] result The result of adding a trusted session |
949 | + * \param [in,out] context The context provided by the client |
950 | + */ |
951 | +typedef void (*mir_trust_session_add_trusted_session_callback)( |
952 | + MirTrustSession* trusted_session, MirTrustSessionAddTrustResult result, void* context); |
953 | + |
954 | +/** |
955 | + * Callback member of MirTrustSession for handling of trust sessions events. |
956 | + * \param [in] trusted_session The trust session associated with the callback |
957 | + * \param [in] state The state of the trust session |
958 | + * \param [in,out] context The context provided by the client |
959 | + */ |
960 | +typedef void (*mir_trust_session_event_callback)( |
961 | + MirTrustSession* trusted_session, MirTrustSessionState state, void* context); |
962 | + |
963 | #ifdef __cplusplus |
964 | } |
965 | /**@}*/ |
966 | |
967 | === modified file 'include/shared/mir_toolkit/common.h' |
968 | --- include/shared/mir_toolkit/common.h 2014-03-06 06:05:17 +0000 |
969 | +++ include/shared/mir_toolkit/common.h 2014-05-09 12:26:43 +0000 |
970 | @@ -87,6 +87,23 @@ |
971 | mir_power_mode_off /* Powered down. */ |
972 | } MirPowerMode; |
973 | |
974 | +typedef enum MirTrustSessionState |
975 | +{ |
976 | + mir_trust_session_state_stopped = 0, |
977 | + mir_trust_session_state_started |
978 | +} MirTrustSessionState; |
979 | + |
980 | +/** |
981 | + * MirTrustSessionAddTrustResult specifies the result of a |
982 | + * call to add an app id to a trust session |
983 | + */ |
984 | +typedef enum |
985 | +{ |
986 | + mir_trust_session_add_tust_failed, |
987 | + mir_trust_session_add_tust_duplicate, |
988 | + mir_trust_session_add_tust_succeeded |
989 | +} MirTrustSessionAddTrustResult; |
990 | + |
991 | /** |
992 | * The order of components in a format enum matches the |
993 | * order of the components as they would be written in an |
994 | |
995 | === modified file 'include/shared/mir_toolkit/event.h' |
996 | --- include/shared/mir_toolkit/event.h 2014-03-06 06:05:17 +0000 |
997 | +++ include/shared/mir_toolkit/event.h 2014-05-09 12:26:43 +0000 |
998 | @@ -40,7 +40,8 @@ |
999 | mir_event_type_key, |
1000 | mir_event_type_motion, |
1001 | mir_event_type_surface, |
1002 | - mir_event_type_resize |
1003 | + mir_event_type_resize, |
1004 | + mir_event_type_trust_session_state_change |
1005 | } MirEventType; |
1006 | |
1007 | typedef enum { |
1008 | @@ -204,6 +205,13 @@ |
1009 | int height; |
1010 | } MirResizeEvent; |
1011 | |
1012 | +typedef struct |
1013 | +{ |
1014 | + MirEventType type; |
1015 | + |
1016 | + MirTrustSessionState new_state; |
1017 | +} MirTrustSessionEvent; |
1018 | + |
1019 | typedef union |
1020 | { |
1021 | MirEventType type; |
1022 | @@ -211,6 +219,7 @@ |
1023 | MirMotionEvent motion; |
1024 | MirSurfaceEvent surface; |
1025 | MirResizeEvent resize; |
1026 | + MirTrustSessionEvent trust_session; |
1027 | } MirEvent; |
1028 | |
1029 | #ifdef __cplusplus |
1030 | |
1031 | === modified file 'include/test/mir_test/test_protobuf_client.h' |
1032 | --- include/test/mir_test/test_protobuf_client.h 2013-08-28 03:41:48 +0000 |
1033 | +++ include/test/mir_test/test_protobuf_client.h 2014-05-09 12:26:43 +0000 |
1034 | @@ -21,6 +21,7 @@ |
1035 | #define MIR_TEST_TEST_CLIENT_H_ |
1036 | |
1037 | #include "mir_protobuf.pb.h" |
1038 | +#include "wait_condition.h" |
1039 | |
1040 | #include <gmock/gmock.h> |
1041 | |
1042 | @@ -49,6 +50,10 @@ |
1043 | mir::protobuf::Connection connection; |
1044 | mir::protobuf::DisplayConfiguration disp_config; |
1045 | mir::protobuf::DisplayConfiguration disp_config_response; |
1046 | + mir::protobuf::TrustSessionParameters trust_session_parameters; |
1047 | + mir::protobuf::TrustedSession trusted_session; |
1048 | + mir::protobuf::TrustSession trust_session; |
1049 | + mir::protobuf::TrustSessionAddResult add_trust_result; |
1050 | |
1051 | MOCK_METHOD0(connect_done, void()); |
1052 | MOCK_METHOD0(create_surface_done, void()); |
1053 | @@ -57,6 +62,9 @@ |
1054 | MOCK_METHOD0(disconnect_done, void()); |
1055 | MOCK_METHOD0(drm_auth_magic_done, void()); |
1056 | MOCK_METHOD0(display_configure_done, void()); |
1057 | + MOCK_METHOD0(trust_session_start_done, void()); |
1058 | + MOCK_METHOD0(trust_session_add_trusted_session_done, void()); |
1059 | + MOCK_METHOD0(trust_session_stop_done, void()); |
1060 | |
1061 | void on_connect_done(); |
1062 | |
1063 | @@ -94,6 +102,12 @@ |
1064 | |
1065 | void wait_for_configure_display_done(); |
1066 | |
1067 | + void wait_for_trust_session_start_done(); |
1068 | + |
1069 | + void wait_for_trust_session_add_trusted_session_done(); |
1070 | + |
1071 | + void wait_for_trust_session_stop_done(); |
1072 | + |
1073 | const int maxwait; |
1074 | std::atomic<bool> connect_done_called; |
1075 | std::atomic<bool> create_surface_called; |
1076 | @@ -104,6 +118,10 @@ |
1077 | std::atomic<bool> configure_display_done_called; |
1078 | std::atomic<bool> tfd_done_called; |
1079 | |
1080 | + WaitCondition wc_trust_session_start; |
1081 | + WaitCondition wc_trust_session_add; |
1082 | + WaitCondition wc_trust_session_stop; |
1083 | + |
1084 | std::atomic<int> connect_done_count; |
1085 | std::atomic<int> create_surface_done_count; |
1086 | std::atomic<int> disconnect_done_count; |
1087 | |
1088 | === modified file 'include/test/mir_test_doubles/mock_scene_session.h' |
1089 | --- include/test/mir_test_doubles/mock_scene_session.h 2014-05-07 14:25:45 +0000 |
1090 | +++ include/test/mir_test_doubles/mock_scene_session.h 2014-05-09 12:26:43 +0000 |
1091 | @@ -52,6 +52,9 @@ |
1092 | MOCK_METHOD3(configure_surface, int(frontend::SurfaceId, MirSurfaceAttrib, int)); |
1093 | |
1094 | MOCK_METHOD1(set_lifecycle_state, void(MirLifecycleState state)); |
1095 | + |
1096 | + MOCK_METHOD0(begin_trust_session, void()); |
1097 | + MOCK_METHOD0(end_trust_session, void()); |
1098 | }; |
1099 | |
1100 | } |
1101 | |
1102 | === modified file 'include/test/mir_test_doubles/mock_shell.h' |
1103 | --- include/test/mir_test_doubles/mock_shell.h 2014-04-15 05:31:19 +0000 |
1104 | +++ include/test/mir_test_doubles/mock_shell.h 2014-05-09 12:26:43 +0000 |
1105 | @@ -22,6 +22,7 @@ |
1106 | #include "mir/scene/surface_creation_parameters.h" |
1107 | #include "mir/frontend/shell.h" |
1108 | #include "mir/frontend/surface_id.h" |
1109 | +#include "mir/scene/trust_session_creation_parameters.h" |
1110 | |
1111 | #include <gmock/gmock.h> |
1112 | |
1113 | @@ -43,6 +44,14 @@ |
1114 | |
1115 | MOCK_METHOD2(create_surface_for, frontend::SurfaceId(std::shared_ptr<frontend::Session> const&, scene::SurfaceCreationParameters const&)); |
1116 | MOCK_METHOD1(handle_surface_created, void(std::shared_ptr<frontend::Session> const&)); |
1117 | + |
1118 | + MOCK_METHOD2(start_trust_session_for, std::shared_ptr<frontend::TrustSession>( |
1119 | + std::shared_ptr<frontend::Session> const&, |
1120 | + scene::TrustSessionCreationParameters const&)); |
1121 | + MOCK_METHOD2(add_trusted_session_for, MirTrustSessionAddTrustResult( |
1122 | + std::shared_ptr<frontend::TrustSession> const&, |
1123 | + pid_t)); |
1124 | + MOCK_METHOD1(stop_trust_session, void(std::shared_ptr<frontend::TrustSession> const&)); |
1125 | }; |
1126 | |
1127 | } |
1128 | |
1129 | === added file 'include/test/mir_test_doubles/mock_trust_session_listener.h' |
1130 | --- include/test/mir_test_doubles/mock_trust_session_listener.h 1970-01-01 00:00:00 +0000 |
1131 | +++ include/test/mir_test_doubles/mock_trust_session_listener.h 2014-05-09 12:26:43 +0000 |
1132 | @@ -0,0 +1,48 @@ |
1133 | +/* |
1134 | + * Copyright © 2014 Canonical Ltd. |
1135 | + * |
1136 | + * This program is free software: you can redistribute it and/or modify it |
1137 | + * under the terms of the GNU General Public License version 3, |
1138 | + * as published by the Free Software Foundation. |
1139 | + * |
1140 | + * This program is distributed in the hope that it will be useful, |
1141 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1142 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1143 | + * GNU General Public License for more details. |
1144 | + * |
1145 | + * You should have received a copy of the GNU General Public License |
1146 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1147 | + * |
1148 | + * Authored By: Nick Dedekind <nick.dedekind@canonical.com> |
1149 | + */ |
1150 | + |
1151 | +#ifndef MIR_TEST_DOUBLES_MOCK_TRUST_SESSION_LISTENER_H_ |
1152 | +#define MIR_TEST_DOUBLES_MOCK_TRUST_SESSION_LISTENER_H_ |
1153 | + |
1154 | +#include "mir/scene/trust_session_listener.h" |
1155 | + |
1156 | +#include <gmock/gmock.h> |
1157 | + |
1158 | +namespace mir |
1159 | +{ |
1160 | +namespace test |
1161 | +{ |
1162 | +namespace doubles |
1163 | +{ |
1164 | + |
1165 | +struct MockTrustSessionListener : public scene::TrustSessionListener |
1166 | +{ |
1167 | + virtual ~MockTrustSessionListener() noexcept(true) {} |
1168 | + |
1169 | + MOCK_METHOD1(starting, void(scene::TrustSession const&)); |
1170 | + MOCK_METHOD1(stopping, void(scene::TrustSession const&)); |
1171 | + |
1172 | + MOCK_METHOD2(trusted_session_beginning, void(scene::TrustSession&, scene::Session const&)); |
1173 | + MOCK_METHOD2(trusted_session_ending, void(scene::TrustSession&, scene::Session const&)); |
1174 | +}; |
1175 | + |
1176 | +} |
1177 | +} |
1178 | +} // namespace mir |
1179 | + |
1180 | +#endif // MIR_TEST_DOUBLES_MOCK_TRUST_SESSION_LISTENER_H_ |
1181 | |
1182 | === added file 'include/test/mir_test_doubles/null_trust_session.h' |
1183 | --- include/test/mir_test_doubles/null_trust_session.h 1970-01-01 00:00:00 +0000 |
1184 | +++ include/test/mir_test_doubles/null_trust_session.h 2014-05-09 12:26:43 +0000 |
1185 | @@ -0,0 +1,70 @@ |
1186 | +/* |
1187 | + * Copyright © 2013 Canonical Ltd. |
1188 | + * |
1189 | + * This program is free software: you can redistribute it and/or modify it |
1190 | + * under the terms of the GNU General Public License version 3, |
1191 | + * as published by the Free Software Foundation. |
1192 | + * |
1193 | + * This program is distributed in the hope that it will be useful, |
1194 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1195 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1196 | + * GNU General Public License for more details. |
1197 | + * |
1198 | + * You should have received a copy of the GNU General Public License |
1199 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1200 | + * |
1201 | + * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com> |
1202 | + */ |
1203 | + |
1204 | +#ifndef MIR_TEST_DOUBLES_NULL_TRUST_SESSION_H_ |
1205 | +#define MIR_TEST_DOUBLES_NULL_TRUST_SESSION_H_ |
1206 | + |
1207 | +#include "mir/scene/trust_session.h" |
1208 | + |
1209 | +namespace mir |
1210 | +{ |
1211 | +namespace test |
1212 | +{ |
1213 | +namespace doubles |
1214 | +{ |
1215 | + |
1216 | +class NullTrustSession : public scene::TrustSession |
1217 | +{ |
1218 | + MirTrustSessionState get_state() const override |
1219 | + { |
1220 | + return mir_trust_session_state_stopped; |
1221 | + } |
1222 | + |
1223 | + void start() override |
1224 | + { |
1225 | + } |
1226 | + |
1227 | + void stop() override |
1228 | + { |
1229 | + } |
1230 | + |
1231 | + std::weak_ptr<scene::Session> get_trusted_helper() const override |
1232 | + { |
1233 | + return std::weak_ptr<scene::Session>(); |
1234 | + } |
1235 | + |
1236 | + bool add_trusted_child(std::shared_ptr<scene::Session> const&) override |
1237 | + { |
1238 | + return false; |
1239 | + } |
1240 | + |
1241 | + void remove_trusted_child(std::shared_ptr<scene::Session> const&) override |
1242 | + { |
1243 | + } |
1244 | + |
1245 | + void for_each_trusted_child(std::function<void(std::shared_ptr<scene::Session> const&)>, |
1246 | + bool) const override |
1247 | + { |
1248 | + } |
1249 | +}; |
1250 | + |
1251 | +} |
1252 | +} |
1253 | +} |
1254 | + |
1255 | +#endif /* MIR_TEST_DOUBLES_NULL_TRUST_SESSION_H_ */ |
1256 | |
1257 | === modified file 'include/test/mir_test_doubles/stub_scene_session.h' |
1258 | --- include/test/mir_test_doubles/stub_scene_session.h 2014-05-06 16:54:43 +0000 |
1259 | +++ include/test/mir_test_doubles/stub_scene_session.h 2014-05-09 12:26:43 +0000 |
1260 | @@ -76,6 +76,14 @@ |
1261 | void set_lifecycle_state(MirLifecycleState /*state*/) |
1262 | { |
1263 | } |
1264 | + |
1265 | + void begin_trust_session() override |
1266 | + { |
1267 | + } |
1268 | + |
1269 | + void end_trust_session() override |
1270 | + { |
1271 | + } |
1272 | }; |
1273 | |
1274 | } |
1275 | |
1276 | === modified file 'include/test/mir_test_doubles/stub_session.h' |
1277 | --- include/test/mir_test_doubles/stub_session.h 2014-05-06 16:54:43 +0000 |
1278 | +++ include/test/mir_test_doubles/stub_session.h 2014-05-09 12:26:43 +0000 |
1279 | @@ -41,6 +41,10 @@ |
1280 | { |
1281 | return std::shared_ptr<frontend::Surface>(); |
1282 | } |
1283 | + pid_t process_id() const override |
1284 | + { |
1285 | + return 0; |
1286 | + } |
1287 | std::string name() const override |
1288 | { |
1289 | return std::string(); |
1290 | |
1291 | === modified file 'include/test/mir_test_doubles/stub_shell.h' |
1292 | --- include/test/mir_test_doubles/stub_shell.h 2014-04-15 05:31:19 +0000 |
1293 | +++ include/test/mir_test_doubles/stub_shell.h 2014-05-09 12:26:43 +0000 |
1294 | @@ -49,6 +49,21 @@ |
1295 | void handle_surface_created(std::shared_ptr<frontend::Session> const& /* session */) override |
1296 | { |
1297 | } |
1298 | + std::shared_ptr<frontend::TrustSession> start_trust_session_for(std::shared_ptr<frontend::Session> const& /* session */, |
1299 | + scene::TrustSessionCreationParameters const& /* params */) |
1300 | + { |
1301 | + return std::shared_ptr<frontend::TrustSession>(); |
1302 | + } |
1303 | + MirTrustSessionAddTrustResult add_trusted_session_for( |
1304 | + std::shared_ptr<frontend::TrustSession> const& /* trust_session */, |
1305 | + pid_t /* session_pid */) |
1306 | + { |
1307 | + return mir_trust_session_add_tust_failed; |
1308 | + } |
1309 | + void stop_trust_session(std::shared_ptr<frontend::TrustSession> const& /* trust_session */) |
1310 | + { |
1311 | + } |
1312 | + |
1313 | std::shared_ptr<StubSession> const stub_session; |
1314 | }; |
1315 | |
1316 | |
1317 | === modified file 'src/client/CMakeLists.txt' |
1318 | --- src/client/CMakeLists.txt 2014-03-31 14:36:08 +0000 |
1319 | +++ src/client/CMakeLists.txt 2014-05-09 12:26:43 +0000 |
1320 | @@ -47,6 +47,9 @@ |
1321 | private.cpp |
1322 | mir_screencast.cpp |
1323 | mir_screencast_api.cpp |
1324 | + mir_trust_session.cpp |
1325 | + mir_trust_session_api.cpp |
1326 | + event_distributor.cpp |
1327 | ) |
1328 | |
1329 | add_library( |
1330 | @@ -81,7 +84,7 @@ |
1331 | mirclientlttngstatic |
1332 | |
1333 | ${MIR_COMMON_PLATFORM_LIBRARIES} |
1334 | - |
1335 | + |
1336 | 3rd_party |
1337 | ) |
1338 | |
1339 | |
1340 | === modified file 'src/client/connection_configuration.h' |
1341 | --- src/client/connection_configuration.h 2014-03-06 06:05:17 +0000 |
1342 | +++ src/client/connection_configuration.h 2014-05-09 12:26:43 +0000 |
1343 | @@ -47,6 +47,7 @@ |
1344 | class ClientPlatformFactory; |
1345 | class DisplayConfiguration; |
1346 | class LifecycleControl; |
1347 | +class EventDistributor; |
1348 | |
1349 | class ConnectionConfiguration |
1350 | { |
1351 | @@ -60,6 +61,7 @@ |
1352 | virtual std::shared_ptr<input::receiver::InputPlatform> the_input_platform() = 0; |
1353 | virtual std::shared_ptr<DisplayConfiguration> the_display_configuration() = 0; |
1354 | virtual std::shared_ptr<LifecycleControl> the_lifecycle_control() = 0; |
1355 | + virtual std::shared_ptr<EventDistributor> the_event_distributor() = 0; |
1356 | |
1357 | protected: |
1358 | ConnectionConfiguration() = default; |
1359 | |
1360 | === modified file 'src/client/default_connection_configuration.cpp' |
1361 | --- src/client/default_connection_configuration.cpp 2014-03-26 05:48:59 +0000 |
1362 | +++ src/client/default_connection_configuration.cpp 2014-05-09 12:26:43 +0000 |
1363 | @@ -32,6 +32,7 @@ |
1364 | #include "lifecycle_control.h" |
1365 | #include "mir/shared_library.h" |
1366 | #include "client_platform_factory.h" |
1367 | +#include "event_distributor.h" |
1368 | |
1369 | namespace mcl = mir::client; |
1370 | |
1371 | @@ -81,7 +82,7 @@ |
1372 | [this] |
1373 | { |
1374 | return mcl::rpc::make_rpc_channel( |
1375 | - the_socket_file(), the_surface_map(), the_display_configuration(), the_rpc_report(), the_lifecycle_control()); |
1376 | + the_socket_file(), the_surface_map(), the_display_configuration(), the_rpc_report(), the_lifecycle_control(), the_event_distributor()); |
1377 | }); |
1378 | } |
1379 | |
1380 | @@ -182,3 +183,12 @@ |
1381 | return std::make_shared<mcl::LifecycleControl>(); |
1382 | }); |
1383 | } |
1384 | + |
1385 | +std::shared_ptr<mcl::EventDistributor> mcl::DefaultConnectionConfiguration::the_event_distributor() |
1386 | +{ |
1387 | + return event_distributor( |
1388 | + [] |
1389 | + { |
1390 | + return std::make_shared<mcl::EventDistributor>(); |
1391 | + }); |
1392 | +} |
1393 | |
1394 | === modified file 'src/client/default_connection_configuration.h' |
1395 | --- src/client/default_connection_configuration.h 2014-03-06 06:05:17 +0000 |
1396 | +++ src/client/default_connection_configuration.h 2014-05-09 12:26:43 +0000 |
1397 | @@ -54,6 +54,7 @@ |
1398 | std::shared_ptr<input::receiver::InputPlatform> the_input_platform(); |
1399 | std::shared_ptr<DisplayConfiguration> the_display_configuration(); |
1400 | std::shared_ptr<LifecycleControl> the_lifecycle_control(); |
1401 | + std::shared_ptr<EventDistributor> the_event_distributor(); |
1402 | |
1403 | virtual std::string the_socket_file(); |
1404 | virtual std::shared_ptr<rpc::RpcReport> the_rpc_report(); |
1405 | @@ -67,6 +68,7 @@ |
1406 | CachedPtr<ConnectionSurfaceMap> surface_map; |
1407 | CachedPtr<DisplayConfiguration> display_configuration; |
1408 | CachedPtr<LifecycleControl> lifecycle_control; |
1409 | + CachedPtr<EventDistributor> event_distributor; |
1410 | |
1411 | CachedPtr<rpc::RpcReport> rpc_report; |
1412 | CachedPtr<input::receiver::InputReceiverReport> input_receiver_report; |
1413 | |
1414 | === added file 'src/client/event_distributor.cpp' |
1415 | --- src/client/event_distributor.cpp 1970-01-01 00:00:00 +0000 |
1416 | +++ src/client/event_distributor.cpp 2014-05-09 12:26:43 +0000 |
1417 | @@ -0,0 +1,57 @@ |
1418 | +/* |
1419 | + * Copyright © 2014 Canonical Ltd. |
1420 | + * |
1421 | + * This program is free software: you can redistribute it and/or modify it |
1422 | + * under the terms of the GNU Lesser General Public License version 3, |
1423 | + * as published by the Free Software Foundation. |
1424 | + * |
1425 | + * This program is distributed in the hope that it will be useful, |
1426 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1427 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1428 | + * GNU Lesser General Public License for more details. |
1429 | + * |
1430 | + * You should have received a copy of the GNU Lesser General Public License |
1431 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1432 | + * |
1433 | + * Authored by: Nick Dedekind <nick.dedekind@gmail.com> |
1434 | + */ |
1435 | + |
1436 | +#include "event_distributor.h" |
1437 | + |
1438 | +namespace mcl = mir::client; |
1439 | + |
1440 | +mcl::EventDistributor::EventDistributor() : |
1441 | + next_fn_id(0) |
1442 | +{ |
1443 | +} |
1444 | + |
1445 | +int mcl::EventDistributor::register_event_handler(std::function<void(MirEvent const&)> const& fn) |
1446 | +{ |
1447 | + std::lock_guard<decltype(mutex)> lock(mutex); |
1448 | + |
1449 | + int id = next_id(); |
1450 | + event_handlers[id] = fn; |
1451 | + return id; |
1452 | +} |
1453 | + |
1454 | +void mcl::EventDistributor::unregister_event_handler(int id) |
1455 | +{ |
1456 | + std::lock_guard<decltype(mutex)> lock(mutex); |
1457 | + |
1458 | + event_handlers.erase(id); |
1459 | +} |
1460 | + |
1461 | +void mcl::EventDistributor::handle_event(MirEvent const& event) |
1462 | +{ |
1463 | + std::lock_guard<decltype(mutex)> lock(mutex); |
1464 | + |
1465 | + for (auto const& fn : event_handlers) |
1466 | + { |
1467 | + fn.second(event); |
1468 | + } |
1469 | +} |
1470 | + |
1471 | +int mcl::EventDistributor::next_id() |
1472 | +{ |
1473 | + return ++next_fn_id; |
1474 | +} |
1475 | \ No newline at end of file |
1476 | |
1477 | === added file 'src/client/event_distributor.h' |
1478 | --- src/client/event_distributor.h 1970-01-01 00:00:00 +0000 |
1479 | +++ src/client/event_distributor.h 2014-05-09 12:26:43 +0000 |
1480 | @@ -0,0 +1,52 @@ |
1481 | +/* |
1482 | + * Copyright © 2014 Canonical Ltd. |
1483 | + * |
1484 | + * This program is free software: you can redistribute it and/or modify it |
1485 | + * under the terms of the GNU Lesser General Public License version 3, |
1486 | + * as published by the Free Software Foundation. |
1487 | + * |
1488 | + * This program is distributed in the hope that it will be useful, |
1489 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1490 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1491 | + * GNU Lesser General Public License for more details. |
1492 | + * |
1493 | + * You should have received a copy of the GNU Lesser General Public License |
1494 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1495 | + * |
1496 | + * Authored by: Nick Dedekind <nick.dedekind@gmail.com> |
1497 | + */ |
1498 | + |
1499 | +#ifndef MIR_CLIENT_EVENT_DISTRIBUTOR_H |
1500 | + |
1501 | +#include "mir_toolkit/event.h" |
1502 | + |
1503 | +#include <functional> |
1504 | +#include <mutex> |
1505 | +#include <map> |
1506 | + |
1507 | +namespace mir |
1508 | +{ |
1509 | +namespace client |
1510 | +{ |
1511 | +class EventDistributor |
1512 | +{ |
1513 | +public: |
1514 | + EventDistributor(); |
1515 | + ~EventDistributor() = default; |
1516 | + |
1517 | + int register_event_handler(std::function<void(MirEvent const&)> const&); |
1518 | + void unregister_event_handler(int id); |
1519 | + |
1520 | + void handle_event(MirEvent const& event); |
1521 | + |
1522 | +private: |
1523 | + int next_id(); |
1524 | + |
1525 | + mutable std::mutex mutex; |
1526 | + std::map<int, std::function<void(MirEvent const&)>> event_handlers; |
1527 | + int next_fn_id; |
1528 | +}; |
1529 | +} |
1530 | +} |
1531 | + |
1532 | +#endif /* MIR_CLIENT_EVENT_DISTRIBUTOR_H */ |
1533 | |
1534 | === modified file 'src/client/mir_connection.cpp' |
1535 | --- src/client/mir_connection.cpp 2014-05-07 13:51:38 +0000 |
1536 | +++ src/client/mir_connection.cpp 2014-05-09 12:26:43 +0000 |
1537 | @@ -18,6 +18,7 @@ |
1538 | |
1539 | #include "mir_connection.h" |
1540 | #include "mir_surface.h" |
1541 | +#include "mir_trust_session.h" |
1542 | #include "client_platform.h" |
1543 | #include "client_platform_factory.h" |
1544 | #include "rpc/mir_basic_rpc_channel.h" |
1545 | @@ -82,7 +83,8 @@ |
1546 | input_platform(conf.the_input_platform()), |
1547 | display_configuration(conf.the_display_configuration()), |
1548 | lifecycle_control(conf.the_lifecycle_control()), |
1549 | - surface_map(conf.the_surface_map()) |
1550 | + surface_map(conf.the_surface_map()), |
1551 | + event_distributor(conf.the_event_distributor()) |
1552 | { |
1553 | connect_result.set_error("connect not called"); |
1554 | { |
1555 | @@ -193,6 +195,11 @@ |
1556 | return new_wait_handle; |
1557 | } |
1558 | |
1559 | +MirTrustSession* MirConnection::create_trust_session() |
1560 | +{ |
1561 | + return new MirTrustSession(display_server(), event_distributor); |
1562 | +} |
1563 | + |
1564 | namespace |
1565 | { |
1566 | void default_lifecycle_event_handler(MirLifecycleState transition) |
1567 | @@ -522,6 +529,6 @@ |
1568 | } |
1569 | |
1570 | mir::protobuf::DisplayServer& MirConnection::display_server() |
1571 | -{ |
1572 | +{ |
1573 | return server; |
1574 | } |
1575 | |
1576 | === modified file 'src/client/mir_connection.h' |
1577 | --- src/client/mir_connection.h 2014-05-07 13:51:38 +0000 |
1578 | +++ src/client/mir_connection.h 2014-05-09 12:26:43 +0000 |
1579 | @@ -45,6 +45,7 @@ |
1580 | class ConnectionSurfaceMap; |
1581 | class DisplayConfiguration; |
1582 | class LifecycleControl; |
1583 | +class EventDistributor; |
1584 | |
1585 | namespace rpc |
1586 | { |
1587 | @@ -86,6 +87,8 @@ |
1588 | mir_surface_callback callback, |
1589 | void *context); |
1590 | |
1591 | + MirTrustSession* create_trust_session(); |
1592 | + |
1593 | char const * get_error_message(); |
1594 | |
1595 | MirWaitHandle* connect( |
1596 | @@ -172,6 +175,8 @@ |
1597 | |
1598 | std::shared_ptr<mir::client::ConnectionSurfaceMap> const surface_map; |
1599 | |
1600 | + std::shared_ptr<mir::client::EventDistributor> const event_distributor; |
1601 | + |
1602 | std::vector<int> extra_platform_data; |
1603 | |
1604 | struct SurfaceRelease; |
1605 | |
1606 | === added file 'src/client/mir_trust_session.cpp' |
1607 | --- src/client/mir_trust_session.cpp 1970-01-01 00:00:00 +0000 |
1608 | +++ src/client/mir_trust_session.cpp 2014-05-09 12:26:43 +0000 |
1609 | @@ -0,0 +1,182 @@ |
1610 | +/* |
1611 | + * Copyright © 2014 Canonical Ltd. |
1612 | + * |
1613 | + * This program is free software: you can redistribute it and/or modify it |
1614 | + * under the terms of the GNU Lesser General Public License version 3, |
1615 | + * as published by the Free Software Foundation. |
1616 | + * |
1617 | + * This program is distributed in the hope that it will be useful, |
1618 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1619 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1620 | + * GNU Lesser General Public License for more details. |
1621 | + * |
1622 | + * You should have received a copy of the GNU Lesser General Public License |
1623 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1624 | + * |
1625 | + * Authored by: Nick Dedekind <nick.dedekind@gmail.com> |
1626 | + */ |
1627 | + |
1628 | +#include "mir_trust_session.h" |
1629 | +#include "event_distributor.h" |
1630 | + |
1631 | +namespace mp = mir::protobuf; |
1632 | +namespace mcl = mir::client; |
1633 | + |
1634 | +MirTrustSession::MirTrustSession( |
1635 | + mp::DisplayServer& server, |
1636 | + std::shared_ptr<mcl::EventDistributor> const& event_distributor) |
1637 | + : server(server), |
1638 | + event_distributor(event_distributor), |
1639 | + state(mir_trust_session_state_stopped) |
1640 | +{ |
1641 | + event_distributor_fn_id = event_distributor->register_event_handler( |
1642 | + [this](MirEvent const& event) |
1643 | + { |
1644 | + if (event.type != mir_event_type_trust_session_state_change) |
1645 | + return; |
1646 | + |
1647 | + std::lock_guard<decltype(mutex_event_handler)> lock(mutex_event_handler); |
1648 | + |
1649 | + set_state(event.trust_session.new_state); |
1650 | + if (handle_trust_session_event) { |
1651 | + handle_trust_session_event(event.trust_session.new_state); |
1652 | + } |
1653 | + } |
1654 | + ); |
1655 | +} |
1656 | + |
1657 | +MirTrustSession::~MirTrustSession() |
1658 | +{ |
1659 | + event_distributor->unregister_event_handler(event_distributor_fn_id); |
1660 | +} |
1661 | + |
1662 | +MirTrustSessionState MirTrustSession::get_state() const |
1663 | +{ |
1664 | + std::lock_guard<decltype(mutex)> lock(mutex); |
1665 | + |
1666 | + return state; |
1667 | +} |
1668 | + |
1669 | +void MirTrustSession::set_state(MirTrustSessionState new_state) |
1670 | +{ |
1671 | + std::lock_guard<decltype(mutex)> lock(mutex); |
1672 | + |
1673 | + state = new_state; |
1674 | +} |
1675 | + |
1676 | +MirWaitHandle* MirTrustSession::start(pid_t pid, mir_trust_session_callback callback, void* context) |
1677 | +{ |
1678 | + mir::protobuf::TrustSessionParameters parameters; |
1679 | + parameters.mutable_base_trusted_session()->set_pid(pid); |
1680 | + |
1681 | + server.start_trust_session( |
1682 | + 0, |
1683 | + ¶meters, |
1684 | + &session, |
1685 | + google::protobuf::NewCallback(this, &MirTrustSession::done_start, |
1686 | + callback, context)); |
1687 | + |
1688 | + return &start_wait_handle; |
1689 | +} |
1690 | + |
1691 | +MirWaitHandle* MirTrustSession::stop(mir_trust_session_callback callback, void* context) |
1692 | +{ |
1693 | + server.stop_trust_session( |
1694 | + 0, |
1695 | + &protobuf_void, |
1696 | + &protobuf_void, |
1697 | + google::protobuf::NewCallback(this, &MirTrustSession::done_stop, |
1698 | + callback, context)); |
1699 | + |
1700 | + return &stop_wait_handle; |
1701 | +} |
1702 | + |
1703 | +MirWaitHandle* MirTrustSession::add_trusted_session(pid_t pid, |
1704 | + mir_trust_session_add_trusted_session_callback callback, |
1705 | + void* context) |
1706 | +{ |
1707 | + mir::protobuf::TrustedSession trusted_session; |
1708 | + trusted_session.set_pid(pid); |
1709 | + |
1710 | + server.add_trusted_session( |
1711 | + 0, |
1712 | + &trusted_session, |
1713 | + &add_result, |
1714 | + google::protobuf::NewCallback(this, &MirTrustSession::done_add_trusted_session, |
1715 | + callback, context)); |
1716 | + |
1717 | + return &add_result_wait_handle; |
1718 | +} |
1719 | + |
1720 | +void MirTrustSession::register_trust_session_event_callback( |
1721 | + mir_trust_session_event_callback callback, |
1722 | + void* context) |
1723 | +{ |
1724 | + std::lock_guard<decltype(mutex_event_handler)> lock(mutex_event_handler); |
1725 | + |
1726 | + handle_trust_session_event = |
1727 | + [this, callback, context](MirTrustSessionState new_state) |
1728 | + { |
1729 | + callback(this, new_state, context); |
1730 | + }; |
1731 | +} |
1732 | + |
1733 | +void MirTrustSession::done_start(mir_trust_session_callback callback, void* context) |
1734 | +{ |
1735 | + std::string error; |
1736 | + MirTrustSessionState new_state = mir_trust_session_state_stopped; |
1737 | + { |
1738 | + std::lock_guard<decltype(mutex)> lock(mutex); |
1739 | + |
1740 | + if (session.has_state()) |
1741 | + new_state = (MirTrustSessionState)session.state(); |
1742 | + |
1743 | + error = session.error(); |
1744 | + } |
1745 | + set_error_message(error); |
1746 | + set_state(new_state); |
1747 | + |
1748 | + callback(this, context); |
1749 | + start_wait_handle.result_received(); |
1750 | +} |
1751 | + |
1752 | +void MirTrustSession::done_stop(mir_trust_session_callback callback, void* context) |
1753 | +{ |
1754 | + set_state(mir_trust_session_state_stopped); |
1755 | + |
1756 | + callback(this, context); |
1757 | + stop_wait_handle.result_received(); |
1758 | +} |
1759 | + |
1760 | +void MirTrustSession::done_add_trusted_session(mir_trust_session_add_trusted_session_callback callback, void* context) |
1761 | +{ |
1762 | + MirTrustSessionAddTrustResult result = static_cast<MirTrustSessionAddTrustResult>(add_result.result()); |
1763 | + if (add_result.has_error()) |
1764 | + { |
1765 | + set_error_message(add_result.error()); |
1766 | + result = mir_trust_session_add_tust_failed; |
1767 | + } |
1768 | + callback(this, result, context); |
1769 | + add_result_wait_handle.result_received(); |
1770 | +} |
1771 | + |
1772 | +char const* MirTrustSession::get_error_message() |
1773 | +{ |
1774 | + std::lock_guard<decltype(mutex)> lock(mutex); |
1775 | + |
1776 | + if (session.has_error()) |
1777 | + { |
1778 | + return session.error().c_str(); |
1779 | + } |
1780 | + else |
1781 | + { |
1782 | + return error_message.c_str(); |
1783 | + } |
1784 | +} |
1785 | + |
1786 | +void MirTrustSession::set_error_message(std::string const& error) |
1787 | +{ |
1788 | + std::lock_guard<decltype(mutex)> lock(mutex); |
1789 | + |
1790 | + error_message = error; |
1791 | +} |
1792 | |
1793 | === added file 'src/client/mir_trust_session.h' |
1794 | --- src/client/mir_trust_session.h 1970-01-01 00:00:00 +0000 |
1795 | +++ src/client/mir_trust_session.h 2014-05-09 12:26:43 +0000 |
1796 | @@ -0,0 +1,88 @@ |
1797 | +/* |
1798 | + * Copyright © 2014 Canonical Ltd. |
1799 | + * |
1800 | + * This program is free software: you can redistribute it and/or modify it |
1801 | + * under the terms of the GNU Lesser General Public License version 3, |
1802 | + * as published by the Free Software Foundation. |
1803 | + * |
1804 | + * This program is distributed in the hope that it will be useful, |
1805 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1806 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1807 | + * GNU Lesser General Public License for more details. |
1808 | + * |
1809 | + * You should have received a copy of the GNU Lesser General Public License |
1810 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1811 | + * |
1812 | + * Authored by: Nick Dedekind <nick.dedekind@gmail.com> |
1813 | + */ |
1814 | + |
1815 | +#ifndef MIR_CLIENT_MIR_TRUST_SESSION_H_ |
1816 | +#define MIR_CLIENT_MIR_TRUST_SESSION_H_ |
1817 | + |
1818 | +#include "mir_toolkit/mir_client_library.h" |
1819 | + |
1820 | +#include "mir_protobuf.pb.h" |
1821 | +#include "mir_wait_handle.h" |
1822 | + |
1823 | +#include <mutex> |
1824 | +#include <memory> |
1825 | +#include <atomic> |
1826 | + |
1827 | +namespace mir |
1828 | +{ |
1829 | +/// The client-side library implementation namespace |
1830 | +namespace client |
1831 | +{ |
1832 | +class EventDistributor; |
1833 | +} |
1834 | +} |
1835 | + |
1836 | +struct MirTrustSession |
1837 | +{ |
1838 | +public: |
1839 | + MirTrustSession(mir::protobuf::DisplayServer& server, |
1840 | + std::shared_ptr<mir::client::EventDistributor> const& event_distributor); |
1841 | + |
1842 | + ~MirTrustSession(); |
1843 | + |
1844 | + MirTrustSession(MirTrustSession const&) = delete; |
1845 | + MirTrustSession& operator=(MirTrustSession const&) = delete; |
1846 | + |
1847 | + MirWaitHandle* start(pid_t pid, mir_trust_session_callback callback, void* context); |
1848 | + MirWaitHandle* stop(mir_trust_session_callback callback, void* context); |
1849 | + MirWaitHandle* add_trusted_session(pid_t pid, mir_trust_session_add_trusted_session_callback callback, void* context); |
1850 | + |
1851 | + void register_trust_session_event_callback(mir_trust_session_event_callback callback, void* context); |
1852 | + |
1853 | + char const* get_error_message(); |
1854 | + void set_error_message(std::string const& error); |
1855 | + |
1856 | + MirTrustSessionState get_state() const; |
1857 | + void set_state(MirTrustSessionState new_state); |
1858 | + |
1859 | +private: |
1860 | + mutable std::mutex mutex; // Protects members of *this |
1861 | + mutable std::mutex mutex_event_handler; // Need another mutex for callback access to members |
1862 | + |
1863 | + mir::protobuf::DisplayServer& server; |
1864 | + mir::protobuf::TrustSession session; |
1865 | + mir::protobuf::TrustSessionAddResult add_result; |
1866 | + mir::protobuf::Void protobuf_void; |
1867 | + std::string error_message; |
1868 | + |
1869 | + std::shared_ptr<mir::client::EventDistributor> const event_distributor; |
1870 | + std::function<void(MirTrustSessionState)> handle_trust_session_event; |
1871 | + int event_distributor_fn_id; |
1872 | + |
1873 | + MirWaitHandle start_wait_handle; |
1874 | + MirWaitHandle stop_wait_handle; |
1875 | + MirWaitHandle add_result_wait_handle; |
1876 | + MirTrustSessionState state; |
1877 | + |
1878 | + void done_start(mir_trust_session_callback callback, void* context); |
1879 | + void done_stop(mir_trust_session_callback callback, void* context); |
1880 | + void done_add_trusted_session(mir_trust_session_add_trusted_session_callback callback, void* context); |
1881 | +}; |
1882 | + |
1883 | +#endif /* MIR_CLIENT_MIR_TRUST_SESSION_H_ */ |
1884 | + |
1885 | |
1886 | === added file 'src/client/mir_trust_session_api.cpp' |
1887 | --- src/client/mir_trust_session_api.cpp 1970-01-01 00:00:00 +0000 |
1888 | +++ src/client/mir_trust_session_api.cpp 2014-05-09 12:26:43 +0000 |
1889 | @@ -0,0 +1,133 @@ |
1890 | +/* |
1891 | + * Copyright © 2014 Canonical Ltd. |
1892 | + * |
1893 | + * This program is free software: you can redistribute it and/or modify it |
1894 | + * under the terms of the GNU Lesser General Public License version 3, |
1895 | + * as published by the Free Software Foundation. |
1896 | + * |
1897 | + * This program is distributed in the hope that it will be useful, |
1898 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1899 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1900 | + * GNU Lesser General Public License for more details. |
1901 | + * |
1902 | + * You should have received a copy of the GNU Lesser General Public License |
1903 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1904 | + */ |
1905 | + |
1906 | +#include "mir_toolkit/mir_trust_session.h" |
1907 | +#include "mir_trust_session.h" |
1908 | +#include "mir_connection.h" |
1909 | + |
1910 | +#include <stdexcept> |
1911 | +#include <boost/throw_exception.hpp> |
1912 | + |
1913 | +namespace |
1914 | +{ |
1915 | + |
1916 | +// assign_result is compatible with all 2-parameter callbacks |
1917 | +void assign_result(void *result, void **context) |
1918 | +{ |
1919 | + if (context) |
1920 | + *context = result; |
1921 | +} |
1922 | + |
1923 | +void add_trusted_session_callback(MirTrustSession*, |
1924 | + MirTrustSessionAddTrustResult result, |
1925 | + void* context) |
1926 | +{ |
1927 | + if (context) |
1928 | + *(MirTrustSessionAddTrustResult*)context = result; |
1929 | +} |
1930 | + |
1931 | +} |
1932 | + |
1933 | +MirWaitHandle *mir_connection_start_trust_session(MirConnection* connection, |
1934 | + pid_t base_session_pid, |
1935 | + mir_trust_session_callback start_callback, |
1936 | + mir_trust_session_event_callback event_callback, |
1937 | + void* context) |
1938 | +{ |
1939 | + auto trust_session = connection->create_trust_session(); |
1940 | + if (event_callback) |
1941 | + trust_session->register_trust_session_event_callback(event_callback, context); |
1942 | + return trust_session->start(base_session_pid, start_callback, context); |
1943 | +} |
1944 | + |
1945 | +MirTrustSession *mir_connection_start_trust_session_sync(MirConnection* connection, |
1946 | + pid_t base_session_pid, |
1947 | + mir_trust_session_event_callback event_callback, |
1948 | + void* context) |
1949 | +{ |
1950 | + auto trust_session = connection->create_trust_session(); |
1951 | + if (event_callback) |
1952 | + trust_session->register_trust_session_event_callback(event_callback, context); |
1953 | + |
1954 | + mir_wait_for(trust_session->start(base_session_pid, |
1955 | + reinterpret_cast<mir_trust_session_callback>(assign_result), |
1956 | + nullptr)); |
1957 | + return trust_session; |
1958 | +} |
1959 | + |
1960 | +MirTrustSession* mir_connection_create_trust_session(MirConnection* connection) |
1961 | +{ |
1962 | + return connection->create_trust_session(); |
1963 | +} |
1964 | + |
1965 | +MirWaitHandle *mir_trust_session_add_trusted_session(MirTrustSession *trust_session, |
1966 | + pid_t session_pid, |
1967 | + mir_trust_session_add_trusted_session_callback callback, |
1968 | + void* context) |
1969 | +{ |
1970 | + try |
1971 | + { |
1972 | + return trust_session->add_trusted_session(session_pid, callback, context); |
1973 | + } |
1974 | + catch (std::exception const&) |
1975 | + { |
1976 | + // TODO callback with an error |
1977 | + return nullptr; |
1978 | + } |
1979 | +} |
1980 | + |
1981 | +MirTrustSessionAddTrustResult mir_trust_session_add_trusted_session_sync(MirTrustSession *trust_session, pid_t base_session_pid) |
1982 | +{ |
1983 | + MirTrustSessionAddTrustResult result; |
1984 | + mir_wait_for(mir_trust_session_add_trusted_session(trust_session, |
1985 | + base_session_pid, |
1986 | + add_trusted_session_callback, |
1987 | + &result)); |
1988 | + return result; |
1989 | +} |
1990 | + |
1991 | +MirWaitHandle *mir_trust_session_stop(MirTrustSession *trust_session, |
1992 | + mir_trust_session_callback callback, |
1993 | + void* context) |
1994 | +{ |
1995 | + try |
1996 | + { |
1997 | + return trust_session->stop(callback, context); |
1998 | + } |
1999 | + catch (std::exception const&) |
2000 | + { |
2001 | + // TODO callback with an error |
2002 | + return nullptr; |
2003 | + } |
2004 | +} |
2005 | + |
2006 | +MirBool mir_trust_session_stop_sync(MirTrustSession *trust_session) |
2007 | +{ |
2008 | + mir_wait_for(mir_trust_session_stop(trust_session, |
2009 | + reinterpret_cast<mir_trust_session_callback>(assign_result), |
2010 | + NULL)); |
2011 | + return trust_session->get_state() == mir_trust_session_state_stopped ? mir_true : mir_false; |
2012 | +} |
2013 | + |
2014 | +MirTrustSessionState mir_trust_session_get_state(MirTrustSession *trust_session) |
2015 | +{ |
2016 | + return trust_session->get_state(); |
2017 | +} |
2018 | + |
2019 | +void mir_trust_session_release(MirTrustSession* trust_session) |
2020 | +{ |
2021 | + delete trust_session; |
2022 | +} |
2023 | |
2024 | === modified file 'src/client/rpc/make_rpc_channel.h' |
2025 | --- src/client/rpc/make_rpc_channel.h 2014-03-06 06:05:17 +0000 |
2026 | +++ src/client/rpc/make_rpc_channel.h 2014-05-09 12:26:43 +0000 |
2027 | @@ -29,6 +29,7 @@ |
2028 | class SurfaceMap; |
2029 | class DisplayConfiguration; |
2030 | class LifecycleControl; |
2031 | +class EventDistributor; |
2032 | |
2033 | namespace rpc |
2034 | { |
2035 | @@ -39,7 +40,8 @@ |
2036 | std::shared_ptr<SurfaceMap> const& map, |
2037 | std::shared_ptr<DisplayConfiguration> const& disp_conf, |
2038 | std::shared_ptr<RpcReport> const& rpc_report, |
2039 | - std::shared_ptr<LifecycleControl> const& lifecycle_control); |
2040 | + std::shared_ptr<LifecycleControl> const& lifecycle_control, |
2041 | + std::shared_ptr<EventDistributor> const& event_distributor); |
2042 | } |
2043 | } |
2044 | } |
2045 | |
2046 | === modified file 'src/client/rpc/make_socket_rpc_channel.cpp' |
2047 | --- src/client/rpc/make_socket_rpc_channel.cpp 2014-03-06 06:05:17 +0000 |
2048 | +++ src/client/rpc/make_socket_rpc_channel.cpp 2014-05-09 12:26:43 +0000 |
2049 | @@ -44,13 +44,14 @@ |
2050 | std::shared_ptr<mcl::SurfaceMap> const& map, |
2051 | std::shared_ptr<mcl::DisplayConfiguration> const& disp_conf, |
2052 | std::shared_ptr<RpcReport> const& rpc_report, |
2053 | - std::shared_ptr<mcl::LifecycleControl> const& lifecycle_control) |
2054 | + std::shared_ptr<mcl::LifecycleControl> const& lifecycle_control, |
2055 | + std::shared_ptr<mcl::EventDistributor> const& event_distributor) |
2056 | { |
2057 | if (fd_prefix.is_start_of(name)) |
2058 | { |
2059 | auto const fd = atoi(name.c_str()+fd_prefix.size); |
2060 | - return std::make_shared<MirSocketRpcChannel>(fd, map, disp_conf, rpc_report, lifecycle_control); |
2061 | + return std::make_shared<MirSocketRpcChannel>(fd, map, disp_conf, rpc_report, lifecycle_control, event_distributor); |
2062 | } |
2063 | |
2064 | - return std::make_shared<MirSocketRpcChannel>(name, map, disp_conf, rpc_report, lifecycle_control); |
2065 | + return std::make_shared<MirSocketRpcChannel>(name, map, disp_conf, rpc_report, lifecycle_control, event_distributor); |
2066 | } |
2067 | |
2068 | === modified file 'src/client/rpc/mir_socket_rpc_channel.cpp' |
2069 | --- src/client/rpc/mir_socket_rpc_channel.cpp 2014-05-06 14:53:36 +0000 |
2070 | +++ src/client/rpc/mir_socket_rpc_channel.cpp 2014-05-09 12:26:43 +0000 |
2071 | @@ -24,6 +24,7 @@ |
2072 | #include "../mir_surface.h" |
2073 | #include "../display_configuration.h" |
2074 | #include "../lifecycle_control.h" |
2075 | +#include "../event_distributor.h" |
2076 | |
2077 | #include "mir_protobuf.pb.h" // For Buffer frig |
2078 | #include "mir_protobuf_wire.pb.h" |
2079 | @@ -49,7 +50,8 @@ |
2080 | std::shared_ptr<mcl::SurfaceMap> const& surface_map, |
2081 | std::shared_ptr<DisplayConfiguration> const& disp_config, |
2082 | std::shared_ptr<RpcReport> const& rpc_report, |
2083 | - std::shared_ptr<LifecycleControl> const& lifecycle_control) : |
2084 | + std::shared_ptr<LifecycleControl> const& lifecycle_control, |
2085 | + std::shared_ptr<EventDistributor> const& event_distributor) : |
2086 | rpc_report(rpc_report), |
2087 | pending_calls(rpc_report), |
2088 | work(io_service), |
2089 | @@ -57,6 +59,7 @@ |
2090 | surface_map(surface_map), |
2091 | display_configuration(disp_config), |
2092 | lifecycle_control(lifecycle_control), |
2093 | + event_distributor(event_distributor), |
2094 | disconnected(false) |
2095 | { |
2096 | socket.connect(endpoint); |
2097 | @@ -68,7 +71,8 @@ |
2098 | std::shared_ptr<mcl::SurfaceMap> const& surface_map, |
2099 | std::shared_ptr<DisplayConfiguration> const& disp_config, |
2100 | std::shared_ptr<RpcReport> const& rpc_report, |
2101 | - std::shared_ptr<LifecycleControl> const& lifecycle_control) : |
2102 | + std::shared_ptr<LifecycleControl> const& lifecycle_control, |
2103 | + std::shared_ptr<EventDistributor> const& event_distributor) : |
2104 | rpc_report(rpc_report), |
2105 | pending_calls(rpc_report), |
2106 | work(io_service), |
2107 | @@ -76,6 +80,7 @@ |
2108 | surface_map(surface_map), |
2109 | display_configuration(disp_config), |
2110 | lifecycle_control(lifecycle_control), |
2111 | + event_distributor(event_distributor), |
2112 | disconnected(false) |
2113 | { |
2114 | socket.assign(boost::asio::local::stream_protocol(), native_socket); |
2115 | @@ -405,11 +410,25 @@ |
2116 | |
2117 | rpc_report->event_parsing_succeeded(e); |
2118 | |
2119 | - surface_map->with_surface_do(e.surface.id, |
2120 | - [&e](MirSurface* surface) |
2121 | - { |
2122 | - surface->handle_event(e); |
2123 | - }); |
2124 | + event_distributor->handle_event(e); |
2125 | + |
2126 | + // todo - surfaces should register with the event distributor. |
2127 | + if (e.type == mir_event_type_surface) |
2128 | + { |
2129 | + surface_map->with_surface_do(e.surface.id, |
2130 | + [&e](MirSurface* surface) |
2131 | + { |
2132 | + surface->handle_event(e); |
2133 | + }); |
2134 | + } |
2135 | + else if (e.type == mir_event_type_resize) |
2136 | + { |
2137 | + surface_map->with_surface_do(e.resize.surface_id, |
2138 | + [&e](MirSurface* surface) |
2139 | + { |
2140 | + surface->handle_event(e); |
2141 | + }); |
2142 | + } |
2143 | } |
2144 | else |
2145 | { |
2146 | |
2147 | === modified file 'src/client/rpc/mir_socket_rpc_channel.h' |
2148 | --- src/client/rpc/mir_socket_rpc_channel.h 2014-05-05 03:36:45 +0000 |
2149 | +++ src/client/rpc/mir_socket_rpc_channel.h 2014-05-09 12:26:43 +0000 |
2150 | @@ -44,6 +44,7 @@ |
2151 | class DisplayConfiguration; |
2152 | class SurfaceMap; |
2153 | class LifecycleControl; |
2154 | +class EventDistributor; |
2155 | namespace rpc |
2156 | { |
2157 | |
2158 | @@ -56,13 +57,15 @@ |
2159 | std::shared_ptr<SurfaceMap> const& surface_map, |
2160 | std::shared_ptr<DisplayConfiguration> const& disp_config, |
2161 | std::shared_ptr<RpcReport> const& rpc_report, |
2162 | - std::shared_ptr<LifecycleControl> const& lifecycle_control); |
2163 | + std::shared_ptr<LifecycleControl> const& lifecycle_control, |
2164 | + std::shared_ptr<EventDistributor> const& event_distributor); |
2165 | |
2166 | MirSocketRpcChannel(int native_socket, |
2167 | std::shared_ptr<SurfaceMap> const& surface_map, |
2168 | std::shared_ptr<DisplayConfiguration> const& disp_config, |
2169 | std::shared_ptr<RpcReport> const& rpc_report, |
2170 | - std::shared_ptr<LifecycleControl> const& lifecycle_control); |
2171 | + std::shared_ptr<LifecycleControl> const& lifecycle_control, |
2172 | + std::shared_ptr<EventDistributor> const& event_distributor); |
2173 | ~MirSocketRpcChannel(); |
2174 | |
2175 | private: |
2176 | @@ -102,6 +105,7 @@ |
2177 | std::shared_ptr<SurfaceMap> surface_map; |
2178 | std::shared_ptr<DisplayConfiguration> display_configuration; |
2179 | std::shared_ptr<LifecycleControl> lifecycle_control; |
2180 | + std::shared_ptr<EventDistributor> event_distributor; |
2181 | std::atomic<bool> disconnected; |
2182 | }; |
2183 | |
2184 | |
2185 | === modified file 'src/server/default_server_configuration.cpp' |
2186 | --- src/server/default_server_configuration.cpp 2014-05-05 03:36:45 +0000 |
2187 | +++ src/server/default_server_configuration.cpp 2014-05-09 12:26:43 +0000 |
2188 | @@ -36,6 +36,7 @@ |
2189 | #include "mir/time/high_resolution_clock.h" |
2190 | #include "mir/geometry/rectangles.h" |
2191 | #include "mir/default_configuration.h" |
2192 | +#include "mir/scene/null_trust_session_listener.h" |
2193 | |
2194 | #include <map> |
2195 | |
2196 | @@ -87,6 +88,16 @@ |
2197 | }); |
2198 | } |
2199 | |
2200 | +std::shared_ptr<ms::TrustSessionListener> |
2201 | +mir::DefaultServerConfiguration::the_trust_session_listener() |
2202 | +{ |
2203 | + return trust_session_listener( |
2204 | + [this] |
2205 | + { |
2206 | + return std::make_shared<ms::NullTrustSessionListener>(); |
2207 | + }); |
2208 | +} |
2209 | + |
2210 | std::shared_ptr<mi::CursorListener> |
2211 | mir::DefaultServerConfiguration::the_cursor_listener() |
2212 | { |
2213 | |
2214 | === modified file 'src/server/frontend/protobuf_connection_creator.cpp' |
2215 | === modified file 'src/server/frontend/protobuf_message_processor.cpp' |
2216 | --- src/server/frontend/protobuf_message_processor.cpp 2014-05-06 16:54:43 +0000 |
2217 | +++ src/server/frontend/protobuf_message_processor.cpp 2014-05-09 12:26:43 +0000 |
2218 | @@ -174,10 +174,29 @@ |
2219 | { |
2220 | invoke(this, display_server.get(), &protobuf::DisplayServer::release_screencast, invocation); |
2221 | } |
2222 | - else if ("new_fds_for_trusted_clients" == invocation.method_name()) |
2223 | - { |
2224 | - invoke(this, display_server.get(), &protobuf::DisplayServer::new_fds_for_trusted_clients, invocation); |
2225 | - } |
2226 | +<<<<<<< TREE |
2227 | + else if ("new_fds_for_trusted_clients" == invocation.method_name()) |
2228 | + { |
2229 | + invoke(this, display_server.get(), &protobuf::DisplayServer::new_fds_for_trusted_clients, invocation); |
2230 | + } |
2231 | +======= |
2232 | + else if ("new_fds_for_trusted_clients" == invocation.method_name()) |
2233 | + { |
2234 | + invoke(this, display_server.get(), &protobuf::DisplayServer::new_fds_for_trusted_clients, invocation); |
2235 | + } |
2236 | + else if ("start_trust_session" == invocation.method_name()) |
2237 | + { |
2238 | + invoke(this, display_server.get(), &protobuf::DisplayServer::start_trust_session, invocation); |
2239 | + } |
2240 | + else if ("add_trusted_session" == invocation.method_name()) |
2241 | + { |
2242 | + invoke(this, display_server.get(), &protobuf::DisplayServer::add_trusted_session, invocation); |
2243 | + } |
2244 | + else if ("stop_trust_session" == invocation.method_name()) |
2245 | + { |
2246 | + invoke(this, display_server.get(), &protobuf::DisplayServer::stop_trust_session, invocation); |
2247 | + } |
2248 | +>>>>>>> MERGE-SOURCE |
2249 | else if ("disconnect" == invocation.method_name()) |
2250 | { |
2251 | invoke(this, display_server.get(), &protobuf::DisplayServer::disconnect, invocation); |
2252 | |
2253 | === modified file 'src/server/frontend/session_mediator.cpp' |
2254 | --- src/server/frontend/session_mediator.cpp 2014-05-09 11:01:53 +0000 |
2255 | +++ src/server/frontend/session_mediator.cpp 2014-05-09 12:26:43 +0000 |
2256 | @@ -40,6 +40,8 @@ |
2257 | #include "mir/frontend/client_constants.h" |
2258 | #include "mir/frontend/event_sink.h" |
2259 | #include "mir/frontend/screencast.h" |
2260 | +#include "mir/frontend/trust_session.h" |
2261 | +#include "mir/scene/trust_session_creation_parameters.h" |
2262 | |
2263 | #include "mir/geometry/rectangles.h" |
2264 | #include "client_buffer_tracker.h" |
2265 | @@ -416,6 +418,7 @@ |
2266 | done->Run(); |
2267 | } |
2268 | |
2269 | +<<<<<<< TREE |
2270 | void mf::SessionMediator::new_fds_for_trusted_clients( |
2271 | ::google::protobuf::RpcController* , |
2272 | ::mir::protobuf::SocketFDRequest const* parameters, |
2273 | @@ -448,6 +451,51 @@ |
2274 | done->Run(); |
2275 | } |
2276 | |
2277 | +======= |
2278 | +void mf::SessionMediator::new_fds_for_trusted_clients( |
2279 | + ::google::protobuf::RpcController* , |
2280 | + ::mir::protobuf::SocketFDRequest const* parameters, |
2281 | + ::mir::protobuf::SocketFD* response, |
2282 | + ::google::protobuf::Closure* done) |
2283 | +{ |
2284 | + { |
2285 | + std::unique_lock<std::mutex> lock(session_mutex); |
2286 | + auto session = weak_session.lock(); |
2287 | + |
2288 | + if (session.get() == nullptr) |
2289 | + BOOST_THROW_EXCEPTION(std::logic_error("Invalid application session")); |
2290 | + |
2291 | + auto trust_session = weak_trust_session.lock(); |
2292 | + if (trust_session.get() == nullptr) |
2293 | + BOOST_THROW_EXCEPTION(std::logic_error("Invalid trust session")); |
2294 | + |
2295 | + // TODO write a handler that connects the new session to our trust session |
2296 | + auto const connect_handler = [this](std::shared_ptr<frontend::Session> const& session) |
2297 | + { |
2298 | + auto trust_session = weak_trust_session.lock(); |
2299 | + if (trust_session.get() == nullptr) |
2300 | + BOOST_THROW_EXCEPTION(std::logic_error("Invalid trust session")); |
2301 | + |
2302 | + shell->add_trusted_session_for(trust_session, session->process_id()); |
2303 | + }; |
2304 | + |
2305 | + auto const fds_requested = parameters->number(); |
2306 | + |
2307 | + // < 1 is illogical, > 42 is unreasonable |
2308 | + if (fds_requested < 1 || fds_requested > 42) |
2309 | + BOOST_THROW_EXCEPTION(std::runtime_error("number of fds requested out of range")); |
2310 | + |
2311 | + for (auto i = 0; i != fds_requested; ++i) |
2312 | + { |
2313 | + auto const fd = connection_context.fd_for_new_client(connect_handler); |
2314 | + response->add_fd(fd); |
2315 | + } |
2316 | + } |
2317 | + |
2318 | + done->Run(); |
2319 | +} |
2320 | + |
2321 | +>>>>>>> MERGE-SOURCE |
2322 | void mf::SessionMediator::drm_auth_magic( |
2323 | google::protobuf::RpcController* /*controller*/, |
2324 | const mir::protobuf::DRMMagic* request, |
2325 | @@ -487,6 +535,91 @@ |
2326 | done->Run(); |
2327 | } |
2328 | |
2329 | +void mf::SessionMediator::start_trust_session(::google::protobuf::RpcController*, |
2330 | + const ::mir::protobuf::TrustSessionParameters* request, |
2331 | + ::mir::protobuf::TrustSession* response, |
2332 | + ::google::protobuf::Closure* done) |
2333 | +{ |
2334 | + { |
2335 | + std::unique_lock<std::mutex> lock(session_mutex); |
2336 | + auto session = weak_session.lock(); |
2337 | + |
2338 | + if (session.get() == nullptr) |
2339 | + BOOST_THROW_EXCEPTION(std::logic_error("Invalid application session")); |
2340 | + |
2341 | + ms::TrustSessionCreationParameters parameters; |
2342 | + parameters.set_base_process_id(request->base_trusted_session().pid()); |
2343 | + |
2344 | + std::ostringstream stream; |
2345 | + stream << "process id: " << parameters.base_process_id; |
2346 | + report->session_start_trust_session_called(session->name(), stream.str()); |
2347 | + |
2348 | + auto current_trust_session = weak_trust_session.lock(); |
2349 | + if (current_trust_session.get() != nullptr) |
2350 | + BOOST_THROW_EXCEPTION(std::runtime_error("Cannot start another trust session")); |
2351 | + |
2352 | + auto trust_session = shell->start_trust_session_for(session, parameters); |
2353 | + weak_trust_session = trust_session; |
2354 | + |
2355 | + if (trust_session) |
2356 | + { |
2357 | + response->set_state(trust_session->get_state()); |
2358 | + } |
2359 | + } |
2360 | + done->Run(); |
2361 | +} |
2362 | + |
2363 | +void mf::SessionMediator::add_trusted_session(::google::protobuf::RpcController*, |
2364 | + const ::mir::protobuf::TrustedSession* request, |
2365 | + ::mir::protobuf::TrustSessionAddResult* response, |
2366 | + ::google::protobuf::Closure* done) |
2367 | +{ |
2368 | + { |
2369 | + std::unique_lock<std::mutex> lock(session_mutex); |
2370 | + auto session = weak_session.lock(); |
2371 | + |
2372 | + if (session.get() == nullptr) |
2373 | + BOOST_THROW_EXCEPTION(std::logic_error("Invalid application session")); |
2374 | + |
2375 | + auto trust_session = weak_trust_session.lock(); |
2376 | + |
2377 | + if (trust_session.get() == nullptr) |
2378 | + BOOST_THROW_EXCEPTION(std::logic_error("Invalid trust session")); |
2379 | + |
2380 | + std::ostringstream stream; |
2381 | + stream << "process id: " << request->pid(); |
2382 | + report->session_add_trusted_session_called(session->name(), stream.str()); |
2383 | + |
2384 | + response->set_result(shell->add_trusted_session_for(trust_session, request->pid())); |
2385 | + } |
2386 | + done->Run(); |
2387 | +} |
2388 | + |
2389 | +void mf::SessionMediator::stop_trust_session(::google::protobuf::RpcController*, |
2390 | + const ::mir::protobuf::Void*, |
2391 | + ::mir::protobuf::Void*, |
2392 | + ::google::protobuf::Closure* done) |
2393 | +{ |
2394 | + { |
2395 | + std::unique_lock<std::mutex> lock(session_mutex); |
2396 | + auto session = weak_session.lock(); |
2397 | + |
2398 | + if (session.get() == nullptr) |
2399 | + BOOST_THROW_EXCEPTION(std::logic_error("Invalid application session")); |
2400 | + |
2401 | + auto trust_session = weak_trust_session.lock(); |
2402 | + weak_trust_session.reset(); |
2403 | + |
2404 | + if (trust_session.get() == nullptr) |
2405 | + BOOST_THROW_EXCEPTION(std::logic_error("Invalid trusted session")); |
2406 | + |
2407 | + report->session_stop_trust_session_called(session->name()); |
2408 | + |
2409 | + shell->stop_trust_session(trust_session); |
2410 | + } |
2411 | + done->Run(); |
2412 | +} |
2413 | + |
2414 | void mf::SessionMediator::pack_protobuf_buffer( |
2415 | protobuf::Buffer& protobuf_buffer, |
2416 | graphics::Buffer* graphics_buffer, |
2417 | |
2418 | === modified file 'src/server/frontend/session_mediator.h' |
2419 | --- src/server/frontend/session_mediator.h 2014-05-06 16:54:43 +0000 |
2420 | +++ src/server/frontend/session_mediator.h 2014-05-09 12:26:43 +0000 |
2421 | @@ -53,6 +53,7 @@ |
2422 | class EventSink; |
2423 | class DisplayChanger; |
2424 | class Screencast; |
2425 | +class TrustSession; |
2426 | |
2427 | // SessionMediator relays requests from the client process into the server. |
2428 | class SessionMediator : public mir::protobuf::DisplayServer |
2429 | @@ -123,7 +124,26 @@ |
2430 | void screencast_buffer(google::protobuf::RpcController*, |
2431 | const mir::protobuf::ScreencastId*, |
2432 | mir::protobuf::Buffer*, |
2433 | - google::protobuf::Closure* done) override; |
2434 | +<<<<<<< TREE |
2435 | + google::protobuf::Closure* done) override; |
2436 | +======= |
2437 | + google::protobuf::Closure* done) override; |
2438 | + |
2439 | + void start_trust_session(::google::protobuf::RpcController* controller, |
2440 | + const ::mir::protobuf::TrustSessionParameters* request, |
2441 | + ::mir::protobuf::TrustSession* response, |
2442 | + ::google::protobuf::Closure* done); |
2443 | + |
2444 | + void add_trusted_session(::google::protobuf::RpcController* controller, |
2445 | + const ::mir::protobuf::TrustedSession* request, |
2446 | + ::mir::protobuf::TrustSessionAddResult* response, |
2447 | + ::google::protobuf::Closure* done); |
2448 | + |
2449 | + void stop_trust_session(::google::protobuf::RpcController* controller, |
2450 | + const ::mir::protobuf::Void* request, |
2451 | + ::mir::protobuf::Void* response, |
2452 | + ::google::protobuf::Closure* done); |
2453 | +>>>>>>> MERGE-SOURCE |
2454 | |
2455 | /* Platform specific requests */ |
2456 | void drm_auth_magic(google::protobuf::RpcController* controller, |
2457 | @@ -160,8 +180,14 @@ |
2458 | |
2459 | std::mutex session_mutex; |
2460 | std::weak_ptr<Session> weak_session; |
2461 | - |
2462 | - ConnectionContext const connection_context; |
2463 | +<<<<<<< TREE |
2464 | + |
2465 | + ConnectionContext const connection_context; |
2466 | +======= |
2467 | + std::weak_ptr<TrustSession> weak_trust_session; |
2468 | + |
2469 | + ConnectionContext const connection_context; |
2470 | +>>>>>>> MERGE-SOURCE |
2471 | }; |
2472 | |
2473 | } |
2474 | |
2475 | === modified file 'src/server/report/logging/session_mediator_report.cpp' |
2476 | --- src/server/report/logging/session_mediator_report.cpp 2014-03-06 06:05:17 +0000 |
2477 | +++ src/server/report/logging/session_mediator_report.cpp 2014-05-09 12:26:43 +0000 |
2478 | @@ -73,6 +73,21 @@ |
2479 | log->log(ml::Logger::informational, "session_configure_display_called(\"" + app_name + "\")", component); |
2480 | } |
2481 | |
2482 | +void mrl::SessionMediatorReport::session_start_trust_session_called(std::string const& app_name, std::string const& trust_info) |
2483 | +{ |
2484 | + log->log(ml::Logger::informational, "session_start_trust_session_called(\"" + app_name + "\"):\n" + trust_info, component); |
2485 | +} |
2486 | + |
2487 | +void mrl::SessionMediatorReport::session_add_trusted_session_called(std::string const& app_name, std::string const& trust_info) |
2488 | +{ |
2489 | + log->log(ml::Logger::informational, "session_add_trusted_session_called(\"" + app_name + "\"):\n" + trust_info, component); |
2490 | +} |
2491 | + |
2492 | +void mrl::SessionMediatorReport::session_stop_trust_session_called(std::string const& app_name) |
2493 | +{ |
2494 | + log->log(ml::Logger::informational, "session_stop_trust_session_called(\"" + app_name + "\")", component); |
2495 | +} |
2496 | + |
2497 | void mrl::SessionMediatorReport::session_error( |
2498 | std::string const& app_name, |
2499 | char const* method, |
2500 | |
2501 | === modified file 'src/server/report/logging/session_mediator_report.h' |
2502 | --- src/server/report/logging/session_mediator_report.h 2014-03-06 06:05:17 +0000 |
2503 | +++ src/server/report/logging/session_mediator_report.h 2014-05-09 12:26:43 +0000 |
2504 | @@ -57,6 +57,12 @@ |
2505 | |
2506 | virtual void session_configure_display_called(std::string const& app_name); |
2507 | |
2508 | + virtual void session_start_trust_session_called(std::string const& app_name, std::string const& trust_info); |
2509 | + |
2510 | + virtual void session_add_trusted_session_called(std::string const& app_name, std::string const& trust_info); |
2511 | + |
2512 | + virtual void session_stop_trust_session_called(std::string const& app_name); |
2513 | + |
2514 | virtual void session_error( |
2515 | std::string const& app_name, |
2516 | char const* method, |
2517 | |
2518 | === modified file 'src/server/report/lttng/session_mediator_report.cpp' |
2519 | --- src/server/report/lttng/session_mediator_report.cpp 2014-02-09 16:18:16 +0000 |
2520 | +++ src/server/report/lttng/session_mediator_report.cpp 2014-05-09 12:26:43 +0000 |
2521 | @@ -38,6 +38,17 @@ |
2522 | MIR_SESSION_MEDIATOR_EVENT_METHOD(session_drm_auth_magic_called) |
2523 | MIR_SESSION_MEDIATOR_EVENT_METHOD(session_configure_surface_called) |
2524 | MIR_SESSION_MEDIATOR_EVENT_METHOD(session_configure_display_called) |
2525 | +MIR_SESSION_MEDIATOR_EVENT_METHOD(session_stop_trust_session_called) |
2526 | + |
2527 | +void mir::report::lttng::SessionMediatorReport::session_start_trust_session_called(std::string const& app_name, std::string const& trust_info) |
2528 | +{ |
2529 | + mir_tracepoint(mir_server_session_mediator, session_start_trust_session_called, app_name.c_str(), trust_info.c_str()); |
2530 | +} |
2531 | + |
2532 | +void mir::report::lttng::SessionMediatorReport::session_add_trusted_session_called(std::string const& app_name, std::string const& trust_info) |
2533 | +{ |
2534 | + mir_tracepoint(mir_server_session_mediator, session_add_trusted_session_called, app_name.c_str(), trust_info.c_str()); |
2535 | +} |
2536 | |
2537 | void mir::report::lttng::SessionMediatorReport::session_error(std::string const& app_name, char const* method, std::string const& what) |
2538 | { |
2539 | |
2540 | === modified file 'src/server/report/lttng/session_mediator_report.h' |
2541 | --- src/server/report/lttng/session_mediator_report.h 2014-02-09 16:18:16 +0000 |
2542 | +++ src/server/report/lttng/session_mediator_report.h 2014-05-09 12:26:43 +0000 |
2543 | @@ -41,6 +41,9 @@ |
2544 | void session_drm_auth_magic_called(std::string const& app_name) override; |
2545 | void session_configure_surface_called(std::string const& app_name) override; |
2546 | void session_configure_display_called(std::string const& app_name) override; |
2547 | + void session_start_trust_session_called(std::string const& app_name, std::string const& trust_info) override; |
2548 | + void session_add_trusted_session_called(std::string const& app_name, std::string const& trust_info) override; |
2549 | + void session_stop_trust_session_called(std::string const& app_name) override; |
2550 | |
2551 | void session_error(std::string const& app_name, char const* method, std::string const& what) override; |
2552 | private: |
2553 | |
2554 | === modified file 'src/server/report/lttng/session_mediator_report_tp.h' |
2555 | --- src/server/report/lttng/session_mediator_report_tp.h 2014-02-03 11:44:32 +0000 |
2556 | +++ src/server/report/lttng/session_mediator_report_tp.h 2014-05-09 12:26:43 +0000 |
2557 | @@ -47,6 +47,27 @@ |
2558 | MIR_SESSION_MEDIATOR_EVENT(session_drm_auth_magic_called) |
2559 | MIR_SESSION_MEDIATOR_EVENT(session_configure_surface_called) |
2560 | MIR_SESSION_MEDIATOR_EVENT(session_configure_display_called) |
2561 | +MIR_SESSION_MEDIATOR_EVENT(session_stop_trust_session_called) |
2562 | + |
2563 | +TRACEPOINT_EVENT( |
2564 | + mir_server_session_mediator, |
2565 | + session_start_trust_session_called, |
2566 | + TP_ARGS(char const*, application, char const*, trust_info), |
2567 | + TP_FIELDS( |
2568 | + ctf_string(application, application) |
2569 | + ctf_string(trust_info, trust_info) |
2570 | + ) |
2571 | + ) |
2572 | + |
2573 | +TRACEPOINT_EVENT( |
2574 | + mir_server_session_mediator, |
2575 | + session_add_trusted_session_called, |
2576 | + TP_ARGS(char const*, application, char const*, trust_info), |
2577 | + TP_FIELDS( |
2578 | + ctf_string(application, application) |
2579 | + ctf_string(trust_info, trust_info) |
2580 | + ) |
2581 | + ) |
2582 | |
2583 | TRACEPOINT_EVENT( |
2584 | mir_server_session_mediator, |
2585 | |
2586 | === modified file 'src/server/report/null/session_mediator_report.cpp' |
2587 | --- src/server/report/null/session_mediator_report.cpp 2014-03-06 06:05:17 +0000 |
2588 | +++ src/server/report/null/session_mediator_report.cpp 2014-05-09 12:26:43 +0000 |
2589 | @@ -50,6 +50,18 @@ |
2590 | { |
2591 | } |
2592 | |
2593 | +void mir::report::null::SessionMediatorReport::session_start_trust_session_called(std::string const&, std::string const&) |
2594 | +{ |
2595 | +} |
2596 | + |
2597 | +void mir::report::null::SessionMediatorReport::session_add_trusted_session_called(std::string const&, std::string const&) |
2598 | +{ |
2599 | +} |
2600 | + |
2601 | +void mir::report::null::SessionMediatorReport::session_stop_trust_session_called(std::string const&) |
2602 | +{ |
2603 | +} |
2604 | + |
2605 | void mir::report::null::SessionMediatorReport::session_error( |
2606 | std::string const&, |
2607 | char const* , |
2608 | |
2609 | === modified file 'src/server/report/null/session_mediator_report.h' |
2610 | --- src/server/report/null/session_mediator_report.h 2014-02-09 16:18:16 +0000 |
2611 | +++ src/server/report/null/session_mediator_report.h 2014-05-09 12:26:43 +0000 |
2612 | @@ -51,6 +51,12 @@ |
2613 | |
2614 | void session_configure_display_called(std::string const& app_name) override; |
2615 | |
2616 | + void session_start_trust_session_called(std::string const& app_name, std::string const& trust_info) override; |
2617 | + |
2618 | + void session_add_trusted_session_called(std::string const& app_name, std::string const& trust_info) override; |
2619 | + |
2620 | + void session_stop_trust_session_called(std::string const& app_name) override; |
2621 | + |
2622 | void session_error( |
2623 | std::string const& app_name, |
2624 | char const* method, |
2625 | |
2626 | === modified file 'src/server/scene/CMakeLists.txt' |
2627 | --- src/server/scene/CMakeLists.txt 2014-05-06 03:33:05 +0000 |
2628 | +++ src/server/scene/CMakeLists.txt 2014-05-09 12:26:43 +0000 |
2629 | @@ -20,4 +20,7 @@ |
2630 | threaded_snapshot_strategy.cpp |
2631 | legacy_scene_change_notification.cpp |
2632 | legacy_surface_change_notification.cpp |
2633 | + trust_session_impl.cpp |
2634 | + trust_session_container.cpp |
2635 | + trust_session_creation_parameters.cpp |
2636 | ) |
2637 | |
2638 | === modified file 'src/server/scene/application_session.cpp' |
2639 | --- src/server/scene/application_session.cpp 2014-05-06 16:54:43 +0000 |
2640 | +++ src/server/scene/application_session.cpp 2014-05-09 12:26:43 +0000 |
2641 | @@ -23,6 +23,7 @@ |
2642 | #include "snapshot_strategy.h" |
2643 | #include "mir/scene/session_listener.h" |
2644 | #include "mir/frontend/event_sink.h" |
2645 | +#include "default_session_container.h" |
2646 | |
2647 | #include <boost/throw_exception.hpp> |
2648 | |
2649 | @@ -30,6 +31,7 @@ |
2650 | #include <memory> |
2651 | #include <cassert> |
2652 | #include <algorithm> |
2653 | +#include <cstring> |
2654 | |
2655 | namespace mf = mir::frontend; |
2656 | namespace ms = mir::scene; |
2657 | @@ -181,3 +183,22 @@ |
2658 | { |
2659 | event_sink->handle_lifecycle_event(state); |
2660 | } |
2661 | + |
2662 | +void ms::ApplicationSession::begin_trust_session() |
2663 | +{ |
2664 | + // All sessions which are part of the trust session get this event. |
2665 | + MirEvent start_event; |
2666 | + memset(&start_event, 0, sizeof start_event); |
2667 | + start_event.type = mir_event_type_trust_session_state_change; |
2668 | + start_event.trust_session.new_state = mir_trust_session_state_started; |
2669 | + event_sink->handle_event(start_event); |
2670 | +} |
2671 | + |
2672 | +void ms::ApplicationSession::end_trust_session() |
2673 | +{ |
2674 | + MirEvent stop_event; |
2675 | + memset(&stop_event, 0, sizeof stop_event); |
2676 | + stop_event.type = mir_event_type_trust_session_state_change; |
2677 | + stop_event.trust_session.new_state = mir_trust_session_state_stopped; |
2678 | + event_sink->handle_event(stop_event); |
2679 | +} |
2680 | |
2681 | === modified file 'src/server/scene/application_session.h' |
2682 | --- src/server/scene/application_session.h 2014-05-06 16:54:43 +0000 |
2683 | +++ src/server/scene/application_session.h 2014-05-09 12:26:43 +0000 |
2684 | @@ -71,6 +71,9 @@ |
2685 | |
2686 | void set_lifecycle_state(MirLifecycleState state); |
2687 | |
2688 | + void begin_trust_session() override; |
2689 | + void end_trust_session() override; |
2690 | + |
2691 | protected: |
2692 | ApplicationSession(ApplicationSession const&) = delete; |
2693 | ApplicationSession& operator=(ApplicationSession const&) = delete; |
2694 | |
2695 | === modified file 'src/server/scene/default_configuration.cpp' |
2696 | --- src/server/scene/default_configuration.cpp 2014-05-09 03:00:20 +0000 |
2697 | +++ src/server/scene/default_configuration.cpp 2014-05-09 12:26:43 +0000 |
2698 | @@ -25,12 +25,12 @@ |
2699 | #include "mir/abnormal_exit.h" |
2700 | #include "mir/scene/session.h" |
2701 | |
2702 | +#include "session_container.h" |
2703 | #include "broadcasting_session_event_sink.h" |
2704 | #include "default_session_container.h" |
2705 | #include "gl_pixel_buffer.h" |
2706 | #include "global_event_sender.h" |
2707 | #include "mediating_display_changer.h" |
2708 | -#include "session_container.h" |
2709 | #include "session_manager.h" |
2710 | #include "surface_allocator.h" |
2711 | #include "surface_controller.h" |
2712 | @@ -184,7 +184,8 @@ |
2713 | the_shell_focus_setter(), |
2714 | the_snapshot_strategy(), |
2715 | the_session_event_sink(), |
2716 | - the_session_listener()); |
2717 | + the_session_listener(), |
2718 | + the_trust_session_listener()); |
2719 | }); |
2720 | } |
2721 | |
2722 | |
2723 | === modified file 'src/server/scene/session_manager.cpp' |
2724 | --- src/server/scene/session_manager.cpp 2014-04-15 05:31:19 +0000 |
2725 | +++ src/server/scene/session_manager.cpp 2014-05-09 12:26:43 +0000 |
2726 | @@ -24,6 +24,12 @@ |
2727 | #include "mir/scene/session.h" |
2728 | #include "mir/scene/session_listener.h" |
2729 | #include "session_event_sink.h" |
2730 | +#include "mir/scene/trust_session_creation_parameters.h" |
2731 | +#include "trust_session_impl.h" |
2732 | +#include "trust_session_container.h" |
2733 | +#include "mir/scene/trust_session_listener.h" |
2734 | + |
2735 | +#include <boost/throw_exception.hpp> |
2736 | |
2737 | #include <memory> |
2738 | #include <cassert> |
2739 | @@ -38,13 +44,16 @@ |
2740 | std::shared_ptr<msh::FocusSetter> const& focus_setter, |
2741 | std::shared_ptr<SnapshotStrategy> const& snapshot_strategy, |
2742 | std::shared_ptr<SessionEventSink> const& session_event_sink, |
2743 | - std::shared_ptr<SessionListener> const& session_listener) : |
2744 | + std::shared_ptr<SessionListener> const& session_listener, |
2745 | + std::shared_ptr<TrustSessionListener> const& trust_session_listener) : |
2746 | surface_coordinator(surface_factory), |
2747 | app_container(container), |
2748 | focus_setter(focus_setter), |
2749 | snapshot_strategy(snapshot_strategy), |
2750 | session_event_sink(session_event_sink), |
2751 | - session_listener(session_listener) |
2752 | + session_listener(session_listener), |
2753 | + trust_session_listener(trust_session_listener), |
2754 | + trust_session_container(std::make_shared<TrustSessionContainer>()) |
2755 | { |
2756 | assert(surface_factory); |
2757 | assert(container); |
2758 | @@ -85,6 +94,16 @@ |
2759 | |
2760 | session_listener->starting(new_session); |
2761 | |
2762 | + { |
2763 | + trust_session_container->for_each_trust_session_for_process(client_pid, |
2764 | + [client_pid, new_session](std::shared_ptr<frontend::TrustSession> const& trust_session) |
2765 | + { |
2766 | + auto scene_trust_session = std::dynamic_pointer_cast<ms::TrustSession>(trust_session); |
2767 | + |
2768 | + scene_trust_session->add_trusted_child(new_session); |
2769 | + }); |
2770 | + } |
2771 | + |
2772 | set_focus_to(new_session); |
2773 | |
2774 | return new_session; |
2775 | @@ -122,12 +141,45 @@ |
2776 | scene_session->force_requests_to_complete(); |
2777 | |
2778 | session_event_sink->handle_session_stopping(scene_session); |
2779 | + |
2780 | + { |
2781 | + std::unique_lock<std::mutex> lock(trust_sessions_mutex); |
2782 | + |
2783 | + std::vector<std::shared_ptr<frontend::TrustSession>> trust_sessions; |
2784 | + trust_session_container->for_each_trust_session_for_process(scene_session->process_id(), |
2785 | + [&](std::shared_ptr<frontend::TrustSession> const& trust_session) |
2786 | + { |
2787 | + trust_sessions.push_back(trust_session); |
2788 | + }); |
2789 | + |
2790 | + for(auto trust_session : trust_sessions) |
2791 | + { |
2792 | + auto scene_trust_session = std::dynamic_pointer_cast<ms::TrustSession>(trust_session); |
2793 | + |
2794 | + if (scene_trust_session->get_trusted_helper().lock() == scene_session) |
2795 | + { |
2796 | + stop_trust_session_locked(lock, scene_trust_session); |
2797 | + } |
2798 | + else |
2799 | + { |
2800 | + scene_trust_session->remove_trusted_child(scene_session); |
2801 | + |
2802 | + trust_session_container->remove_process(scene_session->process_id()); |
2803 | + } |
2804 | + } |
2805 | + } |
2806 | + |
2807 | session_listener->stopping(scene_session); |
2808 | |
2809 | app_container->remove_session(scene_session); |
2810 | |
2811 | std::unique_lock<std::mutex> lock(mutex); |
2812 | - set_focus_to_locked(lock, app_container->successor_of(std::shared_ptr<Session>())); |
2813 | + auto old_focus = focus_application.lock(); |
2814 | + if (old_focus == scene_session) |
2815 | + { |
2816 | + // only reset the focus if this session had focus |
2817 | + set_focus_to_locked(lock, app_container->successor_of(std::shared_ptr<ms::Session>())); |
2818 | + } |
2819 | } |
2820 | |
2821 | void ms::SessionManager::focus_next() |
2822 | @@ -169,3 +221,73 @@ |
2823 | { |
2824 | set_focus_to(std::dynamic_pointer_cast<Session>(session)); |
2825 | } |
2826 | + |
2827 | +std::shared_ptr<mf::TrustSession> ms::SessionManager::start_trust_session_for(std::shared_ptr<mf::Session> const& session, |
2828 | + TrustSessionCreationParameters const& params) |
2829 | +{ |
2830 | + std::unique_lock<std::mutex> lock(trust_sessions_mutex); |
2831 | + |
2832 | + auto shell_session = std::dynamic_pointer_cast<ms::Session>(session); |
2833 | + |
2834 | + auto const trust_session = std::make_shared<TrustSessionImpl>(shell_session, params, trust_session_listener); |
2835 | + |
2836 | + trust_session_container->insert(trust_session, shell_session->process_id()); |
2837 | + |
2838 | + trust_session->start(); |
2839 | + trust_session_listener->starting(*(trust_session.get())); |
2840 | + |
2841 | + add_trusted_session_for_locked(lock, trust_session, params.base_process_id); |
2842 | + return trust_session; |
2843 | +} |
2844 | + |
2845 | +MirTrustSessionAddTrustResult ms::SessionManager::add_trusted_session_for(std::shared_ptr<mf::TrustSession> const& trust_session, |
2846 | + pid_t session_pid) |
2847 | +{ |
2848 | + std::unique_lock<std::mutex> lock(trust_sessions_mutex); |
2849 | + |
2850 | + return add_trusted_session_for_locked(lock, trust_session, session_pid); |
2851 | +} |
2852 | + |
2853 | +MirTrustSessionAddTrustResult ms::SessionManager::add_trusted_session_for_locked(std::unique_lock<std::mutex> const&, |
2854 | + std::shared_ptr<mf::TrustSession> const& trust_session, |
2855 | + pid_t session_pid) |
2856 | +{ |
2857 | + auto scene_trust_session = std::dynamic_pointer_cast<ms::TrustSession>(trust_session); |
2858 | + |
2859 | + trust_session_container->insert(trust_session, session_pid); |
2860 | + |
2861 | + bool added = false; |
2862 | + app_container->for_each( |
2863 | + [&](std::shared_ptr<ms::Session> const& container_session) |
2864 | + { |
2865 | + if (container_session->process_id() == session_pid) |
2866 | + { |
2867 | + added |= scene_trust_session->add_trusted_child(container_session); |
2868 | + } |
2869 | + }); |
2870 | + |
2871 | + if (!added) |
2872 | + BOOST_THROW_EXCEPTION(std::runtime_error("failed to add trusted session")); |
2873 | + |
2874 | + return mir_trust_session_add_tust_succeeded; |
2875 | +} |
2876 | + |
2877 | +void ms::SessionManager::stop_trust_session(std::shared_ptr<mf::TrustSession> const& trust_session) |
2878 | +{ |
2879 | + std::unique_lock<std::mutex> lock(trust_sessions_mutex); |
2880 | + |
2881 | + stop_trust_session_locked(lock, trust_session); |
2882 | +} |
2883 | + |
2884 | +void ms::SessionManager::stop_trust_session_locked(std::unique_lock<std::mutex> const&, |
2885 | + std::shared_ptr<mf::TrustSession> const& trust_session) |
2886 | +{ |
2887 | + auto scene_trust_session = std::dynamic_pointer_cast<ms::TrustSession>(trust_session); |
2888 | + |
2889 | + trust_session->stop(); |
2890 | + |
2891 | + trust_session_container->remove_trust_session(trust_session); |
2892 | + |
2893 | + trust_session_listener->stopping(*(scene_trust_session).get()); |
2894 | +} |
2895 | + |
2896 | |
2897 | === modified file 'src/server/scene/session_manager.h' |
2898 | --- src/server/scene/session_manager.h 2014-04-15 05:31:19 +0000 |
2899 | +++ src/server/scene/session_manager.h 2014-05-09 12:26:43 +0000 |
2900 | @@ -26,6 +26,7 @@ |
2901 | #include <mutex> |
2902 | #include <memory> |
2903 | #include <vector> |
2904 | +#include <map> |
2905 | |
2906 | namespace mir |
2907 | { |
2908 | @@ -42,6 +43,8 @@ |
2909 | class SessionListener; |
2910 | class SnapshotStrategy; |
2911 | class SurfaceCoordinator; |
2912 | +class TrustSessionContainer; |
2913 | +class TrustSessionListener; |
2914 | |
2915 | class SessionManager : public frontend::Shell, public shell::FocusController |
2916 | { |
2917 | @@ -51,7 +54,8 @@ |
2918 | std::shared_ptr<shell::FocusSetter> const& focus_setter, |
2919 | std::shared_ptr<SnapshotStrategy> const& snapshot_strategy, |
2920 | std::shared_ptr<SessionEventSink> const& session_event_sink, |
2921 | - std::shared_ptr<SessionListener> const& session_listener); |
2922 | + std::shared_ptr<SessionListener> const& session_listener, |
2923 | + std::shared_ptr<TrustSessionListener> const& trust_session_listener); |
2924 | virtual ~SessionManager(); |
2925 | |
2926 | virtual std::shared_ptr<frontend::Session> open_session( |
2927 | @@ -71,6 +75,12 @@ |
2928 | |
2929 | void handle_surface_created(std::shared_ptr<frontend::Session> const& session) override; |
2930 | |
2931 | + std::shared_ptr<frontend::TrustSession> start_trust_session_for(std::shared_ptr<frontend::Session> const& session, |
2932 | + TrustSessionCreationParameters const& params) override; |
2933 | + MirTrustSessionAddTrustResult add_trusted_session_for(std::shared_ptr<frontend::TrustSession> const& trust_session, |
2934 | + pid_t session_pid) override; |
2935 | + void stop_trust_session(std::shared_ptr<frontend::TrustSession> const& trust_session) override; |
2936 | + |
2937 | protected: |
2938 | SessionManager(const SessionManager&) = delete; |
2939 | SessionManager& operator=(const SessionManager&) = delete; |
2940 | @@ -82,11 +92,20 @@ |
2941 | std::shared_ptr<SnapshotStrategy> const snapshot_strategy; |
2942 | std::shared_ptr<SessionEventSink> const session_event_sink; |
2943 | std::shared_ptr<SessionListener> const session_listener; |
2944 | + std::shared_ptr<TrustSessionListener> const trust_session_listener; |
2945 | + std::shared_ptr<TrustSessionContainer> trust_session_container; |
2946 | |
2947 | std::mutex mutex; |
2948 | std::weak_ptr<Session> focus_application; |
2949 | |
2950 | void set_focus_to_locked(std::unique_lock<std::mutex> const& lock, std::shared_ptr<Session> const& next_focus); |
2951 | + |
2952 | + MirTrustSessionAddTrustResult add_trusted_session_for_locked(std::unique_lock<std::mutex> const&, |
2953 | + std::shared_ptr<frontend::TrustSession> const& trust_session, |
2954 | + pid_t session_pid); |
2955 | + void stop_trust_session_locked(std::unique_lock<std::mutex> const& lock, |
2956 | + std::shared_ptr<frontend::TrustSession> const& trust_session); |
2957 | + std::mutex mutable trust_sessions_mutex; |
2958 | }; |
2959 | |
2960 | } |
2961 | |
2962 | === added file 'src/server/scene/trust_session_container.cpp' |
2963 | --- src/server/scene/trust_session_container.cpp 1970-01-01 00:00:00 +0000 |
2964 | +++ src/server/scene/trust_session_container.cpp 2014-05-09 12:26:43 +0000 |
2965 | @@ -0,0 +1,95 @@ |
2966 | +/* |
2967 | + * Copyright © 2014 Canonical Ltd. |
2968 | + * |
2969 | + * This program is free software: you can redistribute it and/or modify it |
2970 | + * under the terms of the GNU General Public License version 3, |
2971 | + * as published by the Free Software Foundation. |
2972 | + * |
2973 | + * This program is distributed in the hope that it will be useful, |
2974 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2975 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2976 | + * GNU General Public License for more details. |
2977 | + * |
2978 | + * You should have received a copy of the GNU General Public License |
2979 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2980 | + * |
2981 | + * Authored By: Nick Dedekind <nick.dedekind@canonical.com> |
2982 | + */ |
2983 | + |
2984 | +#include "trust_session_container.h" |
2985 | + |
2986 | +namespace ms = mir::scene; |
2987 | +namespace mf = mir::frontend; |
2988 | + |
2989 | +uint insertion_order = 0; |
2990 | + |
2991 | +ms::TrustSessionContainer::TrustSessionContainer() |
2992 | + : trust_session_index(process_map) |
2993 | + , process_index(get<1>(process_map)) |
2994 | +{ |
2995 | +} |
2996 | + |
2997 | +bool ms::TrustSessionContainer::insert(std::shared_ptr<mf::TrustSession> const& trust_session, ClientProcess const& process) |
2998 | +{ |
2999 | + std::unique_lock<std::mutex> lk(mutex); |
3000 | + |
3001 | + object_by_trust_session::iterator it; |
3002 | + bool valid = false; |
3003 | + |
3004 | + Object obj{trust_session, process, insertion_order++}; |
3005 | + boost::tie(it,valid) = process_map.insert(obj); |
3006 | + |
3007 | + return valid; |
3008 | +} |
3009 | + |
3010 | +void ms::TrustSessionContainer::for_each_process_for_trust_session( |
3011 | + std::shared_ptr<mf::TrustSession> const& trust_session, |
3012 | + std::function<void(ClientProcess const& id)> f) |
3013 | +{ |
3014 | + std::unique_lock<std::mutex> lk(mutex); |
3015 | + |
3016 | + object_by_trust_session::iterator it,end; |
3017 | + boost::tie(it,end) = trust_session_index.equal_range(trust_session); |
3018 | + |
3019 | + for (; it != end; ++it) |
3020 | + { |
3021 | + Object const& obj = *it; |
3022 | + f(obj.client_process); |
3023 | + } |
3024 | +} |
3025 | + |
3026 | +void ms::TrustSessionContainer::for_each_trust_session_for_process( |
3027 | + ClientProcess const& process, |
3028 | + std::function<void(std::shared_ptr<mf::TrustSession> const&)> f) |
3029 | +{ |
3030 | + std::unique_lock<std::mutex> lk(mutex); |
3031 | + |
3032 | + object_by_process::iterator it,end; |
3033 | + boost::tie(it,end) = process_index.equal_range(process); |
3034 | + |
3035 | + for (; it != end; ++it) |
3036 | + { |
3037 | + Object const& obj = *it; |
3038 | + f(obj.trust_session); |
3039 | + } |
3040 | +} |
3041 | + |
3042 | +void ms::TrustSessionContainer::remove_trust_session(std::shared_ptr<frontend::TrustSession> const& trust_session) |
3043 | +{ |
3044 | + std::unique_lock<std::mutex> lk(mutex); |
3045 | + |
3046 | + object_by_trust_session::iterator it,end; |
3047 | + boost::tie(it,end) = trust_session_index.equal_range(trust_session); |
3048 | + |
3049 | + trust_session_index.erase(it, end); |
3050 | +} |
3051 | + |
3052 | +void ms::TrustSessionContainer::remove_process(ClientProcess const& process) |
3053 | +{ |
3054 | + std::unique_lock<std::mutex> lk(mutex); |
3055 | + |
3056 | + object_by_process::iterator it,end; |
3057 | + boost::tie(it,end) = process_index.equal_range(process); |
3058 | + |
3059 | + process_index.erase(it, end); |
3060 | +} |
3061 | |
3062 | === added file 'src/server/scene/trust_session_container.h' |
3063 | --- src/server/scene/trust_session_container.h 1970-01-01 00:00:00 +0000 |
3064 | +++ src/server/scene/trust_session_container.h 2014-05-09 12:26:43 +0000 |
3065 | @@ -0,0 +1,103 @@ |
3066 | +/* |
3067 | + * Copyright © 2014 Canonical Ltd. |
3068 | + * |
3069 | + * This program is free software: you can redistribute it and/or modify it |
3070 | + * under the terms of the GNU General Public License version 3, |
3071 | + * as published by the Free Software Foundation. |
3072 | + * |
3073 | + * This program is distributed in the hope that it will be useful, |
3074 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3075 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3076 | + * GNU General Public License for more details. |
3077 | + * |
3078 | + * You should have received a copy of the GNU General Public License |
3079 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3080 | + * |
3081 | + * Authored By: Nick Dedekind <nick.dedekind@canonical.com> |
3082 | + */ |
3083 | + |
3084 | +#ifndef MIR_SCENE_TRUST_SESSION_CONTAINER_H_ |
3085 | +#define MIR_SCENE_TRUST_SESSION_CONTAINER_H_ |
3086 | + |
3087 | +#include <sys/types.h> |
3088 | +#include <mutex> |
3089 | +#include <map> |
3090 | + |
3091 | +#include <boost/multi_index_container.hpp> |
3092 | +#include <boost/multi_index/member.hpp> |
3093 | +#include <boost/multi_index/ordered_index.hpp> |
3094 | +#include <boost/multi_index/hashed_index.hpp> |
3095 | +#include <boost/multi_index/composite_key.hpp> |
3096 | + |
3097 | +namespace mir |
3098 | +{ |
3099 | +namespace frontend |
3100 | +{ |
3101 | +class TrustSession; |
3102 | +class Session; |
3103 | +} |
3104 | + |
3105 | +using boost::multi_index_container; |
3106 | +using namespace boost::multi_index; |
3107 | + |
3108 | +namespace scene |
3109 | +{ |
3110 | + |
3111 | +class TrustSessionContainer |
3112 | +{ |
3113 | +public: |
3114 | + TrustSessionContainer(); |
3115 | + virtual ~TrustSessionContainer() = default; |
3116 | + |
3117 | + typedef pid_t ClientProcess; |
3118 | + |
3119 | + bool insert(std::shared_ptr<frontend::TrustSession> const& trust_session, ClientProcess const& process); |
3120 | + |
3121 | + void for_each_process_for_trust_session(std::shared_ptr<frontend::TrustSession> const& trust_session, std::function<void(ClientProcess const&)> f); |
3122 | + void for_each_trust_session_for_process(ClientProcess const& process, std::function<void(std::shared_ptr<frontend::TrustSession> const&)> f); |
3123 | + |
3124 | + void remove_trust_session(std::shared_ptr<frontend::TrustSession> const& trust_session); |
3125 | + void remove_process(ClientProcess const& process); |
3126 | + |
3127 | +private: |
3128 | + std::mutex mutable mutex; |
3129 | + |
3130 | + typedef struct { |
3131 | + std::shared_ptr<frontend::TrustSession> trust_session; |
3132 | + ClientProcess client_process; |
3133 | + uint insert_order; |
3134 | + } Object; |
3135 | + |
3136 | + typedef multi_index_container< |
3137 | + Object, |
3138 | + indexed_by< |
3139 | + ordered_non_unique< |
3140 | + composite_key< |
3141 | + Object, |
3142 | + member<Object, std::shared_ptr<frontend::TrustSession>, &Object::trust_session>, |
3143 | + member<Object, uint, &Object::insert_order> |
3144 | + > |
3145 | + >, |
3146 | + ordered_unique< |
3147 | + composite_key< |
3148 | + Object, |
3149 | + member<Object, ClientProcess, &Object::client_process>, |
3150 | + member<Object, std::shared_ptr<frontend::TrustSession>, &Object::trust_session> |
3151 | + > |
3152 | + > |
3153 | + > |
3154 | + > TrustSessionsProcesses; |
3155 | + |
3156 | + typedef nth_index<TrustSessionsProcesses,0>::type object_by_trust_session; |
3157 | + typedef nth_index<TrustSessionsProcesses,1>::type object_by_process; |
3158 | + |
3159 | + |
3160 | + TrustSessionsProcesses process_map; |
3161 | + object_by_trust_session& trust_session_index; |
3162 | + object_by_process& process_index; |
3163 | +}; |
3164 | + |
3165 | +} |
3166 | +} |
3167 | + |
3168 | +#endif // MIR_SCENE_TRUST_SESSION_CONTAINER_H_ |
3169 | |
3170 | === added file 'src/server/scene/trust_session_creation_parameters.cpp' |
3171 | --- src/server/scene/trust_session_creation_parameters.cpp 1970-01-01 00:00:00 +0000 |
3172 | +++ src/server/scene/trust_session_creation_parameters.cpp 2014-05-09 12:26:43 +0000 |
3173 | @@ -0,0 +1,51 @@ |
3174 | +/* |
3175 | + * Copyright © 2014 Canonical Ltd. |
3176 | + * |
3177 | + * This program is free software: you can redistribute it and/or modify it |
3178 | + * under the terms of the GNU General Public License version 3, |
3179 | + * as published by the Free Software Foundation. |
3180 | + * |
3181 | + * This program is distributed in the hope that it will be useful, |
3182 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3183 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3184 | + * GNU General Public License for more details. |
3185 | + * |
3186 | + * You should have received a copy of the GNU General Public License |
3187 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3188 | + * |
3189 | + * Authored By: Nick Dedekind <nick.dedekind@canonical.com> |
3190 | + */ |
3191 | + |
3192 | +#include "mir/scene/trust_session_creation_parameters.h" |
3193 | + |
3194 | +namespace ms = mir::scene; |
3195 | + |
3196 | +ms::TrustSessionCreationParameters::TrustSessionCreationParameters() |
3197 | + : base_process_id(0) |
3198 | +{ |
3199 | +} |
3200 | + |
3201 | +ms::TrustSessionCreationParameters& ms::TrustSessionCreationParameters::set_base_process_id(pid_t process_id) |
3202 | +{ |
3203 | + base_process_id = process_id; |
3204 | + return *this; |
3205 | +} |
3206 | + |
3207 | +bool ms::operator==( |
3208 | + const TrustSessionCreationParameters& lhs, |
3209 | + const TrustSessionCreationParameters& rhs) |
3210 | +{ |
3211 | + return lhs.base_process_id == rhs.base_process_id; |
3212 | +} |
3213 | + |
3214 | +bool ms::operator!=( |
3215 | + const TrustSessionCreationParameters& lhs, |
3216 | + const TrustSessionCreationParameters& rhs) |
3217 | +{ |
3218 | + return !(lhs == rhs); |
3219 | +} |
3220 | + |
3221 | +ms::TrustSessionCreationParameters ms::a_trust_session() |
3222 | +{ |
3223 | + return TrustSessionCreationParameters(); |
3224 | +} |
3225 | |
3226 | === added file 'src/server/scene/trust_session_impl.cpp' |
3227 | --- src/server/scene/trust_session_impl.cpp 1970-01-01 00:00:00 +0000 |
3228 | +++ src/server/scene/trust_session_impl.cpp 2014-05-09 12:26:43 +0000 |
3229 | @@ -0,0 +1,187 @@ |
3230 | +/* |
3231 | + * Copyright © 2014 Canonical Ltd. |
3232 | + * |
3233 | + * This program is free software: you can redistribute it and/or modify it |
3234 | + * under the terms of the GNU General Public License version 3, |
3235 | + * as published by the Free Software Foundation. |
3236 | + * |
3237 | + * This program is distributed in the hope that it will be useful, |
3238 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3239 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3240 | + * GNU General Public License for more details. |
3241 | + * |
3242 | + * You should have received a copy of the GNU General Public License |
3243 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3244 | + * |
3245 | + * Authored By: Nick Dedekind <nick.dedekind@canonical.com> |
3246 | + */ |
3247 | + |
3248 | +#include "trust_session_impl.h" |
3249 | +#include "mir/scene/session.h" |
3250 | +#include "mir/scene/trust_session_creation_parameters.h" |
3251 | +#include "mir/scene/trust_session_listener.h" |
3252 | +#include "session_container.h" |
3253 | + |
3254 | +#include <sstream> |
3255 | +#include <algorithm> |
3256 | + |
3257 | +namespace ms = mir::scene; |
3258 | + |
3259 | +int next_unique_id = 0; |
3260 | + |
3261 | +ms::TrustSessionImpl::TrustSessionImpl( |
3262 | + std::weak_ptr<ms::Session> const& session, |
3263 | + TrustSessionCreationParameters const&, |
3264 | + std::shared_ptr<TrustSessionListener> const& trust_session_listener) : |
3265 | + trusted_helper(session), |
3266 | + trust_session_listener(trust_session_listener), |
3267 | + state(mir_trust_session_state_stopped) |
3268 | +{ |
3269 | +} |
3270 | + |
3271 | +ms::TrustSessionImpl::~TrustSessionImpl() |
3272 | +{ |
3273 | + TrustSessionImpl::stop(); |
3274 | +} |
3275 | + |
3276 | +MirTrustSessionState ms::TrustSessionImpl::get_state() const |
3277 | +{ |
3278 | + std::lock_guard<decltype(mutex)> lock(mutex); |
3279 | + |
3280 | + return state; |
3281 | +} |
3282 | + |
3283 | +std::weak_ptr<ms::Session> ms::TrustSessionImpl::get_trusted_helper() const |
3284 | +{ |
3285 | + std::lock_guard<decltype(mutex)> lock(mutex); |
3286 | + |
3287 | + return trusted_helper; |
3288 | +} |
3289 | + |
3290 | +void ms::TrustSessionImpl::start() |
3291 | +{ |
3292 | + std::lock_guard<decltype(mutex)> lock(mutex); |
3293 | + |
3294 | + if (state == mir_trust_session_state_started) |
3295 | + return; |
3296 | + |
3297 | + state = mir_trust_session_state_started; |
3298 | + |
3299 | + auto helper = trusted_helper.lock(); |
3300 | + if (helper) { |
3301 | + helper->begin_trust_session(); |
3302 | + } |
3303 | +} |
3304 | + |
3305 | +void ms::TrustSessionImpl::stop() |
3306 | +{ |
3307 | + std::lock_guard<decltype(mutex)> lock(mutex); |
3308 | + |
3309 | + if (state == mir_trust_session_state_stopped) |
3310 | + return; |
3311 | + |
3312 | + state = mir_trust_session_state_stopped; |
3313 | + |
3314 | + auto helper = trusted_helper.lock(); |
3315 | + if (helper) { |
3316 | + helper->end_trust_session(); |
3317 | + } |
3318 | + |
3319 | + std::vector<std::shared_ptr<ms::Session>> children; |
3320 | + { |
3321 | + std::lock_guard<decltype(mutex_children)> child_lock(mutex_children); |
3322 | + |
3323 | + for (auto rit = trusted_children.rbegin(); rit != trusted_children.rend(); ++rit) |
3324 | + { |
3325 | + auto session = (*rit).lock(); |
3326 | + if (session) |
3327 | + { |
3328 | + children.push_back(session); |
3329 | + } |
3330 | + } |
3331 | + trusted_children.clear(); |
3332 | + } |
3333 | + |
3334 | + for (auto session : children) |
3335 | + { |
3336 | + trust_session_listener->trusted_session_ending(*this, *(session).get()); |
3337 | + } |
3338 | +} |
3339 | + |
3340 | +bool ms::TrustSessionImpl::add_trusted_child(std::shared_ptr<ms::Session> const& session) |
3341 | +{ |
3342 | + std::lock_guard<decltype(mutex)> lock(mutex); |
3343 | + |
3344 | + if (state == mir_trust_session_state_stopped) |
3345 | + return false; |
3346 | + |
3347 | + { |
3348 | + std::lock_guard<decltype(mutex_children)> child_lock(mutex_children); |
3349 | + |
3350 | + if (std::find_if(trusted_children.begin(), trusted_children.end(), |
3351 | + [session](std::weak_ptr<ms::Session> const& child) |
3352 | + { |
3353 | + return child.lock() == session; |
3354 | + }) != trusted_children.end()) |
3355 | + { |
3356 | + return false; |
3357 | + } |
3358 | + |
3359 | + trusted_children.push_back(session); |
3360 | + } |
3361 | + |
3362 | + trust_session_listener->trusted_session_beginning(*this, *(session).get()); |
3363 | + return true; |
3364 | +} |
3365 | + |
3366 | +void ms::TrustSessionImpl::remove_trusted_child(std::shared_ptr<ms::Session> const& session) |
3367 | +{ |
3368 | + std::lock_guard<decltype(mutex)> lock(mutex); |
3369 | + |
3370 | + if (state == mir_trust_session_state_stopped) |
3371 | + return; |
3372 | + |
3373 | + bool found = false; |
3374 | + { |
3375 | + std::lock_guard<decltype(mutex_children)> child_lock(mutex_children); |
3376 | + |
3377 | + for (auto it = trusted_children.begin(); it != trusted_children.end(); ++it) |
3378 | + { |
3379 | + auto trusted_child = (*it).lock(); |
3380 | + if (trusted_child && trusted_child == session) { |
3381 | + found = true; |
3382 | + trusted_children.erase(it); |
3383 | + break; |
3384 | + } |
3385 | + } |
3386 | + } |
3387 | + |
3388 | + if (found) |
3389 | + { |
3390 | + trust_session_listener->trusted_session_ending(*this, *(session).get()); |
3391 | + } |
3392 | +} |
3393 | + |
3394 | +void ms::TrustSessionImpl::for_each_trusted_child( |
3395 | + std::function<void(std::shared_ptr<ms::Session> const&)> f, |
3396 | + bool reverse) const |
3397 | +{ |
3398 | + std::lock_guard<decltype(mutex_children)> child_lock(mutex_children); |
3399 | + |
3400 | + if (reverse) |
3401 | + { |
3402 | + for (auto rit = trusted_children.rbegin(); rit != trusted_children.rend(); ++rit) |
3403 | + { |
3404 | + if (auto trusted_child = (*rit).lock()) |
3405 | + f(trusted_child); |
3406 | + } |
3407 | + } |
3408 | + else |
3409 | + { |
3410 | + for (auto it = trusted_children.begin(); it != trusted_children.end(); ++it) |
3411 | + { |
3412 | + if (auto trusted_child = (*it).lock()) |
3413 | + f(trusted_child); |
3414 | + } |
3415 | + } |
3416 | +} |
3417 | |
3418 | === added file 'src/server/scene/trust_session_impl.h' |
3419 | --- src/server/scene/trust_session_impl.h 1970-01-01 00:00:00 +0000 |
3420 | +++ src/server/scene/trust_session_impl.h 2014-05-09 12:26:43 +0000 |
3421 | @@ -0,0 +1,74 @@ |
3422 | +/* |
3423 | + * Copyright © 2014 Canonical Ltd. |
3424 | + * |
3425 | + * This program is free software: you can redistribute it and/or modify it |
3426 | + * under the terms of the GNU General Public License version 3, |
3427 | + * as published by the Free Software Foundation. |
3428 | + * |
3429 | + * This program is distributed in the hope that it will be useful, |
3430 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3431 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3432 | + * GNU General Public License for more details. |
3433 | + * |
3434 | + * You should have received a copy of the GNU General Public License |
3435 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3436 | + * |
3437 | + * Authored By: Nick Dedekind <nick.dedekind@canonical.com> |
3438 | + */ |
3439 | + |
3440 | +#ifndef MIR_SCENE_TRUST_SESSION_IMPL_H_ |
3441 | +#define MIR_SCENE_TRUST_SESSION_IMPL_H_ |
3442 | + |
3443 | +#include "mir/scene/trust_session.h" |
3444 | + |
3445 | +#include <vector> |
3446 | +#include <atomic> |
3447 | +#include <mutex> |
3448 | + |
3449 | +namespace mir |
3450 | +{ |
3451 | + |
3452 | +namespace scene |
3453 | +{ |
3454 | +class SessionContainer; |
3455 | +class TrustSessionCreationParameters; |
3456 | +class TrustSessionListener; |
3457 | + |
3458 | +class TrustSessionImpl : public TrustSession |
3459 | +{ |
3460 | +public: |
3461 | + TrustSessionImpl(std::weak_ptr<Session> const& session, |
3462 | + TrustSessionCreationParameters const& parameters, |
3463 | + std::shared_ptr<TrustSessionListener> const& trust_session_listener); |
3464 | + ~TrustSessionImpl(); |
3465 | + |
3466 | + MirTrustSessionState get_state() const override; |
3467 | + std::weak_ptr<Session> get_trusted_helper() const override; |
3468 | + |
3469 | + void start() override; |
3470 | + void stop() override; |
3471 | + |
3472 | + bool add_trusted_child(std::shared_ptr<Session> const& session); |
3473 | + void remove_trusted_child(std::shared_ptr<Session> const& session); |
3474 | + void for_each_trusted_child(std::function<void(std::shared_ptr<Session> const&)> f, bool reverse) const; |
3475 | + |
3476 | +protected: |
3477 | + TrustSessionImpl(const TrustSessionImpl&) = delete; |
3478 | + TrustSessionImpl& operator=(const TrustSessionImpl&) = delete; |
3479 | + |
3480 | +private: |
3481 | + std::weak_ptr<Session> const trusted_helper; |
3482 | + std::shared_ptr<TrustSessionListener> const trust_session_listener; |
3483 | + MirTrustSessionState state; |
3484 | + std::string cookie; |
3485 | + std::mutex mutable mutex; |
3486 | + |
3487 | + std::mutex mutable mutex_children; |
3488 | + std::vector<pid_t> client_processes; |
3489 | + std::vector<std::weak_ptr<Session>> trusted_children; |
3490 | +}; |
3491 | + |
3492 | +} |
3493 | +} |
3494 | + |
3495 | +#endif // MIR_SCENE_TRUST_SESSION_H_ |
3496 | |
3497 | === modified file 'src/shared/protobuf/mir_protobuf.proto' |
3498 | --- src/shared/protobuf/mir_protobuf.proto 2014-05-06 16:54:43 +0000 |
3499 | +++ src/shared/protobuf/mir_protobuf.proto 2014-05-09 12:26:43 +0000 |
3500 | @@ -100,7 +100,7 @@ |
3501 | optional int32 pixel_format = 4; |
3502 | optional int32 buffer_usage = 5; |
3503 | optional Buffer buffer = 6; |
3504 | - |
3505 | + |
3506 | repeated sint32 fd = 7; |
3507 | optional int32 fds_on_side_channel = 8; |
3508 | |
3509 | @@ -175,18 +175,50 @@ |
3510 | optional string error = 127; |
3511 | } |
3512 | |
3513 | -message SocketFDRequest { |
3514 | - required int32 number = 1; |
3515 | -} |
3516 | - |
3517 | - |
3518 | -message SocketFD { |
3519 | - repeated sint32 fd = 1; |
3520 | - optional int32 fds_on_side_channel = 2; |
3521 | - |
3522 | - optional string error = 127; |
3523 | -} |
3524 | - |
3525 | +<<<<<<< TREE |
3526 | +message SocketFDRequest { |
3527 | + required int32 number = 1; |
3528 | +} |
3529 | + |
3530 | + |
3531 | +message SocketFD { |
3532 | + repeated sint32 fd = 1; |
3533 | + optional int32 fds_on_side_channel = 2; |
3534 | + |
3535 | + optional string error = 127; |
3536 | +} |
3537 | + |
3538 | +======= |
3539 | +message SocketFDRequest { |
3540 | + required int32 number = 1; |
3541 | +} |
3542 | + |
3543 | +message SocketFD { |
3544 | + repeated sint32 fd = 1; |
3545 | + optional int32 fds_on_side_channel = 2; |
3546 | + |
3547 | + optional string error = 127; |
3548 | +} |
3549 | + |
3550 | +message TrustedSession { |
3551 | + required int32 pid = 1; |
3552 | +} |
3553 | + |
3554 | +message TrustSessionParameters { |
3555 | + required TrustedSession base_trusted_session = 1; |
3556 | +} |
3557 | + |
3558 | +message TrustSession { |
3559 | + optional uint32 state = 1; |
3560 | + optional string error = 127; |
3561 | +} |
3562 | + |
3563 | +message TrustSessionAddResult { |
3564 | + required int32 result = 1; |
3565 | + optional string error = 127; |
3566 | +} |
3567 | + |
3568 | +>>>>>>> MERGE-SOURCE |
3569 | service DisplayServer { |
3570 | // Platform independent requests |
3571 | rpc connect(ConnectParameters) returns (Connection); |
3572 | @@ -206,5 +238,13 @@ |
3573 | rpc create_screencast(ScreencastParameters) returns (Screencast); |
3574 | rpc screencast_buffer(ScreencastId) returns (Buffer); |
3575 | rpc release_screencast(ScreencastId) returns (Void); |
3576 | - rpc new_fds_for_trusted_clients(SocketFDRequest) returns (SocketFD); |
3577 | +<<<<<<< TREE |
3578 | + rpc new_fds_for_trusted_clients(SocketFDRequest) returns (SocketFD); |
3579 | +======= |
3580 | + rpc new_fds_for_trusted_clients(SocketFDRequest) returns (SocketFD); |
3581 | + |
3582 | + rpc start_trust_session(TrustSessionParameters) returns (TrustSession); |
3583 | + rpc add_trusted_session(TrustedSession) returns (TrustSessionAddResult); |
3584 | + rpc stop_trust_session(Void) returns (Void); |
3585 | +>>>>>>> MERGE-SOURCE |
3586 | } |
3587 | |
3588 | === modified file 'tests/acceptance-tests/CMakeLists.txt' |
3589 | --- tests/acceptance-tests/CMakeLists.txt 2014-05-07 14:00:57 +0000 |
3590 | +++ tests/acceptance-tests/CMakeLists.txt 2014-05-09 12:26:43 +0000 |
3591 | @@ -28,6 +28,7 @@ |
3592 | test_surfaces_with_output_id.cpp |
3593 | test_server_disconnect.cpp |
3594 | test_client_library_drm.cpp |
3595 | + test_client_trust_session_api.cpp |
3596 | test_protobuf.cpp |
3597 | test_client_screencast.cpp |
3598 | test_client_surface_swap_buffers.cpp |
3599 | |
3600 | === added file 'tests/acceptance-tests/test_client_trust_session_api.cpp' |
3601 | --- tests/acceptance-tests/test_client_trust_session_api.cpp 1970-01-01 00:00:00 +0000 |
3602 | +++ tests/acceptance-tests/test_client_trust_session_api.cpp 2014-05-09 12:26:43 +0000 |
3603 | @@ -0,0 +1,106 @@ |
3604 | +/* |
3605 | + * Copyright © 2013 Canonical Ltd. |
3606 | + * |
3607 | + * This program is free software: you can redistribute it and/or modify |
3608 | + * it under the terms of the GNU General Public License version 3 as |
3609 | + * published by the Free Software Foundation. |
3610 | + * |
3611 | + * This program is distributed in the hope that it will be useful, |
3612 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3613 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3614 | + * GNU General Public License for more details. |
3615 | + * |
3616 | + * You should have received a copy of the GNU General Public License |
3617 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3618 | + * |
3619 | + * Authored by: Nick Dedekind <nick.dedekind@canonical.com> |
3620 | + */ |
3621 | + |
3622 | +#include "mir_test_framework/display_server_test_fixture.h" |
3623 | + |
3624 | +#include "mir_toolkit/mir_client_library.h" |
3625 | +#include "mir_toolkit/mir_trust_session.h" |
3626 | + |
3627 | +#include <gtest/gtest.h> |
3628 | + |
3629 | +namespace mtf = mir_test_framework; |
3630 | + |
3631 | +namespace |
3632 | +{ |
3633 | + char const* const mir_test_socket = mtf::test_socket_file().c_str(); |
3634 | +} |
3635 | + |
3636 | +using MirClientTrustSessionAPITest = DefaultDisplayServerTestFixture; |
3637 | + |
3638 | +namespace mir |
3639 | +{ |
3640 | +namespace |
3641 | +{ |
3642 | +struct ClientConfigCommon : TestingClientConfiguration |
3643 | +{ |
3644 | + ClientConfigCommon() |
3645 | + : connection(0) |
3646 | + , trust_session(0) |
3647 | + , started(0) |
3648 | + , stopped(0) |
3649 | + { |
3650 | + } |
3651 | + |
3652 | + static void connection_callback(MirConnection * connection, void * context) |
3653 | + { |
3654 | + ClientConfigCommon * config = reinterpret_cast<ClientConfigCommon *>(context); |
3655 | + config->connection = connection; |
3656 | + } |
3657 | + |
3658 | + virtual void connected(MirConnection * new_connection) |
3659 | + { |
3660 | + connection = new_connection; |
3661 | + } |
3662 | + |
3663 | + static void trust_session_start_callback(MirTrustSession * session, void * context) |
3664 | + { |
3665 | + ClientConfigCommon * config = reinterpret_cast<ClientConfigCommon *>(context); |
3666 | + config->trust_session = session; |
3667 | + config->started++; |
3668 | + } |
3669 | + |
3670 | + static void trust_session_stop_callback(MirTrustSession * /* session */, void * context) |
3671 | + { |
3672 | + ClientConfigCommon * config = reinterpret_cast<ClientConfigCommon *>(context); |
3673 | + config->stopped++; |
3674 | + } |
3675 | + |
3676 | + MirConnection* connection; |
3677 | + MirTrustSession* trust_session; |
3678 | + int started; |
3679 | + int stopped; |
3680 | +}; |
3681 | +} |
3682 | + |
3683 | +TEST_F(MirClientTrustSessionAPITest, client_trust_session_api) |
3684 | +{ |
3685 | + struct ClientConfig : ClientConfigCommon |
3686 | + { |
3687 | + void exec() |
3688 | + { |
3689 | + mir_wait_for(mir_connect(mir_test_socket, __PRETTY_FUNCTION__, connection_callback, this)); |
3690 | + |
3691 | + ASSERT_TRUE(connection != NULL); |
3692 | + EXPECT_TRUE(mir_connection_is_valid(connection)); |
3693 | + EXPECT_STREQ("", mir_connection_get_error_message(connection)); |
3694 | + |
3695 | + mir_wait_for(mir_connection_start_trust_session(connection, __LINE__, trust_session_start_callback, NULL, this)); |
3696 | + ASSERT_TRUE(trust_session != NULL); |
3697 | + EXPECT_EQ(started, 1); |
3698 | + |
3699 | + mir_wait_for(mir_trust_session_stop(trust_session, trust_session_stop_callback, this)); |
3700 | + EXPECT_EQ(stopped, 1); |
3701 | + |
3702 | + mir_connection_release(connection); |
3703 | + } |
3704 | + } client_config; |
3705 | + |
3706 | + launch_client_process(client_config); |
3707 | +} |
3708 | + |
3709 | +} |
3710 | |
3711 | === modified file 'tests/acceptance-tests/test_nested_mir.cpp' |
3712 | --- tests/acceptance-tests/test_nested_mir.cpp 2014-03-06 06:05:17 +0000 |
3713 | +++ tests/acceptance-tests/test_nested_mir.cpp 2014-05-09 12:26:43 +0000 |
3714 | @@ -56,6 +56,9 @@ |
3715 | MOCK_METHOD1(session_next_buffer_called, void (std::string const&)); |
3716 | MOCK_METHOD1(session_release_surface_called, void (std::string const&)); |
3717 | MOCK_METHOD1(session_disconnect_called, void (std::string const&)); |
3718 | + MOCK_METHOD2(session_start_trust_session_called, void (std::string const&, std::string const&)); |
3719 | + MOCK_METHOD2(session_add_trusted_session_called, void (std::string const&, std::string const&)); |
3720 | + MOCK_METHOD1(session_stop_trust_session_called, void (std::string const&)); |
3721 | |
3722 | void session_drm_auth_magic_called(const std::string&) override {}; |
3723 | void session_configure_surface_called(std::string const&) override {}; |
3724 | |
3725 | === modified file 'tests/acceptance-tests/test_server_shutdown.cpp' |
3726 | --- tests/acceptance-tests/test_server_shutdown.cpp 2014-05-09 03:00:20 +0000 |
3727 | +++ tests/acceptance-tests/test_server_shutdown.cpp 2014-05-09 12:26:43 +0000 |
3728 | @@ -117,6 +117,7 @@ |
3729 | std::string const flag_file; |
3730 | }; |
3731 | |
3732 | +<<<<<<< TREE |
3733 | struct FakeEventHubServerConfig : TestingServerConfiguration |
3734 | { |
3735 | std::shared_ptr<mi::InputConfiguration> the_input_configuration() override |
3736 | @@ -157,6 +158,48 @@ |
3737 | std::shared_ptr<mtd::FakeEventHubInputConfiguration> input_configuration; |
3738 | }; |
3739 | |
3740 | +======= |
3741 | +struct FakeEventHubServerConfig : TestingServerConfiguration |
3742 | +{ |
3743 | + std::shared_ptr<mi::InputConfiguration> the_input_configuration() override |
3744 | + { |
3745 | + if (!input_configuration) |
3746 | + { |
3747 | + input_configuration = |
3748 | + std::make_shared<mtd::FakeEventHubInputConfiguration>( |
3749 | + the_composite_event_filter(), |
3750 | + the_input_region(), |
3751 | + std::shared_ptr<mi::CursorListener>(), |
3752 | + the_input_report()); |
3753 | + } |
3754 | + |
3755 | + return input_configuration; |
3756 | + } |
3757 | + |
3758 | + std::shared_ptr<mi::InputManager> the_input_manager() override |
3759 | + { |
3760 | + return DefaultServerConfiguration::the_input_manager(); |
3761 | + } |
3762 | + |
3763 | + std::shared_ptr<mir::shell::InputTargeter> the_input_targeter() override |
3764 | + { |
3765 | + return DefaultServerConfiguration::the_input_targeter(); |
3766 | + } |
3767 | + std::shared_ptr<mir::scene::InputRegistrar> the_input_registrar() override |
3768 | + { |
3769 | + return DefaultServerConfiguration::the_input_registrar(); |
3770 | + } |
3771 | + |
3772 | + mia::FakeEventHub* the_fake_event_hub() |
3773 | + { |
3774 | + the_input_configuration(); |
3775 | + return input_configuration->the_fake_event_hub(); |
3776 | + } |
3777 | + |
3778 | + std::shared_ptr<mtd::FakeEventHubInputConfiguration> input_configuration; |
3779 | +}; |
3780 | + |
3781 | +>>>>>>> MERGE-SOURCE |
3782 | } |
3783 | |
3784 | using ServerShutdown = BespokeDisplayServerTestFixture; |
3785 | |
3786 | === modified file 'tests/integration-tests/frontend/test_application_mediator_report.cpp' |
3787 | --- tests/integration-tests/frontend/test_application_mediator_report.cpp 2014-03-06 06:05:17 +0000 |
3788 | +++ tests/integration-tests/frontend/test_application_mediator_report.cpp 2014-05-09 12:26:43 +0000 |
3789 | @@ -50,6 +50,12 @@ |
3790 | |
3791 | EXPECT_CALL(*this, session_disconnect_called(testing::_)). |
3792 | Times(testing::AtLeast(0)); |
3793 | + |
3794 | + EXPECT_CALL(*this, session_start_trust_session_called(testing::_, testing::_)). |
3795 | + Times(testing::AtLeast(0)); |
3796 | + |
3797 | + EXPECT_CALL(*this, session_stop_trust_session_called(testing::_)). |
3798 | + Times(testing::AtLeast(0)); |
3799 | } |
3800 | |
3801 | MOCK_METHOD1(session_connect_called, void (std::string const&)); |
3802 | @@ -57,6 +63,9 @@ |
3803 | MOCK_METHOD1(session_next_buffer_called, void (std::string const&)); |
3804 | MOCK_METHOD1(session_release_surface_called, void (std::string const&)); |
3805 | MOCK_METHOD1(session_disconnect_called, void (std::string const&)); |
3806 | + MOCK_METHOD2(session_start_trust_session_called, void (std::string const&, std::string const&)); |
3807 | + MOCK_METHOD2(session_add_trusted_session_called, void (std::string const&, std::string const&)); |
3808 | + MOCK_METHOD1(session_stop_trust_session_called, void (std::string const&)); |
3809 | |
3810 | void session_drm_auth_magic_called(const std::string&) override {}; |
3811 | void session_configure_surface_called(std::string const&) override {}; |
3812 | @@ -358,3 +367,175 @@ |
3813 | |
3814 | launch_client_process(client_process); |
3815 | } |
3816 | + |
3817 | +TEST_F(ApplicationMediatorReport, trust_session_start_called) |
3818 | +{ |
3819 | + struct Server : TestingServerConfiguration |
3820 | + { |
3821 | + std::shared_ptr<mf::SessionMediatorReport> |
3822 | + the_application_mediator_report() |
3823 | + { |
3824 | + auto result = std::make_shared<MockApplicationMediatorReport>(); |
3825 | + |
3826 | + EXPECT_CALL(*result, session_start_trust_session_called(testing::_, testing::_)). |
3827 | + Times(1); |
3828 | + |
3829 | + return result; |
3830 | + } |
3831 | + } server_processing; |
3832 | + |
3833 | + launch_server_process(server_processing); |
3834 | + |
3835 | + struct Client: TestingClientConfiguration |
3836 | + { |
3837 | + void exec() |
3838 | + { |
3839 | + mt::TestProtobufClient client(mtf::test_socket_file(), rpc_timeout_ms); |
3840 | + |
3841 | + client.connect_parameters.set_application_name(__PRETTY_FUNCTION__); |
3842 | + EXPECT_CALL(client, connect_done()). |
3843 | + Times(testing::AtLeast(0)); |
3844 | + EXPECT_CALL(client, trust_session_start_done()). |
3845 | + Times(testing::AtLeast(0)); |
3846 | + |
3847 | + client.display_server.connect( |
3848 | + 0, |
3849 | + &client.connect_parameters, |
3850 | + &client.connection, |
3851 | + google::protobuf::NewCallback(&client, &mt::TestProtobufClient::connect_done)); |
3852 | + |
3853 | + client.wait_for_connect_done(); |
3854 | + |
3855 | + client.display_server.start_trust_session( |
3856 | + 0, |
3857 | + &client.trust_session_parameters, |
3858 | + &client.trust_session, |
3859 | + google::protobuf::NewCallback(&client, &mt::TestProtobufClient::trust_session_start_done)); |
3860 | + client.wait_for_trust_session_start_done(); |
3861 | + |
3862 | + } |
3863 | + } client_process; |
3864 | + |
3865 | + launch_client_process(client_process); |
3866 | +} |
3867 | + |
3868 | +TEST_F(ApplicationMediatorReport, trust_session_add_trusted_session_called) |
3869 | +{ |
3870 | + struct Server : TestingServerConfiguration |
3871 | + { |
3872 | + std::shared_ptr<mf::SessionMediatorReport> |
3873 | + the_application_mediator_report() |
3874 | + { |
3875 | + auto result = std::make_shared<MockApplicationMediatorReport>(); |
3876 | + |
3877 | + EXPECT_CALL(*result, session_start_trust_session_called(testing::_, testing::_)). |
3878 | + Times(1); |
3879 | + |
3880 | + return result; |
3881 | + } |
3882 | + } server_processing; |
3883 | + |
3884 | + launch_server_process(server_processing); |
3885 | + |
3886 | + struct Client: TestingClientConfiguration |
3887 | + { |
3888 | + void exec() |
3889 | + { |
3890 | + mt::TestProtobufClient client(mtf::test_socket_file(), rpc_timeout_ms); |
3891 | + |
3892 | + client.connect_parameters.set_application_name(__PRETTY_FUNCTION__); |
3893 | + EXPECT_CALL(client, connect_done()). |
3894 | + Times(testing::AtLeast(0)); |
3895 | + EXPECT_CALL(client, trust_session_start_done()). |
3896 | + Times(testing::AtLeast(0)); |
3897 | + EXPECT_CALL(client, trust_session_add_trusted_session_done()). |
3898 | + Times(testing::AtLeast(0)); |
3899 | + |
3900 | + client.display_server.connect( |
3901 | + 0, |
3902 | + &client.connect_parameters, |
3903 | + &client.connection, |
3904 | + google::protobuf::NewCallback(&client, &mt::TestProtobufClient::connect_done)); |
3905 | + |
3906 | + client.wait_for_connect_done(); |
3907 | + |
3908 | + client.display_server.start_trust_session( |
3909 | + 0, |
3910 | + &client.trust_session_parameters, |
3911 | + &client.trust_session, |
3912 | + google::protobuf::NewCallback(&client, &mt::TestProtobufClient::trust_session_start_done)); |
3913 | + client.wait_for_trust_session_start_done(); |
3914 | + |
3915 | + client.display_server.add_trusted_session( |
3916 | + 0, |
3917 | + &client.trusted_session, |
3918 | + &client.add_trust_result, |
3919 | + google::protobuf::NewCallback(&client, &mt::TestProtobufClient::trust_session_add_trusted_session_done)); |
3920 | + client.wait_for_trust_session_add_trusted_session_done(); |
3921 | + |
3922 | + } |
3923 | + } client_process; |
3924 | + |
3925 | + launch_client_process(client_process); |
3926 | +} |
3927 | + |
3928 | +TEST_F(ApplicationMediatorReport, trust_session_stop_called) |
3929 | +{ |
3930 | + struct Server : TestingServerConfiguration |
3931 | + { |
3932 | + std::shared_ptr<mf::SessionMediatorReport> |
3933 | + the_application_mediator_report() |
3934 | + { |
3935 | + auto result = std::make_shared<MockApplicationMediatorReport>(); |
3936 | + |
3937 | + EXPECT_CALL(*result, session_stop_trust_session_called(testing::_)). |
3938 | + Times(1); |
3939 | + |
3940 | + return result; |
3941 | + } |
3942 | + } server_processing; |
3943 | + |
3944 | + launch_server_process(server_processing); |
3945 | + |
3946 | + struct Client: TestingClientConfiguration |
3947 | + { |
3948 | + void exec() |
3949 | + { |
3950 | + mt::TestProtobufClient client(mtf::test_socket_file(), rpc_timeout_ms); |
3951 | + |
3952 | + client.connect_parameters.set_application_name(__PRETTY_FUNCTION__); |
3953 | + EXPECT_CALL(client, connect_done()). |
3954 | + Times(testing::AtLeast(0)); |
3955 | + EXPECT_CALL(client, trust_session_start_done()). |
3956 | + Times(testing::AtLeast(0)); |
3957 | + EXPECT_CALL(client, trust_session_stop_done()). |
3958 | + Times(testing::AtLeast(0)); |
3959 | + |
3960 | + client.display_server.connect( |
3961 | + 0, |
3962 | + &client.connect_parameters, |
3963 | + &client.connection, |
3964 | + google::protobuf::NewCallback(&client, &mt::TestProtobufClient::connect_done)); |
3965 | + |
3966 | + client.wait_for_connect_done(); |
3967 | + |
3968 | + client.display_server.start_trust_session( |
3969 | + 0, |
3970 | + &client.trust_session_parameters, |
3971 | + &client.trust_session, |
3972 | + google::protobuf::NewCallback(&client, &mt::TestProtobufClient::trust_session_start_done)); |
3973 | + client.wait_for_trust_session_start_done(); |
3974 | + |
3975 | + client.display_server.stop_trust_session( |
3976 | + 0, |
3977 | + &client.ignored, |
3978 | + &client.ignored, |
3979 | + google::protobuf::NewCallback(&client, &mt::TestProtobufClient::trust_session_stop_done)); |
3980 | + client.wait_for_trust_session_stop_done(); |
3981 | + } |
3982 | + } client_process; |
3983 | + |
3984 | + launch_client_process(client_process); |
3985 | +} |
3986 | + |
3987 | + |
3988 | |
3989 | === modified file 'tests/integration-tests/test_display_server_main_loop_events.cpp' |
3990 | === modified file 'tests/integration-tests/test_session_manager.cpp' |
3991 | --- tests/integration-tests/test_session_manager.cpp 2014-04-15 05:31:19 +0000 |
3992 | +++ tests/integration-tests/test_session_manager.cpp 2014-05-09 12:26:43 +0000 |
3993 | @@ -24,6 +24,7 @@ |
3994 | #include "mir/compositor/buffer_stream.h" |
3995 | #include "src/server/scene/basic_surface.h" |
3996 | #include "mir/scene/surface_creation_parameters.h" |
3997 | +#include "mir/scene/null_trust_session_listener.h" |
3998 | |
3999 | #include "mir_test/gmock_fixes.h" |
4000 | #include "mir_test/fake_shared.h" |
4001 | @@ -55,7 +56,8 @@ |
4002 | mt::fake_shared(focus_setter), |
4003 | std::make_shared<mtd::NullSnapshotStrategy>(), |
4004 | std::make_shared<mtd::NullSessionEventSink>(), |
4005 | - mt::fake_shared(session_listener)) |
4006 | + mt::fake_shared(session_listener), |
4007 | + std::make_shared<ms::NullTrustSessionListener>()) |
4008 | { |
4009 | |
4010 | } |
4011 | |
4012 | === modified file 'tests/mir_test_doubles/test_protobuf_client.cpp' |
4013 | --- tests/mir_test_doubles/test_protobuf_client.cpp 2014-03-06 06:05:17 +0000 |
4014 | +++ tests/mir_test_doubles/test_protobuf_client.cpp 2014-05-09 12:26:43 +0000 |
4015 | @@ -22,6 +22,7 @@ |
4016 | #include "src/client/connection_surface_map.h" |
4017 | #include "src/client/display_configuration.h" |
4018 | #include "src/client/lifecycle_control.h" |
4019 | +#include "src/client/event_distributor.h" |
4020 | #include "src/client/rpc/make_rpc_channel.h" |
4021 | #include "src/client/rpc/mir_basic_rpc_channel.h" |
4022 | |
4023 | @@ -38,7 +39,8 @@ |
4024 | std::make_shared<mir::client::ConnectionSurfaceMap>(), |
4025 | std::make_shared<mir::client::DisplayConfiguration>(), |
4026 | rpc_report, |
4027 | - std::make_shared<mir::client::LifecycleControl>())), |
4028 | + std::make_shared<mir::client::LifecycleControl>(), |
4029 | + std::make_shared<mir::client::EventDistributor>())), |
4030 | display_server(channel.get(), ::google::protobuf::Service::STUB_DOESNT_OWN_CHANNEL), |
4031 | maxwait(timeout_ms), |
4032 | connect_done_called(false), |
4033 | @@ -59,6 +61,9 @@ |
4034 | surface_parameters.set_buffer_usage(0); |
4035 | surface_parameters.set_output_id(mir_display_output_id_invalid); |
4036 | |
4037 | + trusted_session.set_pid(__LINE__); |
4038 | + trust_session_parameters.mutable_base_trusted_session()->set_pid(__LINE__); |
4039 | + |
4040 | ON_CALL(*this, connect_done()) |
4041 | .WillByDefault(testing::Invoke(this, &TestProtobufClient::on_connect_done)); |
4042 | ON_CALL(*this, create_surface_done()) |
4043 | @@ -73,6 +78,12 @@ |
4044 | .WillByDefault(testing::Invoke(this, &TestProtobufClient::on_drm_auth_magic_done)); |
4045 | ON_CALL(*this, display_configure_done()) |
4046 | .WillByDefault(testing::Invoke(this, &TestProtobufClient::on_configure_display_done)); |
4047 | + ON_CALL(*this, trust_session_start_done()) |
4048 | + .WillByDefault(testing::Invoke(&wc_trust_session_start, &WaitCondition::wake_up_everyone)); |
4049 | + ON_CALL(*this, trust_session_add_trusted_session_done()) |
4050 | + .WillByDefault(testing::Invoke(&wc_trust_session_add, &WaitCondition::wake_up_everyone)); |
4051 | + ON_CALL(*this, trust_session_stop_done()) |
4052 | + .WillByDefault(testing::Invoke(&wc_trust_session_stop, &WaitCondition::wake_up_everyone)); |
4053 | } |
4054 | |
4055 | void mir::test::TestProtobufClient::on_connect_done() |
4056 | @@ -225,3 +236,18 @@ |
4057 | } |
4058 | tfd_done_called.store(false); |
4059 | } |
4060 | + |
4061 | +void mir::test::TestProtobufClient::wait_for_trust_session_start_done() |
4062 | +{ |
4063 | + wc_trust_session_start.wait_for_at_most_seconds(maxwait); |
4064 | +} |
4065 | + |
4066 | +void mir::test::TestProtobufClient::wait_for_trust_session_add_trusted_session_done() |
4067 | +{ |
4068 | + wc_trust_session_add.wait_for_at_most_seconds(maxwait); |
4069 | +} |
4070 | + |
4071 | +void mir::test::TestProtobufClient::wait_for_trust_session_stop_done() |
4072 | +{ |
4073 | + wc_trust_session_stop.wait_for_at_most_seconds(maxwait); |
4074 | +} |
4075 | |
4076 | === modified file 'tests/unit-tests/client/CMakeLists.txt' |
4077 | --- tests/unit-tests/client/CMakeLists.txt 2014-03-06 06:05:17 +0000 |
4078 | +++ tests/unit-tests/client/CMakeLists.txt 2014-05-09 12:26:43 +0000 |
4079 | @@ -8,6 +8,7 @@ |
4080 | ${CMAKE_CURRENT_SOURCE_DIR}/test_wait_handle.cpp |
4081 | ${CMAKE_CURRENT_SOURCE_DIR}/test_client_display_conf.cpp |
4082 | ${CMAKE_CURRENT_SOURCE_DIR}/test_mir_screencast.cpp |
4083 | + ${CMAKE_CURRENT_SOURCE_DIR}/test_mir_trust_session.cpp |
4084 | ) |
4085 | |
4086 | if(MIR_TEST_PLATFORM STREQUAL "android") |
4087 | |
4088 | === added file 'tests/unit-tests/client/test_mir_trust_session.cpp' |
4089 | --- tests/unit-tests/client/test_mir_trust_session.cpp 1970-01-01 00:00:00 +0000 |
4090 | +++ tests/unit-tests/client/test_mir_trust_session.cpp 2014-05-09 12:26:43 +0000 |
4091 | @@ -0,0 +1,244 @@ |
4092 | +/* |
4093 | + * Copyright © 2014 Canonical Ltd. |
4094 | + * |
4095 | + * This program is free software: you can redistribute it and/or modify it |
4096 | + * under the terms of the GNU General Public License version 3, |
4097 | + * as published by the Free Software Foundation. |
4098 | + * |
4099 | + * This program is distributed in the hope that it will be useful, |
4100 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4101 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4102 | + * GNU General Public License for more details. |
4103 | + * |
4104 | + * You should have received a copy of the GNU General Public License |
4105 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
4106 | + * |
4107 | + * Authored by: Nick Dedekind <nick.dedekind <nick.dedekind@canonical.com> |
4108 | + */ |
4109 | + |
4110 | +#include "src/client/mir_trust_session.h" |
4111 | +#include "src/client/event_distributor.h" |
4112 | + |
4113 | +#include <gtest/gtest.h> |
4114 | +#include <gmock/gmock.h> |
4115 | + |
4116 | +#include <thread> |
4117 | + |
4118 | +namespace mcl = mir::client; |
4119 | + |
4120 | +namespace google |
4121 | +{ |
4122 | +namespace protobuf |
4123 | +{ |
4124 | +class RpcController; |
4125 | +} |
4126 | +} |
4127 | + |
4128 | +namespace |
4129 | +{ |
4130 | + |
4131 | +struct MockProtobufServer : mir::protobuf::DisplayServer |
4132 | +{ |
4133 | + |
4134 | + MOCK_METHOD4(start_trust_session, |
4135 | + void(::google::protobuf::RpcController* /*controller*/, |
4136 | + ::mir::protobuf::TrustSessionParameters const* /*request*/, |
4137 | + ::mir::protobuf::TrustSession* /*response*/, |
4138 | + ::google::protobuf::Closure* /*done*/)); |
4139 | + |
4140 | + MOCK_METHOD4(add_trusted_session, |
4141 | + void(::google::protobuf::RpcController* /*controller*/, |
4142 | + const ::mir::protobuf::TrustedSession* /*request*/, |
4143 | + ::mir::protobuf::TrustSessionAddResult* /*response*/, |
4144 | + ::google::protobuf::Closure* /*done*/)); |
4145 | + |
4146 | + MOCK_METHOD4(stop_trust_session, |
4147 | + void(::google::protobuf::RpcController* /*controller*/, |
4148 | + ::mir::protobuf::Void const* /*request*/, |
4149 | + ::mir::protobuf::Void* /*response*/, |
4150 | + ::google::protobuf::Closure* /*done*/)); |
4151 | +}; |
4152 | + |
4153 | +class StubProtobufServer : public mir::protobuf::DisplayServer |
4154 | +{ |
4155 | +public: |
4156 | + void start_trust_session(::google::protobuf::RpcController* /*controller*/, |
4157 | + ::mir::protobuf::TrustSessionParameters const* /*request*/, |
4158 | + ::mir::protobuf::TrustSession* response, |
4159 | + ::google::protobuf::Closure* done) override |
4160 | + { |
4161 | + if (server_thread.joinable()) |
4162 | + server_thread.join(); |
4163 | + server_thread = std::thread{ |
4164 | + [response, done, this] |
4165 | + { |
4166 | + response->clear_error(); |
4167 | + done->Run(); |
4168 | + }}; |
4169 | + } |
4170 | + |
4171 | + void add_trusted_session(::google::protobuf::RpcController* /*controller*/, |
4172 | + const ::mir::protobuf::TrustedSession* /*request*/, |
4173 | + ::mir::protobuf::TrustSessionAddResult* /*response*/, |
4174 | + ::google::protobuf::Closure* done) |
4175 | + { |
4176 | + if (server_thread.joinable()) |
4177 | + server_thread.join(); |
4178 | + server_thread = std::thread{[done, this] { done->Run(); }}; |
4179 | + } |
4180 | + |
4181 | + void stop_trust_session(::google::protobuf::RpcController* /*controller*/, |
4182 | + mir::protobuf::Void const* /*request*/, |
4183 | + ::mir::protobuf::Void* /*response*/, |
4184 | + ::google::protobuf::Closure* done) override |
4185 | + { |
4186 | + if (server_thread.joinable()) |
4187 | + server_thread.join(); |
4188 | + server_thread = std::thread{[done, this] { done->Run(); }}; |
4189 | + } |
4190 | + |
4191 | + StubProtobufServer() |
4192 | + { |
4193 | + } |
4194 | + |
4195 | + ~StubProtobufServer() |
4196 | + { |
4197 | + if (server_thread.joinable()) |
4198 | + server_thread.join(); |
4199 | + } |
4200 | + |
4201 | +private: |
4202 | + std::thread server_thread; |
4203 | +}; |
4204 | + |
4205 | +class MirTrustSessionTest : public testing::Test |
4206 | +{ |
4207 | +public: |
4208 | + MirTrustSessionTest() |
4209 | + : event_distributor{std::make_shared<mcl::EventDistributor>()} |
4210 | + { |
4211 | + } |
4212 | + |
4213 | + static void trust_session_event(MirTrustSession*, MirTrustSessionState new_state, void* context) |
4214 | + { |
4215 | + MirTrustSessionTest* test = static_cast<MirTrustSessionTest*>(context); |
4216 | + test->state_updated(new_state); |
4217 | + } |
4218 | + |
4219 | + MOCK_METHOD1(state_updated, void(MirTrustSessionState)); |
4220 | + |
4221 | + testing::NiceMock<MockProtobufServer> mock_server; |
4222 | + StubProtobufServer stub_server; |
4223 | + std::shared_ptr<mcl::EventDistributor> event_distributor; |
4224 | +}; |
4225 | + |
4226 | +struct MockCallback |
4227 | +{ |
4228 | + MOCK_METHOD2(call, void(void*, void*)); |
4229 | +}; |
4230 | + |
4231 | +void mock_callback_func(MirTrustSession* trust_session, void* context) |
4232 | +{ |
4233 | + auto mock_cb = static_cast<MockCallback*>(context); |
4234 | + mock_cb->call(trust_session, context); |
4235 | +} |
4236 | + |
4237 | +void null_callback_func(MirTrustSession*, void*) |
4238 | +{ |
4239 | +} |
4240 | + |
4241 | +ACTION(RunClosure) |
4242 | +{ |
4243 | + arg3->Run(); |
4244 | +} |
4245 | + |
4246 | +} |
4247 | + |
4248 | +TEST_F(MirTrustSessionTest, start_trust_session) |
4249 | +{ |
4250 | + using namespace testing; |
4251 | + |
4252 | + EXPECT_CALL(mock_server, |
4253 | + start_trust_session(_,_,_,_)) |
4254 | + .WillOnce(RunClosure()); |
4255 | + |
4256 | + MirTrustSession trust_session{ |
4257 | + mock_server, |
4258 | + event_distributor}; |
4259 | + trust_session.start(__LINE__, null_callback_func, nullptr); |
4260 | +} |
4261 | + |
4262 | +TEST_F(MirTrustSessionTest, stop_trust_session) |
4263 | +{ |
4264 | + using namespace testing; |
4265 | + |
4266 | + EXPECT_CALL(mock_server, |
4267 | + stop_trust_session(_,_,_,_)) |
4268 | + .WillOnce(RunClosure()); |
4269 | + |
4270 | + MirTrustSession trust_session{ |
4271 | + mock_server, |
4272 | + event_distributor}; |
4273 | + trust_session.stop(null_callback_func, nullptr); |
4274 | +} |
4275 | + |
4276 | +TEST_F(MirTrustSessionTest, executes_callback_on_start) |
4277 | +{ |
4278 | + using namespace testing; |
4279 | + |
4280 | + MockCallback mock_cb; |
4281 | + EXPECT_CALL(mock_cb, call(_, &mock_cb)); |
4282 | + |
4283 | + MirTrustSession trust_session{ |
4284 | + stub_server, |
4285 | + event_distributor}; |
4286 | + trust_session.start(__LINE__, mock_callback_func, &mock_cb)->wait_for_all(); |
4287 | +} |
4288 | + |
4289 | +TEST_F(MirTrustSessionTest, executes_callback_on_stop) |
4290 | +{ |
4291 | + using namespace testing; |
4292 | + |
4293 | + MockCallback mock_cb; |
4294 | + EXPECT_CALL(mock_cb, call(_, &mock_cb)); |
4295 | + |
4296 | + MirTrustSession trust_session{ |
4297 | + stub_server, |
4298 | + event_distributor}; |
4299 | + trust_session.stop(mock_callback_func, &mock_cb)->wait_for_all(); |
4300 | +} |
4301 | + |
4302 | +TEST_F(MirTrustSessionTest, state_change_event_handler_started) |
4303 | +{ |
4304 | + using namespace testing; |
4305 | + |
4306 | + MirTrustSession trust_session{ |
4307 | + mock_server, |
4308 | + event_distributor}; |
4309 | + trust_session.register_trust_session_event_callback(&MirTrustSessionTest::trust_session_event, this); |
4310 | + |
4311 | + EXPECT_CALL(*this, state_updated(mir_trust_session_state_started)).Times(1); |
4312 | + |
4313 | + MirEvent e; |
4314 | + e.type = mir_event_type_trust_session_state_change; |
4315 | + e.trust_session.new_state = mir_trust_session_state_started; |
4316 | + event_distributor->handle_event(e); |
4317 | +} |
4318 | + |
4319 | +TEST_F(MirTrustSessionTest, state_change_event_handler_stopped) |
4320 | +{ |
4321 | + using namespace testing; |
4322 | + |
4323 | + MirTrustSession trust_session{ |
4324 | + mock_server, |
4325 | + event_distributor}; |
4326 | + trust_session.register_trust_session_event_callback(&MirTrustSessionTest::trust_session_event, this); |
4327 | + |
4328 | + EXPECT_CALL(*this, state_updated(mir_trust_session_state_stopped)).Times(1); |
4329 | + |
4330 | + MirEvent e; |
4331 | + e.type = mir_event_type_trust_session_state_change; |
4332 | + e.trust_session.new_state = mir_trust_session_state_stopped; |
4333 | + event_distributor->handle_event(e); |
4334 | +} |
4335 | + |
4336 | |
4337 | === modified file 'tests/unit-tests/frontend/stress_protobuf_communicator.cpp' |
4338 | --- tests/unit-tests/frontend/stress_protobuf_communicator.cpp 2014-03-06 06:05:17 +0000 |
4339 | +++ tests/unit-tests/frontend/stress_protobuf_communicator.cpp 2014-05-09 12:26:43 +0000 |
4340 | @@ -28,6 +28,7 @@ |
4341 | #include "src/client/connection_surface_map.h" |
4342 | #include "src/client/display_configuration.h" |
4343 | #include "src/client/lifecycle_control.h" |
4344 | +#include "src/client/event_distributor.h" |
4345 | #include "src/client/rpc/null_rpc_report.h" |
4346 | #include "src/client/rpc/make_rpc_channel.h" |
4347 | #include "src/client/rpc/mir_basic_rpc_channel.h" |
4348 | @@ -178,7 +179,8 @@ |
4349 | std::make_shared<mir::client::ConnectionSurfaceMap>(), |
4350 | std::make_shared<mir::client::DisplayConfiguration>(), |
4351 | rpc_report, |
4352 | - std::make_shared<mir::client::LifecycleControl>())), |
4353 | + std::make_shared<mir::client::LifecycleControl>(), |
4354 | + std::make_shared<mir::client::EventDistributor>())), |
4355 | display_server(channel.get(), ::google::protobuf::Service::STUB_DOESNT_OWN_CHANNEL), |
4356 | maxwait(timeout_ms), |
4357 | connect_done_called(false), |
4358 | |
4359 | === modified file 'tests/unit-tests/frontend/test_session_mediator.cpp' |
4360 | --- tests/unit-tests/frontend/test_session_mediator.cpp 2014-05-09 11:01:53 +0000 |
4361 | +++ tests/unit-tests/frontend/test_session_mediator.cpp 2014-05-09 12:26:43 +0000 |
4362 | @@ -713,6 +713,7 @@ |
4363 | EXPECT_EQ(stub_buffer.id().as_uint32_t(), |
4364 | protobuf_buffer.buffer_id()); |
4365 | } |
4366 | +<<<<<<< TREE |
4367 | |
4368 | TEST_F(SessionMediatorTest, client_socket_fd_calls_connector_client_socket_fd) |
4369 | { |
4370 | @@ -762,3 +763,54 @@ |
4371 | |
4372 | mediator.disconnect(nullptr, nullptr, nullptr, null_callback.get()); |
4373 | } |
4374 | +======= |
4375 | + |
4376 | +TEST_F(SessionMediatorTest, client_socket_fd_calls_connector_client_socket_fd) |
4377 | +{ |
4378 | + const int fd_count = 1; |
4379 | + const int dummy_fd = __LINE__; |
4380 | + |
4381 | + mp::ConnectParameters connect_parameters; |
4382 | + mp::Connection connection; |
4383 | + |
4384 | + mediator.connect(nullptr, &connect_parameters, &connection, null_callback.get()); |
4385 | + |
4386 | + ::mir::protobuf::SocketFDRequest request; |
4387 | + ::mir::protobuf::SocketFD response; |
4388 | + request.set_number(1); |
4389 | + |
4390 | + using namespace ::testing; |
4391 | + |
4392 | + EXPECT_CALL(connector, client_socket_fd(_)).Times(1).WillOnce(Return(dummy_fd)); |
4393 | + mediator.new_fds_for_trusted_clients(nullptr, &request, &response, null_callback.get()); |
4394 | + |
4395 | + EXPECT_THAT(response.fd_size(), Eq(fd_count)); |
4396 | + EXPECT_THAT(response.fd(0), Eq(dummy_fd)); |
4397 | + |
4398 | + mediator.disconnect(nullptr, nullptr, nullptr, null_callback.get()); |
4399 | +} |
4400 | + |
4401 | +TEST_F(SessionMediatorTest, client_socket_fd_allocates_requested_number_of_fds) |
4402 | +{ |
4403 | + const int fd_count = 11; |
4404 | + const int dummy_fd = __LINE__; |
4405 | + |
4406 | + mp::ConnectParameters connect_parameters; |
4407 | + mp::Connection connection; |
4408 | + |
4409 | + mediator.connect(nullptr, &connect_parameters, &connection, null_callback.get()); |
4410 | + |
4411 | + ::mir::protobuf::SocketFDRequest request; |
4412 | + ::mir::protobuf::SocketFD response; |
4413 | + request.set_number(fd_count); |
4414 | + |
4415 | + using namespace ::testing; |
4416 | + |
4417 | + EXPECT_CALL(connector, client_socket_fd(_)).Times(fd_count).WillRepeatedly(Return(dummy_fd)); |
4418 | + mediator.new_fds_for_trusted_clients(nullptr, &request, &response, null_callback.get()); |
4419 | + |
4420 | + EXPECT_THAT(response.fd_size(), Eq(fd_count)); |
4421 | + |
4422 | + mediator.disconnect(nullptr, nullptr, nullptr, null_callback.get()); |
4423 | +} |
4424 | +>>>>>>> MERGE-SOURCE |
4425 | |
4426 | === added file 'tests/unit-tests/graphics/mesa/test_drm_helper.cpp.moved' |
4427 | --- tests/unit-tests/graphics/mesa/test_drm_helper.cpp.moved 1970-01-01 00:00:00 +0000 |
4428 | +++ tests/unit-tests/graphics/mesa/test_drm_helper.cpp.moved 2014-05-09 12:26:43 +0000 |
4429 | @@ -0,0 +1,65 @@ |
4430 | +/* |
4431 | + * Copyright © 2014 Canonical Ltd. |
4432 | + * |
4433 | + * This program is free software: you can redistribute it and/or modify |
4434 | + * it under the terms of the GNU General Public License version 3 as |
4435 | + * published by the Free Software Foundation. |
4436 | + * |
4437 | + * This program is distributed in the hope that it will be useful, |
4438 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4439 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4440 | + * GNU General Public License for more details. |
4441 | + * |
4442 | + * You should have received a copy of the GNU General Public License |
4443 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
4444 | + * |
4445 | + * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com> |
4446 | + */ |
4447 | + |
4448 | +#include "src/platform/graphics/mesa/display_helpers.h" |
4449 | +#include "mir/udev/wrapper.h" |
4450 | + |
4451 | +#include "mir_test_framework/udev_environment.h" |
4452 | +#include "mir_test_doubles/mock_drm.h" |
4453 | + |
4454 | +#include <fcntl.h> |
4455 | + |
4456 | +#include <gtest/gtest.h> |
4457 | +#include <gmock/gmock.h> |
4458 | + |
4459 | +namespace mgm = mir::graphics::mesa; |
4460 | +namespace mtf = mir::mir_test_framework; |
4461 | +namespace mtd = mir::test::doubles; |
4462 | + |
4463 | +namespace |
4464 | +{ |
4465 | + |
4466 | +MATCHER_P(FlagSet, flag, "") |
4467 | +{ |
4468 | + return (arg & flag); |
4469 | +} |
4470 | + |
4471 | +class DRMHelperTest : public ::testing::Test |
4472 | +{ |
4473 | +public: |
4474 | + DRMHelperTest() |
4475 | + { |
4476 | + fake_devices.add_standard_device("standard-drm-devices"); |
4477 | + } |
4478 | + |
4479 | +protected: |
4480 | + ::testing::NiceMock<mtd::MockDRM> mock_drm; |
4481 | + mtf::UdevEnvironment fake_devices; |
4482 | +}; |
4483 | + |
4484 | +} |
4485 | + |
4486 | +TEST_F(DRMHelperTest, closes_drm_fd_on_exec) |
4487 | +{ |
4488 | + using namespace testing; |
4489 | + |
4490 | + EXPECT_CALL(mock_drm, open(_, FlagSet(O_CLOEXEC), _)); |
4491 | + |
4492 | + mgm::helpers::DRMHelper drm_helper; |
4493 | + drm_helper.setup(std::make_shared<mir::udev::Context>()); |
4494 | +} |
4495 | |
4496 | === modified file 'tests/unit-tests/scene/CMakeLists.txt' |
4497 | --- tests/unit-tests/scene/CMakeLists.txt 2014-05-06 06:16:13 +0000 |
4498 | +++ tests/unit-tests/scene/CMakeLists.txt 2014-05-09 12:26:43 +0000 |
4499 | @@ -9,6 +9,7 @@ |
4500 | ${CMAKE_CURRENT_SOURCE_DIR}/test_the_session_container_implementation.cpp |
4501 | ${CMAKE_CURRENT_SOURCE_DIR}/test_threaded_snapshot_strategy.cpp |
4502 | ${CMAKE_CURRENT_SOURCE_DIR}/test_mediating_display_changer.cpp |
4503 | + ${CMAKE_CURRENT_SOURCE_DIR}/test_trust_session.cpp |
4504 | |
4505 | ${CMAKE_CURRENT_SOURCE_DIR}/test_surface.cpp |
4506 | ${CMAKE_CURRENT_SOURCE_DIR}/test_surface_impl.cpp |
4507 | |
4508 | === modified file 'tests/unit-tests/scene/test_application_session.cpp' |
4509 | --- tests/unit-tests/scene/test_application_session.cpp 2014-04-15 10:19:19 +0000 |
4510 | +++ tests/unit-tests/scene/test_application_session.cpp 2014-05-09 12:26:43 +0000 |
4511 | @@ -27,6 +27,7 @@ |
4512 | #include "mir_test_doubles/stub_display_configuration.h" |
4513 | #include "mir_test_doubles/null_snapshot_strategy.h" |
4514 | #include "mir_test_doubles/null_event_sink.h" |
4515 | +#include "mir_test_doubles/null_trust_session.h" |
4516 | |
4517 | #include <gmock/gmock.h> |
4518 | #include <gtest/gtest.h> |
4519 | @@ -70,6 +71,10 @@ |
4520 | arg.stride == mir::geometry::Stride{} && |
4521 | arg.pixels == nullptr; |
4522 | } |
4523 | + |
4524 | +MATCHER_P(EqTrustedEventState, state, "") { |
4525 | + return arg.type == mir_event_type_trust_session_state_change && arg.trust_session.new_state == state; |
4526 | +} |
4527 | } |
4528 | |
4529 | TEST(ApplicationSession, create_and_destroy_surface) |
4530 | @@ -380,3 +385,43 @@ |
4531 | |
4532 | EXPECT_THAT(app_session.process_id(), Eq(pid)); |
4533 | } |
4534 | + |
4535 | +TEST(ApplicationSession, begin_trust_session) |
4536 | +{ |
4537 | + using namespace ::testing; |
4538 | + |
4539 | + mtd::MockSurfaceCoordinator surface_coordinator; |
4540 | + MockEventSink sender; |
4541 | + |
4542 | + ms::ApplicationSession app_session( |
4543 | + mt::fake_shared(surface_coordinator), |
4544 | + __LINE__, |
4545 | + "Foo", |
4546 | + std::make_shared<mtd::NullSnapshotStrategy>(), |
4547 | + std::make_shared<ms::NullSessionListener>(), |
4548 | + mt::fake_shared(sender)); |
4549 | + |
4550 | + EXPECT_CALL(sender, handle_event(EqTrustedEventState(mir_trust_session_state_started))).Times(1); |
4551 | + |
4552 | + app_session.begin_trust_session(); |
4553 | +} |
4554 | + |
4555 | +TEST(ApplicationSession, end_trust_session) |
4556 | +{ |
4557 | + using namespace ::testing; |
4558 | + |
4559 | + mtd::MockSurfaceCoordinator surface_coordinator; |
4560 | + MockEventSink sender; |
4561 | + |
4562 | + ms::ApplicationSession app_session( |
4563 | + mt::fake_shared(surface_coordinator), |
4564 | + __LINE__, |
4565 | + "Foo", |
4566 | + std::make_shared<mtd::NullSnapshotStrategy>(), |
4567 | + std::make_shared<ms::NullSessionListener>(), |
4568 | + mt::fake_shared(sender)); |
4569 | + |
4570 | + EXPECT_CALL(sender, handle_event(EqTrustedEventState(mir_trust_session_state_stopped))).Times(1); |
4571 | + |
4572 | + app_session.end_trust_session(); |
4573 | +} |
4574 | |
4575 | === modified file 'tests/unit-tests/scene/test_session_manager.cpp' |
4576 | --- tests/unit-tests/scene/test_session_manager.cpp 2014-04-15 10:19:19 +0000 |
4577 | +++ tests/unit-tests/scene/test_session_manager.cpp 2014-05-09 12:26:43 +0000 |
4578 | @@ -27,6 +27,9 @@ |
4579 | #include "src/server/scene/session_event_sink.h" |
4580 | #include "src/server/scene/basic_surface.h" |
4581 | #include "src/server/report/null_report_factory.h" |
4582 | +#include "mir/scene/trust_session_creation_parameters.h" |
4583 | +#include "mir/scene/null_trust_session_listener.h" |
4584 | +#include "mir/scene/trust_session.h" |
4585 | |
4586 | #include "mir_test/fake_shared.h" |
4587 | #include "mir_test_doubles/mock_buffer_stream.h" |
4588 | @@ -37,6 +40,8 @@ |
4589 | #include "mir_test_doubles/null_snapshot_strategy.h" |
4590 | #include "mir_test_doubles/null_surface_configurator.h" |
4591 | #include "mir_test_doubles/null_session_event_sink.h" |
4592 | +#include "mir_test_doubles/mock_trust_session_listener.h" |
4593 | +#include "mir_test_doubles/null_event_sink.h" |
4594 | |
4595 | #include <gmock/gmock.h> |
4596 | #include <gtest/gtest.h> |
4597 | @@ -44,7 +49,6 @@ |
4598 | namespace mc = mir::compositor; |
4599 | namespace mf = mir::frontend; |
4600 | namespace mi = mir::input; |
4601 | -namespace msh = mir::shell; |
4602 | namespace ms = mir::scene; |
4603 | namespace geom = mir::geometry; |
4604 | namespace mt = mir::test; |
4605 | @@ -78,7 +82,8 @@ |
4606 | mt::fake_shared(focus_setter), |
4607 | std::make_shared<mtd::NullSnapshotStrategy>(), |
4608 | std::make_shared<mtd::NullSessionEventSink>(), |
4609 | - mt::fake_shared(session_listener)) |
4610 | + mt::fake_shared(session_listener), |
4611 | + std::make_shared<ms::NullTrustSessionListener>()) |
4612 | { |
4613 | using namespace ::testing; |
4614 | ON_CALL(container, successor_of(_)).WillByDefault(Return((std::shared_ptr<ms::Session>()))); |
4615 | @@ -178,7 +183,8 @@ |
4616 | mt::fake_shared(focus_setter), |
4617 | std::make_shared<mtd::NullSnapshotStrategy>(), |
4618 | std::make_shared<mtd::NullSessionEventSink>(), |
4619 | - mt::fake_shared(session_listener)) |
4620 | + mt::fake_shared(session_listener), |
4621 | + std::make_shared<ms::NullTrustSessionListener>()) |
4622 | { |
4623 | using namespace ::testing; |
4624 | ON_CALL(container, successor_of(_)).WillByDefault(Return((std::shared_ptr<ms::Session>()))); |
4625 | @@ -187,7 +193,7 @@ |
4626 | mtd::MockSurfaceCoordinator surface_coordinator; |
4627 | testing::NiceMock<MockSessionContainer> container; // Inelegant but some tests need a stub |
4628 | testing::NiceMock<mtd::MockFocusSetter> focus_setter; // Inelegant but some tests need a stub |
4629 | - mtd::MockSessionListener session_listener; |
4630 | + testing::NiceMock<mtd::MockSessionListener> session_listener; |
4631 | |
4632 | ms::SessionManager session_manager; |
4633 | }; |
4634 | @@ -217,7 +223,8 @@ |
4635 | mt::fake_shared(focus_setter), |
4636 | std::make_shared<mtd::NullSnapshotStrategy>(), |
4637 | mt::fake_shared(session_event_sink), |
4638 | - std::make_shared<ms::NullSessionListener>()) |
4639 | + std::make_shared<ms::NullSessionListener>(), |
4640 | + std::make_shared<ms::NullTrustSessionListener>()) |
4641 | { |
4642 | using namespace ::testing; |
4643 | ON_CALL(container, successor_of(_)).WillByDefault(Return((std::shared_ptr<ms::Session>()))); |
4644 | @@ -257,3 +264,46 @@ |
4645 | session_manager.close_session(session1); |
4646 | session_manager.close_session(session); |
4647 | } |
4648 | + |
4649 | +namespace |
4650 | +{ |
4651 | + |
4652 | +struct SessionManagerTrustSessionListenerSetup : public testing::Test |
4653 | +{ |
4654 | + SessionManagerTrustSessionListenerSetup() |
4655 | + : session_manager(mt::fake_shared(surface_coordinator), |
4656 | + mt::fake_shared(container), |
4657 | + mt::fake_shared(focus_setter), |
4658 | + std::make_shared<mtd::NullSnapshotStrategy>(), |
4659 | + std::make_shared<mtd::NullSessionEventSink>(), |
4660 | + std::make_shared<ms::NullSessionListener>(), |
4661 | + mt::fake_shared(trust_session_listener)) |
4662 | + { |
4663 | + using namespace ::testing; |
4664 | + ON_CALL(container, successor_of(_)).WillByDefault(Return((std::shared_ptr<ms::Session>()))); |
4665 | + } |
4666 | + |
4667 | + mtd::MockSurfaceCoordinator surface_coordinator; |
4668 | + testing::NiceMock<MockSessionContainer> container; // Inelegant but some tests need a stub |
4669 | + testing::NiceMock<mtd::MockFocusSetter> focus_setter; // Inelegant but some tests need a stub |
4670 | + testing::NiceMock<mtd::MockTrustSessionListener> trust_session_listener; |
4671 | + mtd::NullEventSink event_sink; |
4672 | + |
4673 | + ms::SessionManager session_manager; |
4674 | +}; |
4675 | +} |
4676 | + |
4677 | +TEST_F(SessionManagerTrustSessionListenerSetup, trust_session_listener_is_notified_of_trust_session_start_and_stop) |
4678 | +{ |
4679 | + using namespace ::testing; |
4680 | + |
4681 | + EXPECT_CALL(trust_session_listener, starting(_)).Times(1); |
4682 | + EXPECT_CALL(trust_session_listener, stopping(_)).Times(1); |
4683 | + |
4684 | + auto helper = session_manager.open_session(__LINE__, "XPlane", mt::fake_shared(event_sink)); |
4685 | + |
4686 | + ms::TrustSessionCreationParameters parameters; |
4687 | + |
4688 | + auto trust_session = session_manager.start_trust_session_for(helper, parameters); |
4689 | + session_manager.stop_trust_session(trust_session); |
4690 | +} |
4691 | |
4692 | === added file 'tests/unit-tests/scene/test_trust_session.cpp' |
4693 | --- tests/unit-tests/scene/test_trust_session.cpp 1970-01-01 00:00:00 +0000 |
4694 | +++ tests/unit-tests/scene/test_trust_session.cpp 2014-05-09 12:26:43 +0000 |
4695 | @@ -0,0 +1,73 @@ |
4696 | +/* |
4697 | + * Copyright © 2014 Canonical Ltd. |
4698 | + * |
4699 | + * This program is free software: you can redistribute it and/or modify |
4700 | + * it under the terms of the GNU General Public License version 3 as |
4701 | + * published by the Free Software Foundation. |
4702 | + * |
4703 | + * This program is distributed in the hope that it will be useful, |
4704 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4705 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4706 | + * GNU General Public License for more details. |
4707 | + * |
4708 | + * You should have received a copy of the GNU General Public License |
4709 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
4710 | + * |
4711 | + * Authored By: Nick Dedekind <nick.dedekind@canonical.com> |
4712 | + */ |
4713 | + |
4714 | +#include "mir/frontend/event_sink.h" |
4715 | +#include "mir/scene/trust_session_creation_parameters.h" |
4716 | +#include "src/server/scene/trust_session_impl.h" |
4717 | +#include "mir_test/fake_shared.h" |
4718 | +#include "mir_test_doubles/mock_scene_session.h" |
4719 | +#include "mir_test_doubles/mock_trust_session_listener.h" |
4720 | + |
4721 | +#include <gmock/gmock.h> |
4722 | +#include <gtest/gtest.h> |
4723 | + |
4724 | +namespace mf = mir::frontend; |
4725 | +namespace ms = mir::scene; |
4726 | +namespace mt = mir::test; |
4727 | +namespace mtd = mir::test::doubles; |
4728 | + |
4729 | + |
4730 | +namespace |
4731 | +{ |
4732 | + |
4733 | +struct TrustSession : public testing::Test |
4734 | +{ |
4735 | + TrustSession() |
4736 | + { |
4737 | + } |
4738 | + |
4739 | + testing::NiceMock<mtd::MockTrustSessionListener> trust_session_listener; |
4740 | + testing::NiceMock<mtd::MockSceneSession> trusted_helper; |
4741 | + testing::NiceMock<mtd::MockSceneSession> trusted_app1; |
4742 | +}; |
4743 | +} |
4744 | + |
4745 | +TEST_F(TrustSession, start_and_stop) |
4746 | +{ |
4747 | + using namespace testing; |
4748 | + |
4749 | + EXPECT_CALL(trusted_helper, begin_trust_session()).Times(1); |
4750 | + EXPECT_CALL(trusted_helper, end_trust_session()).Times(1); |
4751 | + |
4752 | + EXPECT_CALL(trusted_app1, begin_trust_session()).Times(0); |
4753 | + EXPECT_CALL(trusted_app1, end_trust_session()).Times(0); |
4754 | + |
4755 | + EXPECT_CALL(trust_session_listener, trusted_session_beginning(_,_)).Times(1); |
4756 | + EXPECT_CALL(trust_session_listener, trusted_session_ending(_,_)).Times(1); |
4757 | + |
4758 | + auto shared_helper = mt::fake_shared(trusted_helper); |
4759 | + auto shared_app1 = mt::fake_shared(trusted_app1); |
4760 | + |
4761 | + ms::TrustSessionImpl trust_session(shared_helper, |
4762 | + ms::a_trust_session(), |
4763 | + mt::fake_shared(trust_session_listener)); |
4764 | + |
4765 | + trust_session.start(); |
4766 | + trust_session.add_trusted_child(shared_app1); |
4767 | + trust_session.stop(); |
4768 | +} |
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> )
@TrustedSession CreationParamet ers - 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.)