=== added file 'include/server/mir/default_pause_resume_listener.h'
--- include/server/mir/default_pause_resume_listener.h 1970-01-01 00:00:00 +0000
+++ include/server/mir/default_pause_resume_listener.h 2013-09-18 21:09:49 +0000
@@ -0,0 +1,40 @@
+/*
+ * Copyright © 2013 Canonical Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ * Authored by: Robert Ancell
+ */
+
+#ifndef MIR_DEFAULT_PAUSE_RESUME_LISTENER_H_
+#define MIR_DEFAULT_PAUSE_RESUME_LISTENER_H_
+
+#include "mir/pause_resume_listener.h"
+
+namespace mir
+{
+class DefaultPauseResumeListener : public virtual PauseResumeListener
+{
+public:
+ virtual void paused()
+ {
+ }
+
+ virtual void resumed()
+ {
+ }
+};
+
+}
+
+#endif /* MIR_DEFAULT_PAUSE_RESUME_LISTENER_H_ */
=== modified file 'include/server/mir/default_server_configuration.h'
--- include/server/mir/default_server_configuration.h 2013-09-18 16:24:32 +0000
+++ include/server/mir/default_server_configuration.h 2013-09-18 21:09:49 +0000
@@ -123,6 +123,7 @@
virtual std::shared_ptr the_compositor();
virtual std::shared_ptr the_input_manager();
virtual std::shared_ptr the_main_loop();
+ virtual std::shared_ptr the_pause_resume_listener();
virtual std::shared_ptr the_display_changer();
virtual std::shared_ptr the_graphics_platform();
virtual std::shared_ptr the_input_configuration();
@@ -286,6 +287,7 @@
CachedPtr surface_controller;
CachedPtr time_source;
CachedPtr main_loop;
+ CachedPtr pause_resume_listener;
CachedPtr display_configuration_policy;
CachedPtr host_connection;
CachedPtr nested_input_relay;
=== added file 'include/server/mir/pause_resume_listener.h'
--- include/server/mir/pause_resume_listener.h 1970-01-01 00:00:00 +0000
+++ include/server/mir/pause_resume_listener.h 2013-09-18 21:09:49 +0000
@@ -0,0 +1,40 @@
+/*
+ * Copyright © 2013 Canonical Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ * Authored by: Robert Ancell
+ */
+
+#ifndef MIR_PAUSE_RESUME_LISTENER_H_
+#define MIR_PAUSE_RESUME_LISTENER_H_
+
+namespace mir
+{
+
+class PauseResumeListener
+{
+public:
+ virtual void paused() = 0;
+ virtual void resumed() = 0;
+
+protected:
+ PauseResumeListener() = default;
+ virtual ~PauseResumeListener() = default;
+ PauseResumeListener(PauseResumeListener const&) = delete;
+ PauseResumeListener& operator=(PauseResumeListener const&) = delete;
+};
+
+}
+
+#endif /* MIR_PAUSE_RESUME_LISTENER_H_ */
=== modified file 'include/server/mir/server_configuration.h'
--- include/server/mir/server_configuration.h 2013-08-28 03:41:48 +0000
+++ include/server/mir/server_configuration.h 2013-09-18 21:09:49 +0000
@@ -49,6 +49,7 @@
}
class MainLoop;
+class PauseResumeListener;
class DisplayChanger;
class ServerConfiguration
@@ -61,6 +62,7 @@
virtual std::shared_ptr the_compositor() = 0;
virtual std::shared_ptr the_input_manager() = 0;
virtual std::shared_ptr the_main_loop() = 0;
+ virtual std::shared_ptr the_pause_resume_listener() = 0;
virtual std::shared_ptr the_display_changer() = 0;
virtual std::shared_ptr the_graphics_platform() = 0;
virtual std::shared_ptr the_input_configuration() = 0;
=== added file 'include/test/mir_test_doubles/mock_pause_resume_listener.h'
--- include/test/mir_test_doubles/mock_pause_resume_listener.h 1970-01-01 00:00:00 +0000
+++ include/test/mir_test_doubles/mock_pause_resume_listener.h 2013-09-18 21:09:49 +0000
@@ -0,0 +1,44 @@
+/*
+ * Copyright © 2013 Canonical Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ * Authored by: Robert Ancell
+ */
+
+#ifndef MIR_TEST_DOUBLES_MOCK_PAUSE_RESUME_LISTENER_H_
+#define MIR_TEST_DOUBLES_MOCK_PAUSE_RESUME_LISTENER_H_
+
+#include "mir/pause_resume_listener.h"
+
+#include
+
+namespace mir
+{
+namespace test
+{
+namespace doubles
+{
+
+class MockPauseResumeListener : public mir::PauseResumeListener
+{
+public:
+ MOCK_METHOD0(paused, void());
+ MOCK_METHOD0(resumed, void());
+};
+
+}
+}
+}
+
+#endif /* MIR_TEST_DOUBLES_MOCK_PAUSE_RESUME_LISTENER_H_ */
=== modified file 'src/server/default_server_configuration.cpp'
--- src/server/default_server_configuration.cpp 2013-09-18 16:24:32 +0000
+++ src/server/default_server_configuration.cpp 2013-09-18 21:09:49 +0000
@@ -19,6 +19,7 @@
#include "mir/default_server_configuration.h"
#include "mir/abnormal_exit.h"
#include "mir/asio_main_loop.h"
+#include "mir/default_pause_resume_listener.h"
#include "mir/shared_library.h"
#include "mir/options/program_option.h"
@@ -936,6 +937,16 @@
});
}
+
+std::shared_ptr mir::DefaultServerConfiguration::the_pause_resume_listener()
+{
+ return pause_resume_listener(
+ []()
+ {
+ return std::make_shared();
+ });
+}
+
std::shared_ptr
mir::DefaultServerConfiguration::the_display_configuration_policy()
{
=== modified file 'src/server/display_server.cpp'
--- src/server/display_server.cpp 2013-08-28 03:41:48 +0000
+++ src/server/display_server.cpp 2013-09-18 21:09:49 +0000
@@ -21,6 +21,7 @@
#include "mir/display_server.h"
#include "mir/server_configuration.h"
#include "mir/main_loop.h"
+#include "mir/pause_resume_listener.h"
#include "mir/display_changer.h"
#include "mir/compositor/compositor.h"
@@ -74,6 +75,7 @@
communicator{config.the_communicator()},
input_manager{config.the_input_manager()},
main_loop{config.the_main_loop()},
+ pause_resume_listener{config.the_pause_resume_listener()},
display_changer{config.the_display_changer()},
paused{false},
configure_display_on_resume{false}
@@ -113,6 +115,8 @@
return false;
}
+ pause_resume_listener->paused();
+
return true;
}
@@ -149,6 +153,8 @@
return false;
}
+ pause_resume_listener->resumed();
+
return true;
}
@@ -173,6 +179,7 @@
std::shared_ptr const communicator;
std::shared_ptr const input_manager;
std::shared_ptr const main_loop;
+ std::shared_ptr const pause_resume_listener;
std::shared_ptr const display_changer;
bool paused;
bool configure_display_on_resume;
=== modified file 'tests/integration-tests/test_display_server_main_loop_events.cpp'
--- tests/integration-tests/test_display_server_main_loop_events.cpp 2013-08-28 03:41:48 +0000
+++ tests/integration-tests/test_display_server_main_loop_events.cpp 2013-09-18 21:09:49 +0000
@@ -22,12 +22,14 @@
#include "mir/graphics/display_configuration_policy.h"
#include "mir/main_loop.h"
#include "mir/display_changer.h"
+#include "mir/pause_resume_listener.h"
#include "mir_test/pipe.h"
#include "mir_test_framework/testing_server_configuration.h"
#include "mir_test_doubles/mock_input_manager.h"
#include "mir_test_doubles/mock_compositor.h"
#include "mir_test_doubles/null_display.h"
+#include "mir_test_doubles/mock_pause_resume_listener.h"
#include "mir/run_mir.h"
#include
@@ -311,6 +313,71 @@
int const resume_signal;
};
+class TestPauseResumeListenerConfig : public mtf::TestingServerConfiguration
+{
+public:
+ TestPauseResumeListenerConfig()
+ : pause_signal{SIGUSR1}, resume_signal{SIGUSR2}
+ {
+ }
+
+ std::shared_ptr the_display() override
+ {
+ if (!mock_display)
+ {
+ auto display = mtf::TestingServerConfiguration::the_display();
+ mock_display = std::make_shared(display,
+ pause_signal,
+ resume_signal,
+ p.read_fd());
+ }
+
+ return mock_display;
+ }
+
+ std::shared_ptr the_pause_resume_listener() override
+ {
+ if (!mock_pause_resume_listener)
+ mock_pause_resume_listener = std::make_shared();
+
+ return mock_pause_resume_listener;
+ }
+
+ std::shared_ptr the_mock_display()
+ {
+ the_display();
+ return mock_display;
+ }
+
+ std::shared_ptr the_mock_pause_resume_listener()
+ {
+ the_pause_resume_listener();
+ return mock_pause_resume_listener;
+ }
+
+ void emit_pause_event_and_wait_for_handler()
+ {
+ kill(getpid(), pause_signal);
+ while (!mock_display->pause_handler_invoked())
+ std::this_thread::sleep_for(std::chrono::microseconds{500});
+ }
+
+ void emit_resume_event_and_wait_for_handler()
+ {
+ kill(getpid(), resume_signal);
+ while (!mock_display->resume_handler_invoked())
+ std::this_thread::sleep_for(std::chrono::microseconds{500});
+ }
+
+private:
+ std::shared_ptr mock_display;
+ std::shared_ptr mock_pause_resume_listener;
+
+ mt::Pipe p;
+ int const pause_signal;
+ int const resume_signal;
+};
+
}
TEST(DisplayServerMainLoopEvents, display_server_shuts_down_properly_on_sigint)
@@ -582,3 +649,35 @@
t.detach();
});
}
+
+TEST(DisplayServerMainLoopEvents, pause_resume_listener)
+{
+ using namespace testing;
+
+ TestPauseResumeListenerConfig server_config;
+
+ auto mock_display = server_config.the_mock_display();
+ auto mock_pause_resume_listener = server_config.the_mock_pause_resume_listener();
+
+ {
+ InSequence s;
+
+ EXPECT_CALL(*mock_display, pause()).Times(1);
+ EXPECT_CALL(*mock_pause_resume_listener, paused()).Times(1);
+ EXPECT_CALL(*mock_display, resume()).Times(1);
+ EXPECT_CALL(*mock_pause_resume_listener, resumed()).Times(1);
+ }
+
+ mir::run_mir(server_config,
+ [&server_config](mir::DisplayServer&)
+ {
+ std::thread t{
+ [&]
+ {
+ server_config.emit_pause_event_and_wait_for_handler();
+ server_config.emit_resume_event_and_wait_for_handler();
+ kill(getpid(), SIGTERM);
+ }};
+ t.detach();
+ });
+}