30
30
#include "src/client/mir_connection.h"
31
31
#include "src/client/default_connection_configuration.h"
32
32
#include "src/client/rpc/null_rpc_report.h"
33
#include "mir/dispatch/simple_dispatch_thread.h"
34
#include "mir/dispatch/dispatchable.h"
34
36
#include "mir/frontend/connector.h"
35
37
#include "mir/input/input_platform.h"
36
#include "mir/input/input_receiver_thread.h"
38
39
#include "mir_test/test_protobuf_server.h"
39
40
#include "mir_test/stub_server_tool.h"
40
41
#include "mir_test/gmock_fixes.h"
41
42
#include "mir_test/fake_shared.h"
43
#include "mir_test/pipe.h"
44
#include "mir_test/signal.h"
42
45
#include "mir_test_doubles/stub_client_buffer.h"
46
#include "mir_test/test_dispatchable.h"
48
#include <boost/throw_exception.hpp>
43
49
#include "mir_test_doubles/stub_client_buffer_factory.h"
44
50
#include "mir_test_doubles/stub_client_buffer_stream_factory.h"
45
51
#include "mir_test_doubles/mock_client_buffer_stream_factory.h"
46
52
#include "mir_test_doubles/mock_client_buffer_stream.h"
48
#include <gtest/gtest.h>
49
#include <gmock/gmock.h>
249
253
struct StubClientInputPlatform : public mircv::InputPlatform
251
std::shared_ptr<mircv::InputReceiverThread> create_input_thread(int /* fd */, std::function<void(MirEvent*)> const& /* callback */)
255
std::shared_ptr<mir::dispatch::Dispatchable> create_input_receiver(int /* fd */, std::shared_ptr<mircv::XKBMapper> const&, std::function<void(MirEvent*)> const& /* callback */)
253
return std::shared_ptr<mircv::InputReceiverThread>();
257
return std::shared_ptr<mir::dispatch::Dispatchable>();
257
261
struct MockClientInputPlatform : public mircv::InputPlatform
259
MOCK_METHOD2(create_input_thread, std::shared_ptr<mircv::InputReceiverThread>(int, std::function<void(MirEvent*)> const&));
262
struct MockInputReceiverThread : public mircv::InputReceiverThread
264
MOCK_METHOD0(start, void());
265
MOCK_METHOD0(stop, void());
266
MOCK_METHOD0(join, void());
263
MOCK_METHOD3(create_input_receiver, std::shared_ptr<mir::dispatch::Dispatchable>(int, std::shared_ptr<mircv::XKBMapper> const&, std::function<void(MirEvent*)> const&));
269
266
class TestConnectionConfiguration : public mcl::DefaultConnectionConfiguration
442
439
EXPECT_GE(std::chrono::steady_clock::now(), expected_end);
445
TEST_F(MirClientSurfaceTest, next_buffer_delegates_to_buffer_stream)
447
using namespace testing;
449
mtd::MockClientBufferStream mock_bs;
450
EXPECT_CALL(mock_bs, next_buffer(_)).Times(1);
452
mtd::MockClientBufferStreamFactory bs_factory;
453
EXPECT_CALL(bs_factory, make_producer_stream(_,_))
454
.Times(1).WillOnce(Return(mt::fake_shared(mock_bs)));
456
auto const surface = create_and_wait_for_surface_with(*client_comm_channel, mt::fake_shared(bs_factory));
457
surface->next_buffer(&null_surface_callback, nullptr);
460
// TODO: input fd is not checked in the test
461
TEST_F(MirClientSurfaceTest, creates_input_thread_with_input_fd_when_delegate_specified)
463
using namespace ::testing;
465
auto mock_input_platform = std::make_shared<MockClientInputPlatform>();
466
auto mock_input_thread = std::make_shared<NiceMock<MockInputReceiverThread>>();
467
MirEventDelegate delegate = {null_event_callback, nullptr};
469
EXPECT_CALL(*mock_input_platform, create_input_thread(_, _)).Times(1)
470
.WillOnce(Return(mock_input_thread));
471
EXPECT_CALL(*mock_input_thread, start()).Times(1);
472
EXPECT_CALL(*mock_input_thread, stop()).Times(1);
474
MirSurface surface{connection.get(), *client_comm_channel, nullptr,
475
stub_buffer_stream_factory, mock_input_platform, spec, &null_surface_callback, nullptr};
476
auto wait_handle = surface.get_create_wait_handle();
477
wait_handle->wait_for_all();
478
surface.set_event_handler(&delegate);
481
TEST_F(MirClientSurfaceTest, does_not_create_input_thread_when_no_delegate_specified)
483
using namespace ::testing;
485
auto mock_input_platform = std::make_shared<MockClientInputPlatform>();
486
auto mock_input_thread = std::make_shared<NiceMock<MockInputReceiverThread>>();
488
EXPECT_CALL(*mock_input_platform, create_input_thread(_, _)).Times(0);
489
EXPECT_CALL(*mock_input_thread, start()).Times(0);
490
EXPECT_CALL(*mock_input_thread, stop()).Times(0);
442
TEST_F(MirClientSurfaceTest, creates_input_thread_with_input_dispatcher_when_delegate_specified)
444
using namespace ::testing;
446
auto dispatched = std::make_shared<mt::Signal>();
448
auto mock_input_dispatcher = std::make_shared<mt::TestDispatchable>([dispatched]() { dispatched->raise(); });
449
auto mock_input_platform = std::make_shared<MockClientInputPlatform>();
451
EXPECT_CALL(*mock_input_platform, create_input_receiver(_, _, _)).Times(1)
452
.WillOnce(Return(mock_input_dispatcher));
454
MirSurface surface{connection.get(), *client_comm_channel, nullptr,
455
stub_buffer_stream_factory, mock_input_platform, spec, &null_surface_callback, nullptr};
456
auto wait_handle = surface.get_create_wait_handle();
457
wait_handle->wait_for_all();
458
surface.set_event_handler(null_event_callback, nullptr);
460
mock_input_dispatcher->trigger();
462
EXPECT_TRUE(dispatched->wait_for(std::chrono::seconds{5}));
465
TEST_F(MirClientSurfaceTest, replacing_delegate_with_nullptr_prevents_further_dispatch)
467
using namespace ::testing;
469
auto dispatched = std::make_shared<mt::Signal>();
471
auto mock_input_dispatcher = std::make_shared<mt::TestDispatchable>([dispatched]() { dispatched->raise(); });
472
auto mock_input_platform = std::make_shared<MockClientInputPlatform>();
474
EXPECT_CALL(*mock_input_platform, create_input_receiver(_, _, _)).Times(1)
475
.WillOnce(Return(mock_input_dispatcher));
477
MirSurface surface{connection.get(), *client_comm_channel, nullptr,
478
stub_buffer_stream_factory, mock_input_platform, spec, &null_surface_callback, nullptr};
479
auto wait_handle = surface.get_create_wait_handle();
480
wait_handle->wait_for_all();
481
surface.set_event_handler(null_event_callback, nullptr);
483
// Should now not get dispatched.
484
surface.set_event_handler(nullptr, nullptr);
486
mock_input_dispatcher->trigger();
488
EXPECT_FALSE(dispatched->wait_for(std::chrono::seconds{1}));
492
TEST_F(MirClientSurfaceTest, does_not_create_input_dispatcher_when_no_delegate_specified)
494
using namespace ::testing;
496
auto mock_input_platform = std::make_shared<MockClientInputPlatform>();
498
EXPECT_CALL(*mock_input_platform, create_input_receiver(_, _, _)).Times(0);
492
500
MirSurface surface{connection.get(), *client_comm_channel, nullptr,
493
501
stub_buffer_stream_factory, mock_input_platform, spec, &null_surface_callback, nullptr};