Merge lp:~mir-team/unity-system-compositor/toggle-cursor into lp:unity-system-compositor

Proposed by Andreas Pokorny
Status: Work in progress
Proposed branch: lp:~mir-team/unity-system-compositor/toggle-cursor
Merge into: lp:unity-system-compositor
Diff against target: 8316 lines (+1598/-5675)
65 files modified
CMakeLists.txt (+2/-1)
debian/changelog (+0/-8)
debian/control (+5/-4)
spinner/eglapp.c (+10/-7)
spinner/eglspinner.c (+5/-16)
src/CMakeLists.txt (+14/-20)
src/com.canonical.Unity.Screen.xml (+0/-29)
src/cursor_enabler.cpp (+72/-0)
src/cursor_enabler.h (+58/-0)
src/dbus_connection_handle.cpp (+0/-102)
src/dbus_connection_handle.h (+0/-48)
src/dbus_event_loop.cpp (+0/-444)
src/dbus_event_loop.h (+0/-87)
src/dbus_message_handle.cpp (+0/-83)
src/dbus_message_handle.h (+0/-48)
src/dbus_screen.cpp (+213/-0)
src/dbus_screen.h (+77/-0)
src/dbus_screen_observer.h (+9/-26)
src/external_spinner.cpp (+9/-28)
src/external_spinner.h (+2/-4)
src/generate_header_with_string_from_file.sh (+0/-26)
src/powerd_mediator.cpp (+237/-401)
src/powerd_mediator.h (+64/-71)
src/powerkey_handler.cpp (+41/-52)
src/powerkey_handler.h (+22/-27)
src/scoped_dbus_error.h (+0/-57)
src/screen_hardware.h (+0/-49)
src/screen_state_handler.cpp (+75/-73)
src/screen_state_handler.h (+37/-42)
src/server.cpp (+8/-88)
src/server.h (+41/-61)
src/shell.cpp (+157/-0)
src/shell.h (+54/-0)
src/system_compositor.cpp (+71/-15)
src/system_compositor.h (+8/-13)
src/thread_name.cpp (+0/-32)
src/thread_name.h (+0/-29)
src/unity_screen_service.cpp (+0/-358)
src/unity_screen_service.h (+0/-83)
src/window_manager.cpp (+0/-234)
src/window_manager.h (+0/-85)
src/worker_thread.cpp (+142/-0)
src/worker_thread.h (+55/-0)
tests/CMakeLists.txt (+0/-1)
tests/integration-tests/CMakeLists.txt (+0/-53)
tests/integration-tests/dbus_bus.cpp (+0/-52)
tests/integration-tests/dbus_bus.h (+0/-46)
tests/integration-tests/dbus_client.cpp (+0/-151)
tests/integration-tests/dbus_client.h (+0/-113)
tests/integration-tests/run_command.cpp (+0/-44)
tests/integration-tests/run_command.h (+0/-34)
tests/integration-tests/test_dbus_event_loop.cpp (+0/-232)
tests/integration-tests/test_external_spinner.cpp (+0/-167)
tests/integration-tests/test_powerd_mediator.cpp (+0/-655)
tests/integration-tests/test_unity_screen_service.cpp (+0/-413)
tests/integration-tests/usc_test_helper_wait_for_signal.c (+0/-24)
tests/integration-tests/wait_condition.h (+0/-72)
tests/unit-tests/CMakeLists.txt (+1/-4)
tests/unit-tests/advanceable_timer.cpp (+0/-211)
tests/unit-tests/advanceable_timer.h (+0/-53)
tests/unit-tests/fake_shared.h (+0/-33)
tests/unit-tests/test_cursor_enabler.cpp (+109/-0)
tests/unit-tests/test_mir_screen.cpp (+0/-366)
tests/unit-tests/test_screen_event_handler.cpp (+0/-196)
tests/unit-tests/test_session_switcher.cpp (+0/-4)
To merge this branch: bzr merge lp:~mir-team/unity-system-compositor/toggle-cursor
Reviewer Review Type Date Requested Status
Unity System Compositor Development Team Pending
Review via email: mp+248520@code.launchpad.net

Commit message

Toggle cursor by watching the event stream

To post a comment you must log in.
202. By Andreas Pokorny

merged mirevent-2.0

203. By Andreas Pokorny

keep display on when mouse pointer moves

204. By Andreas Pokorny

merge event-2.0 changes back in

*fingers-crossed*

205. By Andreas Pokorny

merge but omit changes from trunk since we need to target mir-0.12.1

206. By Andreas Pokorny

rebase by skipping the changes in unity-system-compositor

Unmerged revisions

206. By Andreas Pokorny

rebase by skipping the changes in unity-system-compositor

205. By Andreas Pokorny

merge but omit changes from trunk since we need to target mir-0.12.1

204. By Andreas Pokorny

merge event-2.0 changes back in

*fingers-crossed*

203. By Andreas Pokorny

keep display on when mouse pointer moves

202. By Andreas Pokorny

merged mirevent-2.0

201. By Andreas Pokorny

further cleanup drops all references to cursor image again

200. By Andreas Pokorny

ok nearly

199. By Andreas Pokorny

merged msh changes

198. By Andreas Pokorny

merged event-2.0 changes

197. By Andreas Pokorny

add test and cleanup further

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2015-04-07 13:36:48 +0000
3+++ CMakeLists.txt 2015-05-12 16:45:46 +0000
4@@ -44,10 +44,11 @@
5 pkg_check_modules(GLIB REQUIRED glib-2.0)
6 pkg_check_modules(MIRCLIENT REQUIRED mirclient)
7 pkg_check_modules(MIRSERVER REQUIRED mirserver)
8-pkg_check_modules(DBUS REQUIRED dbus-1)
9
10 find_package(Boost 1.48.0 COMPONENTS system REQUIRED)
11 find_package(GLESv2 REQUIRED)
12+find_package(Qt5Core)
13+find_package(Qt5DBus)
14
15 add_subdirectory(spinner/)
16 add_subdirectory(src/)
17
18=== modified file 'debian/changelog'
19--- debian/changelog 2015-04-30 16:23:53 +0000
20+++ debian/changelog 2015-05-12 16:45:46 +0000
21@@ -1,11 +1,3 @@
22-unity-system-compositor (0.0.5+15.04.20150430-0ubuntu1) vivid; urgency=medium
23-
24- [ Ricardo Salveti de Araujo ]
25- * Check if the android.conf file is present which means we are on the
26- new way of defining device specific environment variables.
27-
28- -- CI Train Bot <ci-train-bot@canonical.com> Thu, 30 Apr 2015 16:23:53 +0000
29-
30 unity-system-compositor (0.0.5+15.04.20150227-0ubuntu1) vivid; urgency=medium
31
32 [ CI Train Bot ]
33
34=== modified file 'debian/control'
35--- debian/control 2015-05-06 16:09:19 +0000
36+++ debian/control 2015-05-12 16:45:46 +0000
37@@ -4,7 +4,6 @@
38 Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
39 Build-Depends: cmake,
40 cmake-data,
41- dbus,
42 debhelper (>= 9),
43 g++-4.9,
44 google-mock,
45@@ -12,15 +11,17 @@
46 libboost-dev,
47 libboost-system-dev,
48 libcairo2-dev,
49- libdbus-1-dev,
50 libglib2.0-dev,
51 libgles2-mesa-dev,
52- libmirclient-dev (>= 0.13.0),
53- libmirserver-dev (>= 0.13.0),
54+ libmirclient-dev (>= 0.6.0),
55+ libmirserver-dev (>= 0.11.0),
56 libprotobuf-dev,
57 pkg-config,
58 python:any (>= 2.7),
59 python-setuptools,
60+ qt5-default,
61+ qtbase5-dev,
62+ qtbase5-dev-tools,
63 Standards-Version: 3.9.4
64 Homepage: https://launchpad.net/unity-system-compositor
65 # if you don't have have commit access to this branch but would like to upload
66
67=== modified file 'spinner/eglapp.c'
68--- spinner/eglapp.c 2015-04-24 12:48:10 +0000
69+++ spinner/eglapp.c 2015-05-12 16:45:46 +0000
70@@ -92,9 +92,8 @@
71 {
72 (void) surface;
73 (void) context;
74- if (mir_event_get_type(ev) == mir_event_type_resize)
75+ if (ev->type == mir_event_type_resize)
76 {
77- MirResizeEvent const* resize = mir_event_get_resize_event(ev);
78 /*
79 * FIXME: https://bugs.launchpad.net/mir/+bug/1194384
80 * It is unsafe to set the width and height here because we're in a
81@@ -102,9 +101,7 @@
82 * support for event queuing (directing them to another thread) or
83 * full single-threaded callbacks. (LP: #1194384).
84 */
85- printf("Resized to %dx%d\n",
86- mir_resize_event_get_width(resize),
87- mir_resize_event_get_height(resize));
88+ printf("Resized to %dx%d\n", ev->resize.width, ev->resize.height);
89 }
90 }
91
92@@ -147,6 +144,11 @@
93 mir_buffer_usage_hardware,
94 mir_display_output_id_invalid
95 };
96+ MirEventDelegate delegate =
97+ {
98+ mir_eglapp_handle_event,
99+ NULL
100+ };
101 EGLConfig eglconfig;
102 EGLint neglconfigs;
103 EGLContext eglctx;
104@@ -321,7 +323,7 @@
105 surface = mir_connection_create_surface_sync(connection, &surfaceparm);
106 CHECK(mir_surface_is_valid(surface), "Can't create a surface");
107
108- mir_surface_set_event_handler(surface, mir_eglapp_handle_event, NULL);
109+ mir_surface_set_event_handler(surface, &delegate);
110
111 egldisplay = eglGetDisplay(
112 (EGLNativeDisplayType) mir_connection_get_egl_native_display(connection));
113@@ -335,7 +337,8 @@
114 CHECK(neglconfigs > 0, "No EGL config available");
115
116 eglsurface = eglCreateWindowSurface(egldisplay, eglconfig,
117- (EGLNativeWindowType)mir_buffer_stream_get_egl_native_window(mir_surface_get_buffer_stream(surface)), NULL);
118+ (EGLNativeWindowType)mir_surface_get_egl_native_window(surface),
119+ NULL);
120 CHECK(eglsurface != EGL_NO_SURFACE, "eglCreateWindowSurface failed");
121
122 eglctx = eglCreateContext(egldisplay, eglconfig, EGL_NO_CONTEXT,
123
124=== modified file 'spinner/eglspinner.c'
125--- spinner/eglspinner.c 2015-05-01 14:16:27 +0000
126+++ spinner/eglspinner.c 2015-05-12 16:45:46 +0000
127@@ -27,7 +27,6 @@
128 #include <stdlib.h>
129 #include <GLES2/gl2.h>
130 #include <math.h>
131-#include <sys/stat.h>
132 #if HAVE_PROPS
133 #include <hybris/properties/properties.h>
134 #endif
135@@ -37,7 +36,6 @@
136 #define VALUE_KEY "GRID_UNIT_PX"
137 #define VALUE_KEY_LENGTH 12
138 #define PROP_KEY "ro.product.device"
139-#define DEFAULT_FILE "/etc/ubuntu-touch-session.d/android.conf"
140 #define FILE_BASE "/etc/ubuntu-touch-session.d/"
141 #define FILE_EXTENSION ".conf"
142
143@@ -54,22 +52,13 @@
144 // get name of file to read from
145 bzero ((void*) filename, MAX_LENGTH);
146 strcpy (filename, FILE_BASE);
147-
148- struct stat buf;
149- if (stat(DEFAULT_FILE, &buf) == 0)
150- {
151- strcpy (filename, DEFAULT_FILE);
152- }
153- else
154- {
155 #ifdef HAVE_PROPS
156- char* defaultValue = "";
157- char value[PROP_VALUE_MAX];
158- property_get (PROP_KEY, value, defaultValue);
159- strcat (filename, value);
160+ char* defaultValue = "";
161+ char value[PROP_VALUE_MAX];
162+ property_get (PROP_KEY, value, defaultValue);
163+ strcat (filename, value);
164 #endif
165- strcat (filename, FILE_EXTENSION);
166- }
167+ strcat (filename, FILE_EXTENSION);
168
169 // try to open it
170 handle = fopen ((const char*) filename, "r");
171
172=== modified file 'src/CMakeLists.txt'
173--- src/CMakeLists.txt 2015-04-07 13:36:48 +0000
174+++ src/CMakeLists.txt 2015-05-12 16:45:46 +0000
175@@ -16,30 +16,24 @@
176
177 set(USC_SRCS
178 asio_dm_connection.cpp
179- dbus_connection_handle.cpp
180- dbus_event_loop.cpp
181- dbus_message_handle.cpp
182+ cursor_enabler.cpp
183+ dbus_screen.cpp
184 external_spinner.cpp
185- mir_screen.cpp
186 powerd_mediator.cpp
187- screen_event_handler.cpp
188+ powerkey_handler.cpp
189+ screen_state_handler.cpp
190 server.cpp
191+ shell.cpp
192 session_switcher.cpp
193 system_compositor.cpp
194- thread_name.cpp
195- unity_screen_service.cpp
196- unity_screen_service_introspection.h
197- window_manager.cpp
198+ worker_thread.cpp
199 )
200
201-# Generate unity_screen_service_introspection.h from the introspection XML file
202-add_custom_command(
203- OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/unity_screen_service_introspection.h
204- COMMAND sh generate_header_with_string_from_file.sh ${CMAKE_CURRENT_BINARY_DIR}/unity_screen_service_introspection.h unity_screen_service_introspection com.canonical.Unity.Screen.xml
205- DEPENDS com.canonical.Unity.Screen.xml generate_header_with_string_from_file.sh
206- WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
207- VERBATIM
208-)
209+qt5_generate_dbus_interface(dbus_screen.h com.canonical.Unity.Screen.xml)
210+qt5_add_dbus_adaptor(USC_SRCS
211+ ${CMAKE_CURRENT_BINARY_DIR}/com.canonical.Unity.Screen.xml
212+ dbus_screen.h DBusScreen
213+ dbus_screen_adaptor DBusScreenAdaptor)
214
215 # Compile system compositor
216 add_library(
217@@ -58,12 +52,13 @@
218 ${Boost_INCLUDE_DIRS}
219 ${GLESv2_INCLUDE_DIRS}
220 ${MIRSERVER_INCLUDE_DIRS}
221- ${DBUS_INCLUDE_DIRS}
222 )
223 add_definitions(
224 -DDEFAULT_SPINNER="${CMAKE_INSTALL_FULL_BINDIR}/unity-system-compositor-spinner"
225 )
226
227+qt5_use_modules(usc Core DBus)
228+
229 link_directories(${MIRSERVER_LIBRARY_DIRS})
230
231 target_link_libraries(usc
232@@ -71,7 +66,6 @@
233 pthread
234 ${Boost_LIBRARIES}
235 ${GLESv2_LIBRARIES}
236- ${DBUS_LIBRARIES}
237 )
238
239 target_link_libraries(unity-system-compositor
240@@ -87,6 +81,6 @@
241 install(FILES com.canonical.Unity.Screen.conf
242 DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/dbus-1/system.d
243 )
244-install(FILES com.canonical.Unity.Screen.xml
245+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/com.canonical.Unity.Screen.xml
246 DESTINATION ${CMAKE_INSTALL_DATADIR}/dbus-1/interfaces
247 )
248
249=== removed file 'src/com.canonical.Unity.Screen.xml'
250--- src/com.canonical.Unity.Screen.xml 2015-03-18 13:06:10 +0000
251+++ src/com.canonical.Unity.Screen.xml 1970-01-01 00:00:00 +0000
252@@ -1,29 +0,0 @@
253-<!DOCTYPE node PUBLIC '-//freedesktop//DTD D-BUS Object Introspection 1.0//EN' 'http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd'>
254-<node>
255- <interface name='com.canonical.Unity.Screen'>
256- <method name='setScreenPowerMode'>
257- <arg type='b' direction='out'/>
258- <arg name='mode' type='s' direction='in'/>
259- <arg name='reason' type='i' direction='in'/>
260- </method>
261- <method name='keepDisplayOn'>
262- <arg type='i' direction='out'/>
263- </method>
264- <method name='removeDisplayOnRequest'>
265- <arg name='id' type='i' direction='in'/>
266- </method>
267- <method name='setUserBrightness'>
268- <arg name='brightness' type='i' direction='in'/>
269- </method>
270- <method name='userAutobrightnessEnable'>
271- <arg name='enable' type='b' direction='in'/>
272- </method>
273- <method name='setInactivityTimeouts'>
274- <arg name='poweroff_timeout' type='i' direction='in'/>
275- <arg name='dimmer_timeout' type='i' direction='in'/>
276- </method>
277- <method name='setTouchVisualizationEnabled'>
278- <arg name='enabled' type='b' direction='in'/>
279- </method>
280- </interface>
281-</node>
282
283=== added file 'src/cursor_enabler.cpp'
284--- src/cursor_enabler.cpp 1970-01-01 00:00:00 +0000
285+++ src/cursor_enabler.cpp 2015-05-12 16:45:46 +0000
286@@ -0,0 +1,72 @@
287+/*
288+ * Copyright © 2015 Canonical Ltd.
289+ *
290+ * This program is free software: you can redistribute it and/or modify
291+ * it under the terms of the GNU General Public License version 3 as
292+ * published by the Free Software Foundation.
293+ *
294+ * This program is distributed in the hope that it will be useful,
295+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
296+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
297+ * GNU General Public License for more details.
298+ *
299+ * You should have received a copy of the GNU General Public License
300+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
301+ */
302+
303+#include "cursor_enabler.h"
304+
305+#include "mir/graphics/cursor.h"
306+#include "mir_toolkit/event.h"
307+
308+namespace mi = mir::input;
309+
310+CursorEnabler::CursorEnabler(
311+ std::shared_ptr<mir::graphics::Cursor> const& cursor,
312+ std::chrono::milliseconds remove_pointer_timeout)
313+ : cursor_shown(false), remove_delay{static_cast<uint32_t>(remove_pointer_timeout.count())}, last_cursor_movement(0),
314+ cursor(cursor)
315+{
316+ cursor->hide();
317+}
318+
319+CursorEnabler::~CursorEnabler() = default;
320+
321+bool CursorEnabler::handle(MirEvent const& event)
322+{
323+ if (mir_event_get_type(&event) != mir_event_type_input)
324+ {
325+ return false;
326+ }
327+ auto const* ev = mir_event_get_input_event(&event);
328+ if (mir_input_event_type_pointer == mir_input_event_get_type(ev))
329+ {
330+ enable_cursor();
331+ last_cursor_movement = event.motion.event_time;
332+ }
333+ else if (remove_delay &&
334+ mir_input_event_type_touch == mir_input_event_get_type(ev) &&
335+ (event.motion.event_time - last_cursor_movement > remove_delay))
336+ {
337+ disable_cursor();
338+ }
339+ return false;
340+}
341+
342+void CursorEnabler::enable_cursor()
343+{
344+ if (!cursor_shown)
345+ {
346+ cursor->show();
347+ cursor_shown = true;
348+ }
349+}
350+
351+void CursorEnabler::disable_cursor()
352+{
353+ if (cursor_shown)
354+ {
355+ cursor->hide();
356+ cursor_shown = false;
357+ }
358+}
359
360=== added file 'src/cursor_enabler.h'
361--- src/cursor_enabler.h 1970-01-01 00:00:00 +0000
362+++ src/cursor_enabler.h 2015-05-12 16:45:46 +0000
363@@ -0,0 +1,58 @@
364+/*
365+ * Copyright © 2015 Canonical Ltd.
366+ *
367+ * This program is free software: you can redistribute it and/or modify
368+ * it under the terms of the GNU General Public License version 3 as
369+ * published by the Free Software Foundation.
370+ *
371+ * This program is distributed in the hope that it will be useful,
372+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
373+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
374+ * GNU General Public License for more details.
375+ *
376+ * You should have received a copy of the GNU General Public License
377+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
378+ */
379+
380+#ifndef USC_CURSOR_IMAGE_ENABLER_H_
381+#define USC_CURSOR_IMAGE_ENABLER_H_
382+
383+#include "mir/input/event_filter.h"
384+
385+#include <memory>
386+#include <chrono>
387+
388+namespace mir
389+{
390+namespace graphics
391+{
392+class Cursor;
393+class CursorImage;
394+}
395+}
396+
397+/*
398+ * Disables the cursor on construction and waits for the first mir pointer/cursor
399+ * event to come by for enabling the cursor again.
400+ */
401+class CursorEnabler : public mir::input::EventFilter
402+{
403+public:
404+ CursorEnabler(std::shared_ptr<mir::graphics::Cursor> const& cursor,
405+ std::chrono::milliseconds remove_pointer_timeout);
406+
407+ ~CursorEnabler();
408+
409+ bool handle(MirEvent const& event) override;
410+
411+private:
412+ void enable_cursor();
413+ void disable_cursor();
414+
415+ bool cursor_shown;
416+ uint32_t remove_delay;
417+ uint32_t last_cursor_movement;
418+ std::shared_ptr<mir::graphics::Cursor> const cursor;
419+};
420+
421+#endif
422
423=== removed file 'src/dbus_connection_handle.cpp'
424--- src/dbus_connection_handle.cpp 2015-03-18 12:20:58 +0000
425+++ src/dbus_connection_handle.cpp 1970-01-01 00:00:00 +0000
426@@ -1,102 +0,0 @@
427-/*
428- * Copyright © 2015 Canonical Ltd.
429- *
430- * This program is free software: you can redistribute it and/or modify
431- * it under the terms of the GNU General Public License version 3 as
432- * published by the Free Software Foundation.
433- *
434- * This program is distributed in the hope that it will be useful,
435- * but WITHOUT ANY WARRANTY; without even the implied warranty of
436- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
437- * GNU General Public License for more details.
438- *
439- * You should have received a copy of the GNU General Public License
440- * along with this program. If not, see <http://www.gnu.org/licenses/>.
441- *
442- * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>
443- */
444-
445-#include "dbus_connection_handle.h"
446-#include "scoped_dbus_error.h"
447-
448-#include <stdexcept>
449-#include <boost/throw_exception.hpp>
450-
451-usc::DBusConnectionHandle::DBusConnectionHandle(const char* address)
452-{
453- dbus_threads_init_default();
454- ScopedDBusError error;
455-
456- connection = dbus_connection_open_private(address, &error);
457- if (!connection || error)
458- {
459- BOOST_THROW_EXCEPTION(
460- std::runtime_error("dbus_connection_open: " + error.message_str()));
461- }
462-
463- if (!dbus_bus_register(connection, &error))
464- {
465- BOOST_THROW_EXCEPTION(
466- std::runtime_error("dbus_bus_register: " + error.message_str()));
467- }
468-}
469-
470-usc::DBusConnectionHandle::~DBusConnectionHandle()
471-{
472- if (dbus_connection_get_is_connected(connection))
473- dbus_connection_close(connection);
474- dbus_connection_unref(connection);
475-}
476-
477-void usc::DBusConnectionHandle::request_name(char const* name) const
478-{
479- ScopedDBusError error;
480-
481- auto const request_result = dbus_bus_request_name(
482- connection, name, DBUS_NAME_FLAG_DO_NOT_QUEUE, &error);
483- if (error)
484- {
485- BOOST_THROW_EXCEPTION(
486- std::runtime_error("dbus_request_name: " + error.message_str()));
487- }
488-
489- if (request_result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
490- {
491- BOOST_THROW_EXCEPTION(
492- std::runtime_error("dbus_request_name: Failed to become primary owner"));
493- }
494-}
495-
496-void usc::DBusConnectionHandle::add_match(char const* match) const
497-{
498- ScopedDBusError error;
499-
500- dbus_bus_add_match(connection, match, &error);
501- if (error)
502- {
503- BOOST_THROW_EXCEPTION(
504- std::runtime_error("dbus_add_match: " + error.message_str()));
505- }
506-}
507-
508-void usc::DBusConnectionHandle::add_filter(
509- DBusHandleMessageFunction filter_func,
510- void* user_data) const
511-{
512- auto const added = dbus_connection_add_filter(
513- connection,
514- filter_func,
515- user_data,
516- nullptr);
517-
518- if (!added)
519- {
520- BOOST_THROW_EXCEPTION(
521- std::runtime_error("dbus_connection_add_filter: Failed to add filter"));
522- }
523-}
524-
525-usc::DBusConnectionHandle::operator ::DBusConnection*() const
526-{
527- return connection;
528-}
529
530=== removed file 'src/dbus_connection_handle.h'
531--- src/dbus_connection_handle.h 2015-03-17 18:17:14 +0000
532+++ src/dbus_connection_handle.h 1970-01-01 00:00:00 +0000
533@@ -1,48 +0,0 @@
534-/*
535- * Copyright © 2015 Canonical Ltd.
536- *
537- * This program is free software: you can redistribute it and/or modify
538- * it under the terms of the GNU General Public License version 3 as
539- * published by the Free Software Foundation.
540- *
541- * This program is distributed in the hope that it will be useful,
542- * but WITHOUT ANY WARRANTY; without even the implied warranty of
543- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
544- * GNU General Public License for more details.
545- *
546- * You should have received a copy of the GNU General Public License
547- * along with this program. If not, see <http://www.gnu.org/licenses/>.
548- *
549- * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>
550- */
551-
552-#ifndef USC_DBUS_CONNECTION_HANDLE_H_
553-#define USC_DBUS_CONNECTION_HANDLE_H_
554-
555-#include <dbus/dbus.h>
556-
557-namespace usc
558-{
559-
560-class DBusConnectionHandle
561-{
562-public:
563- DBusConnectionHandle(char const* address);
564- ~DBusConnectionHandle();
565-
566- void request_name(char const* name) const;
567- void add_match(char const* match) const;
568- void add_filter(DBusHandleMessageFunction filter_func, void* user_data) const;
569-
570- operator ::DBusConnection*() const;
571-
572-private:
573- DBusConnectionHandle(DBusConnectionHandle const&) = delete;
574- DBusConnectionHandle& operator=(DBusConnectionHandle const&) = delete;
575-
576- ::DBusConnection* connection;
577-};
578-
579-}
580-
581-#endif
582
583=== removed file 'src/dbus_event_loop.cpp'
584--- src/dbus_event_loop.cpp 2015-03-18 12:20:58 +0000
585+++ src/dbus_event_loop.cpp 1970-01-01 00:00:00 +0000
586@@ -1,444 +0,0 @@
587-/*
588- * Copyright © 2015 Canonical Ltd.
589- *
590- * This program is free software: you can redistribute it and/or modify
591- * it under the terms of the GNU General Public License version 3 as
592- * published by the Free Software Foundation.
593- *
594- * This program is distributed in the hope that it will be useful,
595- * but WITHOUT ANY WARRANTY; without even the implied warranty of
596- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
597- * GNU General Public License for more details.
598- *
599- * You should have received a copy of the GNU General Public License
600- * along with this program. If not, see <http://www.gnu.org/licenses/>.
601- *
602- * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>
603- */
604-
605-#ifndef _GNU_SOURCE
606-#define _GNU_SOURCE
607-#endif
608-
609-#include "dbus_event_loop.h"
610-
611-#include <algorithm>
612-
613-#include <sys/epoll.h>
614-#include <sys/timerfd.h>
615-#include <unistd.h>
616-#include <fcntl.h>
617-
618-#include <system_error>
619-#include <boost/throw_exception.hpp>
620-
621-namespace
622-{
623-
624-uint32_t dbus_flags_to_epoll_events(DBusWatch* bus_watch)
625-{
626- unsigned int flags;
627- uint32_t events{0};
628-
629- if (!dbus_watch_get_enabled(bus_watch))
630- return 0;
631-
632- flags = dbus_watch_get_flags(bus_watch);
633- if (flags & DBUS_WATCH_READABLE)
634- events |= EPOLLIN;
635- if (flags & DBUS_WATCH_WRITABLE)
636- events |= EPOLLOUT;
637-
638- return events | EPOLLHUP | EPOLLERR;
639-}
640-
641-unsigned int epoll_events_to_dbus_flags(uint32_t events)
642-{
643- unsigned int flags{0};
644-
645- if (events & EPOLLIN)
646- flags |= DBUS_WATCH_READABLE;
647- if (events & EPOLLOUT)
648- flags |= DBUS_WATCH_WRITABLE;
649- if (events & EPOLLHUP)
650- flags |= DBUS_WATCH_HANGUP;
651- if (events & EPOLLERR)
652- flags |= DBUS_WATCH_ERROR;
653-
654- return flags;
655-}
656-
657-timespec msec_to_timespec(int msec)
658-{
659- static long const milli_to_nano = 1000000;
660- time_t const sec = msec / 1000;
661- long const nsec = (msec % 1000) * milli_to_nano;
662- return timespec{sec, nsec};
663-}
664-
665-}
666-
667-usc::DBusEventLoop::DBusEventLoop(DBusConnection* connection)
668- : connection{connection},
669- running{false},
670- epoll_fd{epoll_create1(EPOLL_CLOEXEC)}
671-{
672- if (epoll_fd == -1)
673- {
674- BOOST_THROW_EXCEPTION(
675- std::system_error(errno, std::system_category(), "epoll_create1"));
676- }
677-
678- int pipefd[2]{};
679-
680- if (pipe2(pipefd, O_CLOEXEC) == -1)
681- {
682- BOOST_THROW_EXCEPTION(
683- std::system_error(errno, std::system_category(), "pipe2"));
684-
685- }
686-
687- wake_up_fd_r = mir::Fd{pipefd[0]};
688- wake_up_fd_w = mir::Fd{pipefd[1]};
689-
690- epoll_event ev{};
691- ev.data.fd = wake_up_fd_r;
692- ev.events = EPOLLIN;
693- if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, ev.data.fd, &ev) == -1)
694- {
695- BOOST_THROW_EXCEPTION(
696- std::system_error(errno, std::system_category(), "epoll_ctl"));
697- }
698-
699- dbus_connection_set_watch_functions(
700- connection,
701- DBusEventLoop::static_add_watch,
702- DBusEventLoop::static_remove_watch,
703- DBusEventLoop::static_toggle_watch,
704- this,
705- nullptr);
706-
707- dbus_connection_set_timeout_functions(
708- connection,
709- DBusEventLoop::static_add_timeout,
710- DBusEventLoop::static_remove_timeout,
711- DBusEventLoop::static_toggle_timeout,
712- this,
713- nullptr);
714-
715- dbus_connection_set_wakeup_main_function(
716- connection,
717- DBusEventLoop::static_wake_up_loop,
718- this, nullptr);
719-}
720-
721-usc::DBusEventLoop::~DBusEventLoop()
722-{
723- stop();
724-
725- dbus_connection_set_watch_functions(
726- connection, nullptr, nullptr, nullptr, nullptr, nullptr);
727-
728- dbus_connection_set_timeout_functions(
729- connection, nullptr, nullptr, nullptr, nullptr, nullptr);
730-
731- dbus_connection_set_wakeup_main_function(
732- connection, nullptr, nullptr, nullptr);
733-}
734-
735-void usc::DBusEventLoop::run(std::promise<void>& started)
736-{
737- running = true;
738- started.set_value();
739-
740- while (running)
741- {
742- epoll_event event{};
743- int n = epoll_wait(epoll_fd, &event, 1, -1);
744- if (n == -1)
745- {
746- if (errno == EINTR)
747- continue;
748-
749- BOOST_THROW_EXCEPTION(
750- std::system_error(errno, std::system_category(), "epoll_wait"));
751- }
752-
753- if (event.data.fd == wake_up_fd_r)
754- {
755- char c;
756- if (read(event.data.fd, &c, 1));
757- }
758- else
759- {
760- auto const& matching_watches = enabled_watches_for(event.data.fd);
761- for (auto const& watch : matching_watches)
762- {
763- dbus_watch_handle(watch, epoll_events_to_dbus_flags(event.events));
764- }
765-
766- if (matching_watches.empty())
767- {
768- auto timeout = enabled_timeout_for(event.data.fd);
769- if (timeout)
770- dbus_timeout_handle(timeout);
771- }
772- }
773-
774- dispatch_actions();
775-
776- dbus_connection_flush(connection);
777-
778- while (dbus_connection_dispatch(connection) == DBUS_DISPATCH_DATA_REMAINS)
779- continue;
780- }
781-
782- // Flush any remaining outgoing messages
783- dbus_connection_flush(connection);
784-}
785-
786-void usc::DBusEventLoop::stop()
787-{
788- running = false;
789- wake_up_loop();
790-}
791-
792-std::vector<DBusWatch*> usc::DBusEventLoop::enabled_watches_for(int fd)
793-{
794- std::lock_guard<std::mutex> lock{mutex};
795-
796- std::vector<DBusWatch*> ret_watches;
797-
798- for (auto const& w : watches)
799- {
800- if (dbus_watch_get_unix_fd(w) == fd &&
801- dbus_watch_get_enabled(w))
802- {
803- ret_watches.push_back(w);
804- }
805- }
806-
807- return ret_watches;
808-}
809-
810-DBusTimeout* usc::DBusEventLoop::enabled_timeout_for(int fd)
811-{
812- std::lock_guard<std::mutex> lock{mutex};
813-
814- for (auto const& p : timeouts)
815- {
816- if (p.second == fd && dbus_timeout_get_enabled(p.first))
817- return p.first;
818- }
819-
820- return nullptr;
821-}
822-
823-dbus_bool_t usc::DBusEventLoop::add_watch(DBusWatch* watch)
824-{
825- std::lock_guard<std::mutex> lock{mutex};
826-
827- int const watch_fd = dbus_watch_get_unix_fd(watch);
828-
829- if (!is_watched(watch_fd))
830- {
831- epoll_event ev{};
832- ev.data.fd = watch_fd;
833- if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, watch_fd, &ev) == -1)
834- return FALSE;
835- }
836-
837- watches.push_back(watch);
838-
839- update_events_for_watch_fd(watch_fd);
840-
841- return TRUE;
842-}
843-
844-void usc::DBusEventLoop::remove_watch(DBusWatch* watch)
845-{
846- std::lock_guard<std::mutex> lock{mutex};
847-
848- watches.erase(std::remove(begin(watches), end(watches), watch), end(watches));
849-
850- int const watch_fd = dbus_watch_get_unix_fd(watch);
851- if (!is_watched(watch_fd))
852- epoll_ctl(epoll_fd, EPOLL_CTL_DEL, watch_fd, nullptr);
853- else
854- update_events_for_watch_fd(watch_fd);
855-}
856-
857-void usc::DBusEventLoop::toggle_watch(DBusWatch* watch)
858-{
859- std::lock_guard<std::mutex> lock{mutex};
860-
861- int const watch_fd = dbus_watch_get_unix_fd(watch);
862- update_events_for_watch_fd(watch_fd);
863-}
864-
865-void usc::DBusEventLoop::update_events_for_watch_fd(int watch_fd)
866-{
867- epoll_event ev{};
868- ev.events = epoll_events_for_watch_fd(watch_fd);
869- ev.data.fd = watch_fd;
870- epoll_ctl(epoll_fd, EPOLL_CTL_MOD, watch_fd, &ev);
871-}
872-
873-bool usc::DBusEventLoop::is_watched(int watch_fd)
874-{
875- auto const iter = std::find_if(
876- begin(watches), end(watches),
877- [watch_fd] (DBusWatch* w) { return dbus_watch_get_unix_fd(w) == watch_fd; });
878-
879- return iter != end(watches);
880-}
881-
882-uint32_t usc::DBusEventLoop::epoll_events_for_watch_fd(int fd)
883-{
884- uint32_t events{};
885-
886- for (auto const& watch : watches)
887- {
888- if (dbus_watch_get_unix_fd(watch) == fd)
889- events |= dbus_flags_to_epoll_events(watch);
890- }
891-
892- return events;
893-}
894-
895-dbus_bool_t usc::DBusEventLoop::add_timeout(DBusTimeout* timeout)
896-{
897- std::lock_guard<std::mutex> lock{mutex};
898-
899- auto tfd = mir::Fd{timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC)};
900-
901- epoll_event ev{};
902- ev.events = EPOLLIN;
903- ev.data.fd = tfd;
904-
905- if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, tfd, &ev))
906- return FALSE;
907-
908- timeouts.emplace_back(timeout, std::move(tfd));
909-
910- return update_timer_fd_for(timeout);
911-}
912-
913-void usc::DBusEventLoop::remove_timeout(DBusTimeout* timeout)
914-{
915- std::lock_guard<std::mutex> lock{mutex};
916-
917- auto tfd = timer_fd_for(timeout);
918- epoll_ctl(epoll_fd, EPOLL_CTL_DEL, tfd, nullptr);
919-
920- timeouts.erase(
921- std::remove_if(begin(timeouts), end(timeouts),
922- [timeout] (decltype(timeouts)::const_reference p)
923- {
924- return p.first == timeout;
925- }),
926- end(timeouts));
927-
928-}
929-
930-void usc::DBusEventLoop::toggle_timeout(DBusTimeout* timeout)
931-{
932- std::lock_guard<std::mutex> lock{mutex};
933- update_timer_fd_for(timeout);
934-}
935-
936-
937-dbus_bool_t usc::DBusEventLoop::update_timer_fd_for(DBusTimeout* timeout)
938-{
939- itimerspec spec{};
940-
941- auto tfd = timer_fd_for(timeout);
942-
943- if (dbus_timeout_get_enabled(timeout))
944- {
945- spec.it_interval = msec_to_timespec(dbus_timeout_get_interval(timeout));
946- spec.it_value = spec.it_interval;
947- }
948-
949- if (timerfd_settime(tfd, 0, &spec, nullptr) == -1)
950- return FALSE;
951-
952- return TRUE;
953-}
954-
955-int usc::DBusEventLoop::timer_fd_for(DBusTimeout* timeout)
956-{
957- auto iter = std::find_if(begin(timeouts), end(timeouts),
958- [timeout] (std::pair<DBusTimeout*,int> const& p)
959- {
960- return p.first == timeout;
961- });
962- return (iter == end(timeouts) ? -1 : iter->second);
963-}
964-
965-void usc::DBusEventLoop::wake_up_loop()
966-{
967- if (write(wake_up_fd_w, "a", 1) != 1)
968- {
969- BOOST_THROW_EXCEPTION(
970- std::system_error(errno, std::system_category(), "write"));
971- }
972-}
973-
974-void usc::DBusEventLoop::enqueue(std::function<void()> const& action)
975-{
976- {
977- std::lock_guard<std::mutex> lock{mutex};
978- actions.push_back(action);
979- }
980-
981- wake_up_loop();
982-}
983-
984-void usc::DBusEventLoop::dispatch_actions()
985-{
986- decltype(actions) actions_to_dispatch;
987-
988- {
989- std::lock_guard<std::mutex> lock{mutex};
990- actions.swap(actions_to_dispatch);
991- }
992-
993- for (auto const& action : actions_to_dispatch)
994- action();
995-}
996-
997-dbus_bool_t usc::DBusEventLoop::static_add_watch(DBusWatch* watch, void* data)
998-{
999- return static_cast<DBusEventLoop*>(data)->add_watch(watch);
1000-}
1001-
1002-void usc::DBusEventLoop::static_remove_watch(DBusWatch* watch, void* data)
1003-{
1004- static_cast<DBusEventLoop*>(data)->remove_watch(watch);
1005-}
1006-
1007-void usc::DBusEventLoop::static_toggle_watch(DBusWatch* watch, void* data)
1008-{
1009- static_cast<DBusEventLoop*>(data)->toggle_watch(watch);
1010-}
1011-
1012-dbus_bool_t usc::DBusEventLoop::static_add_timeout(DBusTimeout* timeout, void* data)
1013-{
1014- return static_cast<DBusEventLoop*>(data)->add_timeout(timeout);
1015-}
1016-
1017-void usc::DBusEventLoop::static_remove_timeout(DBusTimeout* timeout, void* data)
1018-{
1019- static_cast<DBusEventLoop*>(data)->remove_timeout(timeout);
1020-}
1021-
1022-void usc::DBusEventLoop::static_toggle_timeout(DBusTimeout* timeout, void* data)
1023-{
1024- static_cast<DBusEventLoop*>(data)->toggle_timeout(timeout);
1025-}
1026-
1027-void usc::DBusEventLoop::static_wake_up_loop(void* data)
1028-{
1029- static_cast<DBusEventLoop*>(data)->wake_up_loop();
1030-}
1031
1032=== removed file 'src/dbus_event_loop.h'
1033--- src/dbus_event_loop.h 2015-03-18 11:56:28 +0000
1034+++ src/dbus_event_loop.h 1970-01-01 00:00:00 +0000
1035@@ -1,87 +0,0 @@
1036-/*
1037- * Copyright © 2015 Canonical Ltd.
1038- *
1039- * This program is free software: you can redistribute it and/or modify
1040- * it under the terms of the GNU General Public License version 3 as
1041- * published by the Free Software Foundation.
1042- *
1043- * This program is distributed in the hope that it will be useful,
1044- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1045- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1046- * GNU General Public License for more details.
1047- *
1048- * You should have received a copy of the GNU General Public License
1049- * along with this program. If not, see <http://www.gnu.org/licenses/>.
1050- *
1051- * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>
1052- */
1053-
1054-#ifndef USC_DBUS_EVENT_LOOP_H_
1055-#define USC_DBUS_EVENT_LOOP_H_
1056-
1057-#include <mir/fd.h>
1058-
1059-#include <dbus/dbus.h>
1060-
1061-#include <atomic>
1062-#include <vector>
1063-#include <mutex>
1064-#include <future>
1065-
1066-namespace usc
1067-{
1068-
1069-class DBusEventLoop
1070-{
1071-public:
1072- DBusEventLoop(DBusConnection* connection);
1073- ~DBusEventLoop();
1074-
1075- void run(std::promise<void>& started);
1076- void stop();
1077-
1078- void enqueue(std::function<void()> const& action);
1079-
1080-private:
1081- std::vector<DBusWatch*> enabled_watches_for(int fd);
1082- DBusTimeout* enabled_timeout_for(int fd);
1083-
1084- dbus_bool_t add_watch(DBusWatch* watch);
1085- void remove_watch(DBusWatch* watch);
1086- void toggle_watch(DBusWatch* watch);
1087- void update_events_for_watch_fd(int watch_fd);
1088- bool is_watched(int watch_fd);
1089- uint32_t epoll_events_for_watch_fd(int watch_fd);
1090-
1091- dbus_bool_t add_timeout(DBusTimeout* timeout);
1092- void remove_timeout(DBusTimeout* timeout);
1093- void toggle_timeout(DBusTimeout* timeout);
1094- dbus_bool_t update_timer_fd_for(DBusTimeout* timeout);
1095- int timer_fd_for(DBusTimeout* timeout);
1096-
1097- void wake_up_loop();
1098- void dispatch_actions();
1099-
1100- static dbus_bool_t static_add_watch(DBusWatch* watch, void* data);
1101- static void static_remove_watch(DBusWatch* watch, void* data);
1102- static void static_toggle_watch(DBusWatch* watch, void* data);
1103- static dbus_bool_t static_add_timeout(DBusTimeout* timeout, void* data);
1104- static void static_remove_timeout(DBusTimeout* timeout, void* data);
1105- static void static_toggle_timeout(DBusTimeout* timeout, void* data);
1106- static void static_wake_up_loop(void* data);
1107-
1108- DBusConnection* const connection;
1109- std::atomic<bool> running;
1110-
1111- std::mutex mutex;
1112- std::vector<DBusWatch*> watches;
1113- std::vector<std::pair<DBusTimeout*,mir::Fd>> timeouts;
1114- std::vector<std::function<void(void)>> actions;
1115- mir::Fd epoll_fd;
1116- mir::Fd wake_up_fd_r;
1117- mir::Fd wake_up_fd_w;
1118-};
1119-
1120-}
1121-
1122-#endif
1123
1124=== removed file 'src/dbus_message_handle.cpp'
1125--- src/dbus_message_handle.cpp 2015-03-18 12:20:58 +0000
1126+++ src/dbus_message_handle.cpp 1970-01-01 00:00:00 +0000
1127@@ -1,83 +0,0 @@
1128-/*
1129- * Copyright © 2015 Canonical Ltd.
1130- *
1131- * This program is free software: you can redistribute it and/or modify
1132- * it under the terms of the GNU General Public License version 3 as
1133- * published by the Free Software Foundation.
1134- *
1135- * This program is distributed in the hope that it will be useful,
1136- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1137- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1138- * GNU General Public License for more details.
1139- *
1140- * You should have received a copy of the GNU General Public License
1141- * along with this program. If not, see <http://www.gnu.org/licenses/>.
1142- *
1143- * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>
1144- */
1145-
1146-#include "dbus_message_handle.h"
1147-
1148-#include <stdexcept>
1149-#include <boost/throw_exception.hpp>
1150-
1151-usc::DBusMessageHandle::DBusMessageHandle(DBusMessage* message)
1152- : message{message}
1153-{
1154-}
1155-
1156-usc::DBusMessageHandle::DBusMessageHandle(::DBusMessage* message, int first_arg_type, ...)
1157- : message{message}
1158-{
1159- if (!message)
1160- BOOST_THROW_EXCEPTION(std::runtime_error("Invalid dbus message"));
1161-
1162- va_list args;
1163- va_start(args, first_arg_type);
1164- auto appended = dbus_message_append_args_valist(message, first_arg_type, args);
1165- va_end(args);
1166-
1167- if (!appended)
1168- {
1169- dbus_message_unref(message);
1170- BOOST_THROW_EXCEPTION(
1171- std::runtime_error("dbus_message_append_args_valist: Failed to append args"));
1172- }
1173-}
1174-
1175-usc::DBusMessageHandle::DBusMessageHandle(
1176- ::DBusMessage* message, int first_arg_type, va_list args)
1177- : message{message}
1178-{
1179- if (!message)
1180- BOOST_THROW_EXCEPTION(std::runtime_error("Invalid dbus message"));
1181-
1182- if (!dbus_message_append_args_valist(message, first_arg_type, args))
1183- {
1184- dbus_message_unref(message);
1185- BOOST_THROW_EXCEPTION(
1186- std::runtime_error("dbus_message_append_args_valist: Failed to append args"));
1187- }
1188-}
1189-
1190-usc::DBusMessageHandle::DBusMessageHandle(DBusMessageHandle&& other) noexcept
1191- : message{other.message}
1192-{
1193- other.message = nullptr;
1194-}
1195-
1196-usc::DBusMessageHandle::~DBusMessageHandle()
1197-{
1198- if (message)
1199- dbus_message_unref(message);
1200-}
1201-
1202-usc::DBusMessageHandle::operator ::DBusMessage*() const
1203-{
1204- return message;
1205-}
1206-
1207-usc::DBusMessageHandle::operator bool() const
1208-{
1209- return message != nullptr;
1210-}
1211
1212=== removed file 'src/dbus_message_handle.h'
1213--- src/dbus_message_handle.h 2015-03-18 12:20:58 +0000
1214+++ src/dbus_message_handle.h 1970-01-01 00:00:00 +0000
1215@@ -1,48 +0,0 @@
1216-/*
1217- * Copyright © 2015 Canonical Ltd.
1218- *
1219- * This program is free software: you can redistribute it and/or modify
1220- * it under the terms of the GNU General Public License version 3 as
1221- * published by the Free Software Foundation.
1222- *
1223- * This program is distributed in the hope that it will be useful,
1224- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1225- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1226- * GNU General Public License for more details.
1227- *
1228- * You should have received a copy of the GNU General Public License
1229- * along with this program. If not, see <http://www.gnu.org/licenses/>.
1230- *
1231- * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>
1232- */
1233-
1234-#ifndef USC_DBUS_MESSAGE_HANDLE_H_
1235-#define USC_DBUS_MESSAGE_HANDLE_H_
1236-
1237-#include <dbus/dbus.h>
1238-#include <cstdarg>
1239-
1240-namespace usc
1241-{
1242-
1243-class DBusMessageHandle
1244-{
1245-public:
1246- DBusMessageHandle(DBusMessage* message);
1247- DBusMessageHandle(DBusMessage* message, int first_arg_type, ...);
1248- DBusMessageHandle(DBusMessage* message, int first_arg_type, va_list args);
1249- DBusMessageHandle(DBusMessageHandle&&) noexcept;
1250- ~DBusMessageHandle();
1251-
1252- operator ::DBusMessage*() const;
1253- operator bool() const;
1254-
1255-private:
1256- DBusMessageHandle(DBusMessageHandle const&) = delete;
1257- DBusMessageHandle& operator=(DBusMessageHandle const&) = delete;
1258- ::DBusMessage* message;
1259-};
1260-
1261-}
1262-
1263-#endif
1264
1265=== added file 'src/dbus_screen.cpp'
1266--- src/dbus_screen.cpp 1970-01-01 00:00:00 +0000
1267+++ src/dbus_screen.cpp 2015-05-12 16:45:46 +0000
1268@@ -0,0 +1,213 @@
1269+/*
1270+ * Copyright © 2013-2014 Canonical Ltd.
1271+ *
1272+ * This program is free software: you can redistribute it and/or modify
1273+ * it under the terms of the GNU General Public License version 3 as
1274+ * published by the Free Software Foundation.
1275+ *
1276+ * This program is distributed in the hope that it will be useful,
1277+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1278+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1279+ * GNU General Public License for more details.
1280+ *
1281+ * You should have received a copy of the GNU General Public License
1282+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1283+ */
1284+
1285+#include "dbus_screen.h"
1286+#include "dbus_screen_adaptor.h"
1287+#include "dbus_screen_observer.h"
1288+#include "power_state_change_reason.h"
1289+#include "worker_thread.h"
1290+
1291+#include <atomic>
1292+#include <memory>
1293+#include <thread>
1294+#include <iostream>
1295+
1296+#include <QDBusMessage>
1297+#include <QDBusConnection>
1298+#include <QDBusServiceWatcher>
1299+#include <QDebug>
1300+
1301+namespace
1302+{
1303+bool is_valid_reason(int raw_reason)
1304+{
1305+ auto reason = static_cast<PowerStateChangeReason>(raw_reason);
1306+ switch (reason)
1307+ {
1308+ case PowerStateChangeReason::unknown:
1309+ case PowerStateChangeReason::inactivity:
1310+ case PowerStateChangeReason::power_key:
1311+ case PowerStateChangeReason::proximity:
1312+ return true;
1313+ }
1314+ return false;
1315+}
1316+
1317+enum DBusHandlerTaskId
1318+{
1319+ set_power_mode
1320+};
1321+}
1322+
1323+
1324+DBusScreen::DBusScreen(DBusScreenObserver& observer, QObject *parent)
1325+ : QObject(parent),
1326+ dbus_adaptor{new DBusScreenAdaptor(this)},
1327+ service_watcher{new QDBusServiceWatcher()},
1328+ observer{&observer},
1329+ worker_thread{new usc::WorkerThread("USC/DBusHandler")}
1330+{
1331+ QDBusConnection bus = QDBusConnection::systemBus();
1332+ bus.registerObject("/com/canonical/Unity/Screen", this);
1333+ bus.registerService("com.canonical.Unity.Screen");
1334+
1335+ service_watcher->setConnection(bus);
1336+ service_watcher->setWatchMode(QDBusServiceWatcher::WatchForUnregistration);
1337+
1338+ connect(service_watcher.get(),
1339+ SIGNAL(serviceUnregistered(QString const&)),
1340+ this, SLOT(remove_display_on_requestor(QString const&)));
1341+
1342+ //QT's ~QObject will release this child object
1343+ //so release ownership from the unique_ptr
1344+ dbus_adaptor.release();
1345+}
1346+
1347+DBusScreen::~DBusScreen() = default;
1348+
1349+bool DBusScreen::setScreenPowerMode(const QString &mode, int reason)
1350+{
1351+ if (!is_valid_reason(reason))
1352+ return false;
1353+
1354+ MirPowerMode newPowerMode;
1355+
1356+ // Note: the "standby" and "suspend" modes are mostly unused
1357+ if (mode == "on") {
1358+ newPowerMode = MirPowerMode::mir_power_mode_on;
1359+ } else if (mode == "standby") {
1360+ newPowerMode = MirPowerMode::mir_power_mode_standby; // higher power "off" mode (fastest resume)
1361+ } else if (mode == "suspend") {
1362+ newPowerMode = MirPowerMode::mir_power_mode_suspend; // medium power "off" mode
1363+ } else if (mode == "off") {
1364+ newPowerMode = MirPowerMode::mir_power_mode_off; // lowest power "off" mode (slowest resume)
1365+ } else {
1366+ qWarning() << "DBusScreen: unknown mode type" << mode;
1367+ return false;
1368+ }
1369+
1370+ //This call may block - avoid blocking this dbus handling thread
1371+ worker_thread->queue_task([this, newPowerMode, reason]{
1372+ observer->set_screen_power_mode(newPowerMode, static_cast<PowerStateChangeReason>(reason));
1373+ }, DBusHandlerTaskId::set_power_mode);
1374+
1375+ return true;
1376+}
1377+
1378+void DBusScreen::emit_power_state_change(MirPowerMode power_mode, PowerStateChangeReason reason)
1379+{
1380+ QDBusMessage message = QDBusMessage::createSignal("/com/canonical/Unity/Screen",
1381+ "com.canonical.Unity.Screen", "DisplayPowerStateChange");
1382+
1383+ int power_state = (power_mode == MirPowerMode::mir_power_mode_off) ? 0 : 1;
1384+
1385+ QVariant state(power_state);
1386+ QList<QVariant> arguments;
1387+ arguments.append(state);
1388+ arguments.append(static_cast<int>(reason));
1389+ message.setArguments(arguments);
1390+
1391+ QDBusConnection bus = QDBusConnection::systemBus();
1392+ bus.send(message);
1393+}
1394+
1395+int DBusScreen::keepDisplayOn()
1396+{
1397+ static std::atomic<uint32_t> request_id{0};
1398+
1399+ int id = request_id.fetch_add(1);
1400+ auto const& caller = message().service();
1401+
1402+ worker_thread->queue_task([this, id, caller]{
1403+ std::lock_guard<decltype(guard)> lock{guard};
1404+
1405+ //Check that the owner of the request is still valid
1406+ auto system_bus_if = QDBusConnection::systemBus().interface();
1407+ QDBusReply<QString> reply = system_bus_if->serviceOwner(caller);
1408+ if (!reply.isValid())
1409+ return;
1410+
1411+ auto& caller_requests = display_requests[caller.toStdString()];
1412+
1413+ if (caller_requests.size() == 0)
1414+ service_watcher->addWatchedService(caller);
1415+
1416+ caller_requests.insert(id);
1417+
1418+ //This call may block so it needs to be executed outside the thread
1419+ //that received the dbus call
1420+ observer->keep_display_on(true);
1421+
1422+ std::cout << "keepDisplayOn request id:" << id;
1423+ std::cout << " requested by \"" << caller.toStdString() << "\"" << std::endl;
1424+ });
1425+ return id;
1426+}
1427+
1428+void DBusScreen::removeDisplayOnRequest(int cookie)
1429+{
1430+ std::lock_guard<decltype(guard)> lock{guard};
1431+ auto const& requestor = message().service();
1432+
1433+ auto it = display_requests.find(requestor.toStdString());
1434+ if (it == display_requests.end())
1435+ return;
1436+
1437+ std::cout << "removeDisplayOnRequest id:" << cookie;
1438+ std::cout << " requested by \"" << requestor.toStdString() << "\"" << std::endl;
1439+
1440+ auto& caller_requests = it->second;
1441+ caller_requests.erase(cookie);
1442+ if (caller_requests.size() == 0)
1443+ remove_requestor(requestor, lock);
1444+}
1445+
1446+void DBusScreen::remove_display_on_requestor(QString const& requestor)
1447+{
1448+ std::lock_guard<decltype(guard)> lock{guard};
1449+ remove_requestor(requestor, lock);
1450+}
1451+
1452+void DBusScreen::remove_requestor(QString const& requestor, std::lock_guard<std::mutex> const&)
1453+{
1454+ std::cout << "remove_display_on_requestor \"" << requestor.toStdString() << "\"";
1455+ std::cout << std::endl;
1456+
1457+ display_requests.erase(requestor.toStdString());
1458+ service_watcher->removeWatchedService(requestor);
1459+ if (display_requests.size() == 0)
1460+ observer->keep_display_on(false);
1461+}
1462+
1463+void DBusScreen::setUserBrightness(int brightness)
1464+{
1465+ observer->set_brightness(brightness);
1466+}
1467+
1468+void DBusScreen::userAutobrightnessEnable(bool enable)
1469+{
1470+ observer->enable_auto_brightness(enable);
1471+}
1472+
1473+void DBusScreen::setInactivityTimeouts(int poweroff_timeout, int dimmer_timeout)
1474+{
1475+ observer->set_inactivity_timeouts(poweroff_timeout, dimmer_timeout);
1476+}
1477+
1478+void DBusScreen::setTouchVisualizationEnabled(bool enabled)
1479+{
1480+ observer->set_touch_visualization_enabled(enabled);
1481+}
1482
1483=== added file 'src/dbus_screen.h'
1484--- src/dbus_screen.h 1970-01-01 00:00:00 +0000
1485+++ src/dbus_screen.h 2015-05-12 16:45:46 +0000
1486@@ -0,0 +1,77 @@
1487+/*
1488+ * Copyright © 2013-2014 Canonical Ltd.
1489+ *
1490+ * This program is free software: you can redistribute it and/or modify
1491+ * it under the terms of the GNU General Public License version 3 as
1492+ * published by the Free Software Foundation.
1493+ *
1494+ * This program is distributed in the hope that it will be useful,
1495+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1496+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1497+ * GNU General Public License for more details.
1498+ *
1499+ * You should have received a copy of the GNU General Public License
1500+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1501+ */
1502+
1503+#ifndef DBUS_SCREEN_H_
1504+#define DBUS_SCREEN_H_
1505+
1506+#include <mir_toolkit/common.h>
1507+
1508+#include <memory>
1509+#include <mutex>
1510+#include <unordered_map>
1511+#include <unordered_set>
1512+
1513+#include <QObject>
1514+#include <QtCore>
1515+#include <QDBusContext>
1516+
1517+namespace usc {class WorkerThread;}
1518+
1519+class DBusScreenAdaptor;
1520+class DBusScreenObserver;
1521+class QDBusInterface;
1522+class QDBusServiceWatcher;
1523+enum class PowerStateChangeReason;
1524+
1525+class DBusScreen : public QObject, protected QDBusContext
1526+{
1527+ Q_OBJECT
1528+ Q_CLASSINFO("D-Bus Interface", "com.canonical.Unity.Screen")
1529+
1530+public:
1531+ explicit DBusScreen(DBusScreenObserver& observer, QObject *parent = 0);
1532+ virtual ~DBusScreen();
1533+
1534+ void emit_power_state_change(MirPowerMode mode, PowerStateChangeReason reason);
1535+
1536+public Q_SLOTS:
1537+ bool setScreenPowerMode(const QString &mode, int reason);
1538+ int keepDisplayOn();
1539+ void removeDisplayOnRequest(int id);
1540+
1541+ //TODO: Expose same DBus powerd interface for now
1542+ void setUserBrightness(int brightness);
1543+ void userAutobrightnessEnable(bool enable);
1544+
1545+ void setInactivityTimeouts(int poweroff_timeout, int dimmer_timeout);
1546+
1547+ void setTouchVisualizationEnabled(bool enabled);
1548+
1549+private Q_SLOTS:
1550+ void remove_display_on_requestor(QString const& requestor);
1551+
1552+private:
1553+ void remove_requestor(QString const& requestor, std::lock_guard<std::mutex> const& lock);
1554+
1555+ std::mutex guard;
1556+ std::unique_ptr<DBusScreenAdaptor> dbus_adaptor;
1557+ std::unique_ptr<QDBusServiceWatcher> service_watcher;
1558+ std::unordered_map<std::string, std::unordered_set<int>> display_requests;
1559+ DBusScreenObserver* const observer;
1560+ std::unique_ptr<usc::WorkerThread> worker_thread;
1561+};
1562+
1563+#endif /* DBUS_SCREEN_H_ */
1564
1565=== renamed file 'src/screen.h' => 'src/dbus_screen_observer.h'
1566--- src/screen.h 2015-02-18 14:40:29 +0000
1567+++ src/dbus_screen_observer.h 2015-05-12 16:45:46 +0000
1568@@ -1,5 +1,5 @@
1569 /*
1570- * Copyright © 2014-2015 Canonical Ltd.
1571+ * Copyright © 2014 Canonical Ltd.
1572 *
1573 * This program is free software: you can redistribute it and/or modify
1574 * it under the terms of the GNU General Public License version 3 as
1575@@ -14,44 +14,27 @@
1576 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1577 */
1578
1579-#ifndef USC_SCREEN_H_
1580-#define USC_SCREEN_H_
1581-
1582-#include <mir_toolkit/common.h>
1583-#include <functional>
1584+#ifndef DBUS_SCREEN_OBSERVER_H_
1585+#define DBUS_SCREEN_OBSERVER_H_
1586
1587 enum class PowerStateChangeReason;
1588
1589-namespace usc
1590-{
1591-
1592-using PowerStateChangeHandler = std::function<void(MirPowerMode, PowerStateChangeReason)>;
1593-
1594-class Screen
1595+class DBusScreenObserver
1596 {
1597 public:
1598- virtual ~Screen() = default;
1599-
1600- virtual void enable_inactivity_timers(bool enable) = 0;
1601- virtual void toggle_screen_power_mode(PowerStateChangeReason reason) = 0;
1602- virtual void keep_display_on_temporarily() = 0;
1603+ virtual ~DBusScreenObserver() = default;
1604
1605 virtual void set_screen_power_mode(MirPowerMode mode, PowerStateChangeReason reason) = 0;
1606 virtual void keep_display_on(bool on) = 0;
1607 virtual void set_brightness(int brightness) = 0;
1608 virtual void enable_auto_brightness(bool enable) = 0;
1609- virtual void set_inactivity_timeouts(int power_off_timeout, int dimmer_timeout) = 0;
1610-
1611+ virtual void set_inactivity_timeouts(int poweroff_timeout, int dimmer_timeout) = 0;
1612 virtual void set_touch_visualization_enabled(bool enabled) = 0;
1613- virtual void register_power_state_change_handler(
1614- PowerStateChangeHandler const& handler) = 0;
1615
1616 protected:
1617- Screen() = default;
1618- Screen(Screen const&) = delete;
1619- Screen& operator=(Screen const&) = delete;
1620+ DBusScreenObserver() = default;
1621+ DBusScreenObserver(const DBusScreenObserver&) = delete;
1622+ DBusScreenObserver& operator=(const DBusScreenObserver&) = delete;
1623 };
1624
1625-}
1626-
1627 #endif
1628
1629=== modified file 'src/external_spinner.cpp'
1630--- src/external_spinner.cpp 2015-04-01 17:06:16 +0000
1631+++ src/external_spinner.cpp 2015-05-12 16:45:46 +0000
1632@@ -18,15 +18,11 @@
1633
1634 #include "external_spinner.h"
1635
1636-#include <unistd.h>
1637-#include <signal.h>
1638-
1639 usc::ExternalSpinner::ExternalSpinner(
1640 std::string const& executable,
1641 std::string const& mir_socket)
1642 : executable{executable},
1643- mir_socket{mir_socket},
1644- spinner_pid{0}
1645+ mir_socket{mir_socket}
1646 {
1647 }
1648
1649@@ -37,37 +33,22 @@
1650
1651 void usc::ExternalSpinner::ensure_running()
1652 {
1653- std::lock_guard<std::mutex> lock{mutex};
1654-
1655- if (executable.empty() || spinner_pid)
1656+ if (executable.empty() || process.state() != QProcess::NotRunning)
1657 return;
1658
1659- auto pid = fork();
1660- if (!pid)
1661- {
1662- setenv("MIR_SOCKET", mir_socket.c_str(), 1);
1663- execlp(executable.c_str(), executable.c_str(), nullptr);
1664- }
1665- else
1666- {
1667- spinner_pid = pid;
1668- }
1669+ // Launch spinner process to provide default background when a session isn't ready
1670+ QStringList env = QProcess::systemEnvironment();
1671+ env << "MIR_SOCKET=" + QString::fromStdString(mir_socket);
1672+ process.setEnvironment(env);
1673+ process.start(executable.c_str());
1674 }
1675
1676 void usc::ExternalSpinner::kill()
1677 {
1678- std::lock_guard<std::mutex> lock{mutex};
1679-
1680- if (spinner_pid)
1681- {
1682- ::kill(spinner_pid, SIGTERM);
1683- spinner_pid = 0;
1684- }
1685+ process.close();
1686 }
1687
1688 pid_t usc::ExternalSpinner::pid()
1689 {
1690- std::lock_guard<std::mutex> lock{mutex};
1691-
1692- return spinner_pid;
1693+ return process.processId();
1694 }
1695
1696=== modified file 'src/external_spinner.h'
1697--- src/external_spinner.h 2015-04-01 17:06:16 +0000
1698+++ src/external_spinner.h 2015-05-12 16:45:46 +0000
1699@@ -21,9 +21,8 @@
1700
1701 #include "spinner.h"
1702
1703+#include <QProcess>
1704 #include <string>
1705-#include <sys/types.h>
1706-#include <mutex>
1707
1708 namespace usc
1709 {
1710@@ -42,8 +41,7 @@
1711 private:
1712 std::string const executable;
1713 std::string const mir_socket;
1714- std::mutex mutex;
1715- pid_t spinner_pid;
1716+ QProcess process;
1717 };
1718
1719 }
1720
1721=== removed file 'src/generate_header_with_string_from_file.sh'
1722--- src/generate_header_with_string_from_file.sh 2015-03-18 13:06:10 +0000
1723+++ src/generate_header_with_string_from_file.sh 1970-01-01 00:00:00 +0000
1724@@ -1,26 +0,0 @@
1725-# Copyright © 2015 Canonical Ltd.
1726-#
1727-# This program is free software: you can redistribute it and/or modify
1728-# it under the terms of the GNU General Public License version 3 as
1729-# published by the Free Software Foundation.
1730-#
1731-# This program is distributed in the hope that it will be useful,
1732-# but WITHOUT ANY WARRANTY; without even the implied warranty of
1733-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1734-# GNU General Public License for more details.
1735-#
1736-# You should have received a copy of the GNU General Public License
1737-# along with this program. If not, see <http://www.gnu.org/licenses/>.
1738-#
1739-# Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>
1740-
1741-header=$1
1742-varname=$2
1743-filename=$3
1744-
1745-header_guard=$(echo "USC_$(basename $header)_" | tr '[a-z].' '[A-Z]_')
1746-
1747-echo "#ifndef $header_guard
1748-#define $header_guard
1749-const char* const $varname = R\"($(cat $filename))\";
1750-#endif" > $header
1751
1752=== modified file 'src/powerd_mediator.cpp'
1753--- src/powerd_mediator.cpp 2015-04-24 14:40:28 +0000
1754+++ src/powerd_mediator.cpp 2015-05-12 16:45:46 +0000
1755@@ -1,5 +1,5 @@
1756 /*
1757- * Copyright © 2015 Canonical Ltd.
1758+ * Copyright © 2014 Canonical Ltd.
1759 *
1760 * This program is free software: you can redistribute it and/or modify
1761 * it under the terms of the GNU General Public License version 3 as
1762@@ -15,253 +15,163 @@
1763 */
1764
1765 #include "powerd_mediator.h"
1766-#include "thread_name.h"
1767-#include "scoped_dbus_error.h"
1768-
1769-#include "dbus_message_handle.h"
1770-
1771-#include <future>
1772-#include <cstdint>
1773-
1774-namespace
1775-{
1776-
1777-char const* const powerd_service_name = "com.canonical.powerd";
1778-char const* const powerd_service_interface = "com.canonical.powerd";
1779-char const* const powerd_service_path = "/com/canonical/powerd";
1780-
1781-usc::DBusMessageHandle make_powerd_method_call_message(
1782- char const* method, int first_arg_type, va_list args)
1783-{
1784- return usc::DBusMessageHandle{
1785- dbus_message_new_method_call(
1786- powerd_service_name,
1787- powerd_service_path,
1788- powerd_service_interface,
1789- method),
1790- first_arg_type, args};
1791-}
1792-
1793-}
1794-
1795-usc::PowerdMediator::PowerdMediator(std::string const& bus_addr)
1796- : connection{bus_addr.c_str()},
1797- dbus_event_loop{connection},
1798- pending_suspend_block_request{false},
1799- dim_brightness_{10},
1800- min_brightness_{0},
1801+
1802+#include <QDBusConnection>
1803+#include <QDBusInterface>
1804+#include <QDBusReply>
1805+#include <QDBusMetaType>
1806+#include <QDBusArgument>
1807+#include <QDBusServiceWatcher>
1808+
1809+#include <iostream>
1810+
1811+/* Struct for reply to getBrightnessParams DBus call */
1812+struct BrightnessParams
1813+ {
1814+ int dim_brightness;
1815+ int min_brightness;
1816+ int max_brightness;
1817+ int default_brightness;
1818+ bool auto_brightness_supported;
1819+};
1820+Q_DECLARE_METATYPE(BrightnessParams);
1821+
1822+/* Not used but required by qDBusRegisterMetaType*/
1823+QDBusArgument &operator<<(QDBusArgument &argument, const BrightnessParams &mystruct)
1824+{
1825+ argument.beginStructure();
1826+ argument << mystruct.dim_brightness <<
1827+ mystruct.min_brightness <<
1828+ mystruct.max_brightness <<
1829+ mystruct.default_brightness <<
1830+ mystruct.auto_brightness_supported;
1831+ argument.endStructure();
1832+ return argument;
1833+}
1834+
1835+/* Needed to un-marshall powerd response */
1836+const QDBusArgument &operator>>(const QDBusArgument &argument, BrightnessParams &mystruct)
1837+{
1838+ argument.beginStructure();
1839+ argument >> mystruct.dim_brightness >>
1840+ mystruct.min_brightness >>
1841+ mystruct.max_brightness >>
1842+ mystruct.default_brightness >>
1843+ mystruct.auto_brightness_supported;
1844+ argument.endStructure();
1845+ return argument;
1846+}
1847+
1848+PowerdMediator::PowerdMediator()
1849+ : dim_brightness{10},
1850+ normal_brightness{102},
1851+ current_brightness{0},
1852+ min_brightness_{10},
1853 max_brightness_{102},
1854- normal_brightness_{102},
1855- current_brightness{0},
1856- backlight_state{BacklightState::normal},
1857 auto_brightness_supported_{false},
1858 auto_brightness_requested{false},
1859- sys_state{SysState::unknown}
1860+ backlight_state{BacklightState::normal},
1861+ pending_suspend_blocker_request{true},
1862+ powerd_interface{new QDBusInterface("com.canonical.powerd",
1863+ "/com/canonical/powerd", "com.canonical.powerd", QDBusConnection::systemBus())},
1864+ service_watcher{new QDBusServiceWatcher("com.canonical.powerd",
1865+ QDBusConnection::systemBus(), QDBusServiceWatcher::WatchForRegistration)},
1866+ system_state{unknown}
1867 {
1868- connection.add_match(
1869- "type='signal',"
1870- "sender='com.canonical.powerd',"
1871- "interface='com.canonical.powerd',"
1872- "member='SysPowerStateChange'");
1873- connection.add_match(
1874- "type='signal',"
1875- "sender='org.freedesktop.DBus',"
1876- "interface='org.freedesktop.DBus',"
1877- "member='NameOwnerChanged'");
1878- connection.add_filter(handle_dbus_message_thunk, this);
1879-
1880- std::promise<void> event_loop_started;
1881- auto event_loop_started_future = event_loop_started.get_future();
1882-
1883- dbus_loop_thread = std::thread(
1884- [this,&event_loop_started]
1885+ qDBusRegisterMetaType<BrightnessParams>();
1886+
1887+ //Powerd interface may not be available right now or it may restart in the future
1888+ //watch for changes so brightness params get initialized to the most recent values.
1889+ connect(service_watcher.get(),
1890+ SIGNAL(serviceRegistered(QString const&)),
1891+ this, SLOT(powerd_registered()));
1892+
1893+ powerd_interface->connection().connect("com.canonical.powerd",
1894+ "/com/canonical/powerd",
1895+ "com.canonical.powerd",
1896+ "SysPowerStateChange",
1897+ this,
1898+ SLOT(powerd_state_changed(int)));
1899+
1900+ if (powerd_interface->isValid())
1901+ {
1902+ init_brightness_params();
1903+ if (request_suspend_blocker())
1904 {
1905- usc::set_thread_name("USC/DBusPowerd");
1906- dbus_event_loop.run(event_loop_started);
1907- });
1908-
1909- event_loop_started_future.wait();
1910-
1911- init_powerd_state(ForceDisableSuspend::yes);
1912-}
1913-
1914-usc::PowerdMediator::~PowerdMediator()
1915-{
1916- turn_off_backlight();
1917-
1918- dbus_event_loop.stop();
1919- dbus_loop_thread.join();
1920-}
1921-
1922-void usc::PowerdMediator::set_dim_backlight()
1923-{
1924- std::lock_guard<decltype(mutex)> lock{mutex};
1925-
1926- change_backlight_state(BacklightState::dim, ForceBacklightState::no);
1927-}
1928-
1929-void usc::PowerdMediator::set_normal_backlight()
1930-{
1931- std::lock_guard<decltype(mutex)> lock{mutex};
1932-
1933- if (auto_brightness_supported_ && auto_brightness_requested)
1934- change_backlight_state(BacklightState::automatic, ForceBacklightState::no);
1935+ /*
1936+ * If powerd is already up it may already be in the active state
1937+ * and the SysPowerStateChange signal could have already been broadcasted
1938+ * before we got a chance to register a listener for it.
1939+ * We will assume that if the active request succeeds that the system state
1940+ * will become active at some point in the future - this is only a workaround
1941+ * for the lack of a system state query api in powerd
1942+ */
1943+ system_state = active;
1944+ }
1945+ }
1946+}
1947+
1948+PowerdMediator::~PowerdMediator()
1949+{
1950+ if (current_brightness > 0)
1951+ turn_off_backlight();
1952+}
1953+
1954+void PowerdMediator::set_dim_backlight()
1955+{
1956+ change_backlight_state(BacklightState::dim);
1957+}
1958+
1959+void PowerdMediator::set_normal_backlight()
1960+{
1961+ if (auto_brightness_requested)
1962+ change_backlight_state(BacklightState::automatic);
1963 else
1964- change_backlight_state(BacklightState::normal, ForceBacklightState::no);
1965-}
1966-
1967-void usc::PowerdMediator::turn_off_backlight()
1968-{
1969- std::lock_guard<decltype(mutex)> lock{mutex};
1970-
1971- change_backlight_state(BacklightState::off, ForceBacklightState::no);
1972-}
1973-
1974-void usc::PowerdMediator::change_backlight_values(int dim, int normal)
1975-{
1976- std::lock_guard<decltype(mutex)> lock{mutex};
1977-
1978- if (is_valid_brightness(dim))
1979- dim_brightness_ = dim;
1980- if (is_valid_brightness(normal))
1981- normal_brightness_ = normal;
1982-}
1983-
1984-void usc::PowerdMediator::allow_suspend()
1985-{
1986- std::lock_guard<decltype(mutex)> lock{mutex};
1987-
1988- if (!suspend_block_cookie.empty())
1989- {
1990- auto const cstr = suspend_block_cookie.c_str();
1991- invoke_with_reply("clearSysState",
1992- DBUS_TYPE_STRING, &cstr,
1993- DBUS_TYPE_INVALID);
1994-
1995- suspend_block_cookie.clear();
1996- }
1997-
1998- pending_suspend_block_request = false;
1999-}
2000-
2001-void usc::PowerdMediator::disable_suspend()
2002-{
2003- std::unique_lock<decltype(mutex)> lock{mutex};
2004-
2005- if (request_suspend_block())
2006- {
2007- lock.unlock();
2008- wait_for_sys_state(SysState::active);
2009- }
2010-}
2011-
2012-void usc::PowerdMediator::enable_auto_brightness(bool enable)
2013-{
2014- std::lock_guard<decltype(mutex)> lock{mutex};
2015-
2016+ change_backlight_state(BacklightState::normal);
2017+}
2018+
2019+void PowerdMediator::turn_off_backlight()
2020+{
2021+ change_backlight_state(BacklightState::off);
2022+}
2023+
2024+void PowerdMediator::change_backlight_values(int dim, int normal)
2025+{
2026+ if (normal >= min_brightness_ && normal <= max_brightness_)
2027+ normal_brightness = normal;
2028+ if (dim >= min_brightness_ && dim <= max_brightness_)
2029+ dim_brightness = dim;
2030+}
2031+
2032+void PowerdMediator::enable_auto_brightness(bool enable)
2033+{
2034 auto_brightness_requested = enable;
2035-
2036 if (auto_brightness_supported_ && enable)
2037- change_backlight_state(BacklightState::automatic, ForceBacklightState::no);
2038+ change_backlight_state(BacklightState::automatic);
2039 else
2040- change_backlight_state(BacklightState::normal, ForceBacklightState::no);
2041+ change_backlight_state(BacklightState::normal);
2042 }
2043
2044-bool usc::PowerdMediator::auto_brightness_supported()
2045+bool PowerdMediator::auto_brightness_supported()
2046 {
2047- std::lock_guard<decltype(mutex)> lock{mutex};
2048-
2049 return auto_brightness_supported_;
2050 }
2051
2052-void usc::PowerdMediator::set_brightness(int brightness)
2053-{
2054- std::lock_guard<decltype(mutex)> lock{mutex};
2055-
2056- normal_brightness_ = brightness;
2057- if (backlight_state != BacklightState::automatic)
2058- change_backlight_state(BacklightState::normal, ForceBacklightState::yes);
2059-}
2060-
2061-int usc::PowerdMediator::min_brightness()
2062-{
2063- std::lock_guard<decltype(mutex)> lock{mutex};
2064-
2065+int PowerdMediator::min_brightness()
2066+{
2067 return min_brightness_;
2068 }
2069
2070-int usc::PowerdMediator::max_brightness()
2071+int PowerdMediator::max_brightness()
2072 {
2073- std::lock_guard<decltype(mutex)> lock{mutex};
2074-
2075 return max_brightness_;
2076 }
2077
2078-bool usc::PowerdMediator::is_system_suspended()
2079-{
2080- std::lock_guard<decltype(mutex)> lock{mutex};
2081-
2082- return sys_state == SysState::suspend;
2083-}
2084-
2085-::DBusHandlerResult usc::PowerdMediator::handle_dbus_message_thunk(
2086- ::DBusConnection* connection, DBusMessage* message, void* user_data)
2087-{
2088- auto const powerd_mediator = static_cast<PowerdMediator*>(user_data);
2089-
2090- return powerd_mediator->handle_dbus_message(connection, message, user_data);
2091-}
2092-
2093-::DBusHandlerResult usc::PowerdMediator::handle_dbus_message(
2094- ::DBusConnection* connection, ::DBusMessage* message, void* user_data)
2095-{
2096- ScopedDBusError error;
2097-
2098- if (dbus_message_is_signal(message, powerd_service_interface, "SysPowerStateChange"))
2099- {
2100- int32_t state{-1};
2101- dbus_message_get_args(
2102- message, &error, DBUS_TYPE_INT32, &state, DBUS_TYPE_INVALID);
2103-
2104- if (!error)
2105- {
2106- update_sys_state(state == static_cast<int32_t>(SysState::suspend) ?
2107- SysState::suspend : SysState::active);
2108- }
2109- }
2110- else if (dbus_message_is_signal(message, "org.freedesktop.DBus", "NameOwnerChanged"))
2111- {
2112- char const* name = "";
2113- char const* old_owner = "";
2114- char const* new_owner = "";
2115-
2116- dbus_message_get_args(
2117- message, &error,
2118- DBUS_TYPE_STRING, &name,
2119- DBUS_TYPE_STRING, &old_owner,
2120- DBUS_TYPE_STRING, &new_owner,
2121- DBUS_TYPE_INVALID);
2122-
2123- if (!error &&
2124- std::string{powerd_service_name} == name &&
2125- *old_owner == '\0' &&
2126- *new_owner != '\0')
2127- {
2128- init_powerd_state(ForceDisableSuspend::no);
2129- }
2130- }
2131-
2132- return DBUS_HANDLER_RESULT_HANDLED;
2133-}
2134-
2135-void usc::PowerdMediator::init_powerd_state(ForceDisableSuspend force_disable_suspend)
2136-{
2137- std::lock_guard<decltype(mutex)> lock{mutex};
2138-
2139+void PowerdMediator::powerd_registered()
2140+{
2141 init_brightness_params();
2142
2143- /*
2144- * A suspend block request needs to be issued here on the following scenarios:
2145+ /* A suspend block request needs to be issued here on the following scenarios:
2146 * 1. powerd has restarted and PowerdMediator had already issued a request
2147 * to the previous powerd instance
2148 * 2. When booting up the screen is assumed to be on and consequently we need to also issue
2149@@ -269,199 +179,125 @@
2150 * 3. If powerd interface is not available yet, but the screen had been turned on
2151 * then now is the time to issue the request
2152 */
2153- if (!suspend_block_cookie.empty() || pending_suspend_block_request ||
2154- force_disable_suspend == ForceDisableSuspend::yes)
2155+ if (!suspend_block_cookie.isEmpty() || pending_suspend_blocker_request)
2156 {
2157- // Clear the previous cookie as powerd has restarted anyway
2158+ //Clear the previous cookie as powerd has restarted anyway
2159 suspend_block_cookie.clear();
2160- if (request_suspend_block())
2161- {
2162- /*
2163- * If powerd is already up it may already be in the active state
2164- * and the SysPowerStateChange signal could have already been broadcasted
2165- * before we got a chance to register a listener for it.
2166- * We will assume that if the active request succeeds that the system state
2167- * will become active at some point in the future - this is only a workaround
2168- * for the lack of a system state query api in powerd
2169- */
2170- update_sys_state(SysState::active);
2171- }
2172- }
2173-
2174- // Powerd may have restarted, re-apply backlight settings
2175- change_backlight_state(backlight_state, ForceBacklightState::yes);
2176-}
2177-
2178-void usc::PowerdMediator::init_brightness_params()
2179-{
2180- auto reply = invoke_with_reply("getBrightnessParams", DBUS_TYPE_INVALID);
2181-
2182- if (reply)
2183- {
2184- DBusMessageIter msg_iter;
2185- dbus_message_iter_init(reply, &msg_iter);
2186- if (dbus_message_iter_get_arg_type(&msg_iter) != DBUS_TYPE_STRUCT)
2187- return;
2188-
2189- DBusMessageIter struct_iter;
2190- dbus_message_iter_recurse(&msg_iter, &struct_iter);
2191-
2192- int32_t dim, min, max, normal;
2193- dbus_bool_t auto_b;
2194- struct { int type; void* address; } args[]{
2195- { DBUS_TYPE_INT32, &dim },
2196- { DBUS_TYPE_INT32, &min },
2197- { DBUS_TYPE_INT32, &max },
2198- { DBUS_TYPE_INT32, &normal },
2199- { DBUS_TYPE_BOOLEAN, &auto_b }
2200- };
2201-
2202- for (auto const& arg : args)
2203- {
2204- if (dbus_message_iter_get_arg_type(&struct_iter) == arg.type)
2205- dbus_message_iter_get_basic(&struct_iter, arg.address);
2206- else
2207- return;
2208- dbus_message_iter_next(&struct_iter);
2209- }
2210-
2211- dim_brightness_ = dim;
2212- min_brightness_ = min;
2213- max_brightness_ = max;
2214- normal_brightness_ = normal;
2215- auto_brightness_supported_ = (auto_b == TRUE);
2216- }
2217-}
2218-
2219-void usc::PowerdMediator::change_backlight_state(
2220- BacklightState new_state,
2221- ForceBacklightState force_backlight_state)
2222-{
2223- if (backlight_state == new_state &&
2224- force_backlight_state == ForceBacklightState::no)
2225- {
2226+ request_suspend_blocker();
2227+ }
2228+
2229+ //Powerd may have restarted, re-apply backlight settings
2230+ change_backlight_state(backlight_state, true);
2231+}
2232+
2233+void PowerdMediator::set_brightness(int brightness)
2234+{
2235+ normal_brightness = brightness;
2236+
2237+ if (backlight_state != BacklightState::automatic)
2238+ powerd_interface->call("setUserBrightness", brightness);
2239+}
2240+
2241+void PowerdMediator::change_backlight_state(BacklightState new_state, bool force_change)
2242+{
2243+ if (backlight_state == new_state && !force_change)
2244 return;
2245- }
2246-
2247- update_current_brightness_for_state(new_state);
2248- backlight_state = new_state;
2249
2250 if (new_state == BacklightState::automatic)
2251 {
2252- dbus_bool_t const enable{TRUE};
2253- invoke_with_reply("userAutobrightnessEnable",
2254- DBUS_TYPE_BOOLEAN, &enable,
2255- DBUS_TYPE_INVALID);
2256- }
2257- else
2258- {
2259- int32_t const b{current_brightness};
2260- invoke_with_reply("setUserBrightness",
2261- DBUS_TYPE_INT32, &b,
2262- DBUS_TYPE_INVALID);
2263- }
2264-}
2265-
2266-bool usc::PowerdMediator::is_valid_brightness(int brightness)
2267-{
2268- return brightness >= min_brightness_ && brightness <= max_brightness_;
2269-}
2270-
2271-bool usc::PowerdMediator::request_suspend_block()
2272-{
2273- if (suspend_block_cookie.empty())
2274- {
2275- char const* const name{"com.canonical.Unity.Screen"};
2276- int const sys_state_active{static_cast<int>(SysState::active)};
2277-
2278- auto reply = invoke_with_reply(
2279- "requestSysState",
2280- DBUS_TYPE_STRING, &name,
2281- DBUS_TYPE_INT32, &sys_state_active,
2282- DBUS_TYPE_INVALID);
2283-
2284- if (reply)
2285- {
2286- char const* cookie{nullptr};
2287-
2288- dbus_message_get_args(
2289- reply, nullptr,
2290- DBUS_TYPE_STRING, &cookie,
2291- DBUS_TYPE_INVALID);
2292-
2293- if (cookie)
2294- suspend_block_cookie = cookie;
2295-
2296- return true;
2297- }
2298- else
2299- {
2300- pending_suspend_block_request = true;
2301- }
2302- }
2303-
2304- return false;
2305-}
2306-
2307-void usc::PowerdMediator::update_sys_state(SysState state)
2308-{
2309- {
2310- std::lock_guard<decltype(mutex)> lock{sys_state_mutex};
2311- sys_state = state;
2312- }
2313- sys_state_changed.notify_one();
2314-}
2315-
2316-void usc::PowerdMediator::wait_for_sys_state(SysState state)
2317-{
2318- std::unique_lock<decltype(sys_state_mutex)> lock{sys_state_mutex};
2319- sys_state_changed.wait(lock, [this, state]{ return sys_state == state; });
2320-}
2321-
2322-void usc::PowerdMediator::update_current_brightness_for_state(BacklightState state)
2323-{
2324- switch (state)
2325+ powerd_interface->call("userAutobrightnessEnable", true);
2326+ backlight_state = BacklightState::automatic;
2327+ return;
2328+ }
2329+
2330+ switch (new_state)
2331 {
2332 case BacklightState::normal:
2333- current_brightness = normal_brightness_;
2334+ current_brightness = normal_brightness;
2335 break;
2336 case BacklightState::off:
2337 current_brightness = 0;
2338 break;
2339 case BacklightState::dim:
2340- current_brightness = dim_brightness_;
2341+ current_brightness = dim_brightness;
2342 break;
2343 default:
2344+ std::cerr << "unknown backlight state" << std::endl;
2345 break;
2346 }
2347-}
2348-
2349-usc::DBusMessageHandle usc::PowerdMediator::invoke_with_reply(
2350- char const* method, int first_arg_type, ...)
2351-{
2352- va_list args;
2353- va_start(args, first_arg_type);
2354- auto msg = make_powerd_method_call_message(method, first_arg_type, args);
2355- va_end(args);
2356-
2357- std::promise<DBusMessage*> reply_promise;
2358- auto reply_future = reply_promise.get_future();
2359-
2360- auto const send_message_with_reply =
2361- [this, &msg, &reply_promise]
2362- {
2363- auto const reply = dbus_connection_send_with_reply_and_block(
2364- connection, msg, DBUS_TIMEOUT_USE_DEFAULT, nullptr);
2365-
2366- reply_promise.set_value(reply);
2367- };
2368-
2369- // Run in the context of the dbus event loop to avoid
2370- // strange dbus behaviors.
2371- if (std::this_thread::get_id() == dbus_loop_thread.get_id())
2372- send_message_with_reply();
2373+
2374+ powerd_interface->call("setUserBrightness", current_brightness);
2375+ backlight_state = new_state;
2376+}
2377+
2378+void PowerdMediator::allow_suspend()
2379+{
2380+ if (!suspend_block_cookie.isEmpty())
2381+ {
2382+ powerd_interface->call("clearSysState", suspend_block_cookie);
2383+ suspend_block_cookie.clear();
2384+ }
2385+ pending_suspend_blocker_request = false;
2386+}
2387+
2388+void PowerdMediator::disable_suspend()
2389+{
2390+ if (request_suspend_blocker())
2391+ wait_for_state(active);
2392+}
2393+
2394+bool PowerdMediator::request_suspend_blocker()
2395+{
2396+ if (suspend_block_cookie.isEmpty())
2397+ {
2398+ QDBusReply<QString> reply = powerd_interface->call("requestSysState", "com.canonical.Unity.Screen", 1);
2399+ if (reply.isValid())
2400+ {
2401+ suspend_block_cookie = reply.value();
2402+ pending_suspend_blocker_request = false;
2403+ return true;
2404+ }
2405+ else
2406+ {
2407+ //Powerd may not yet be available, so save the pending request
2408+ pending_suspend_blocker_request = true;
2409+ }
2410+ }
2411+ return false;
2412+}
2413+
2414+void PowerdMediator::init_brightness_params()
2415+{
2416+ QDBusReply<BrightnessParams> reply = powerd_interface->call("getBrightnessParams");
2417+ if (reply.isValid())
2418+ {
2419+ auto const& params = reply.value();
2420+ dim_brightness = params.dim_brightness;
2421+ normal_brightness = params.default_brightness;
2422+ min_brightness_ = params.min_brightness;
2423+ max_brightness_ = params.max_brightness;
2424+ auto_brightness_supported_ = params.auto_brightness_supported;
2425+ std::cerr << "initialized brightness parameters" << std::endl;
2426+ }
2427 else
2428- dbus_event_loop.enqueue(send_message_with_reply);
2429-
2430- return usc::DBusMessageHandle{reply_future.get()};
2431+ {
2432+ std::cerr << "getBrightnessParams call failed with: ";
2433+ std::cerr << reply.error().message().toStdString() << std::endl;
2434+ }
2435+}
2436+
2437+void PowerdMediator::powerd_state_changed(int state)
2438+{
2439+ std::unique_lock<std::mutex> lock(system_state_mutex);
2440+
2441+ system_state = state == 0 ? suspended : active;
2442+
2443+ lock.unlock();
2444+ state_change.notify_one();
2445+}
2446+
2447+void PowerdMediator::wait_for_state(SystemState state)
2448+{
2449+ std::unique_lock<std::mutex> lock(system_state_mutex);
2450+ state_change.wait(lock, [this, state]{ return (system_state == state); });
2451 }
2452
2453=== modified file 'src/powerd_mediator.h'
2454--- src/powerd_mediator.h 2015-04-07 13:36:48 +0000
2455+++ src/powerd_mediator.h 2015-05-12 16:45:46 +0000
2456@@ -1,5 +1,5 @@
2457 /*
2458- * Copyright © 2015 Canonical Ltd.
2459+ * Copyright © 2014 Canonical Ltd.
2460 *
2461 * This program is free software: you can redistribute it and/or modify
2462 * it under the terms of the GNU General Public License version 3 as
2463@@ -14,42 +14,53 @@
2464 * along with this program. If not, see <http://www.gnu.org/licenses/>.
2465 */
2466
2467-#ifndef USC_POWERD_MEDIATOR_H_
2468-#define USC_POWERD_MEDIATOR_H_
2469-
2470-#include "screen_hardware.h"
2471-
2472-#include "dbus_connection_handle.h"
2473-#include "dbus_event_loop.h"
2474-
2475-namespace usc
2476-{
2477-class DBusMessageHandle;
2478-
2479-class PowerdMediator : public ScreenHardware
2480-{
2481+#ifndef POWERD_MEDIATOR_
2482+#define POWERD_MEDIATOR_
2483+
2484+#include <mir_toolkit/common.h>
2485+
2486+#include <QString>
2487+#include <QObject>
2488+
2489+#include <memory>
2490+#include <mutex>
2491+#include <condition_variable>
2492+
2493+class QDBusInterface;
2494+class QDBusServiceWatcher;
2495+
2496+/*
2497+ * A Proxy to powerd. Note this class is not thread-safe,
2498+ * synchronization should be done externally.
2499+ */
2500+class PowerdMediator : public QObject
2501+{
2502+ Q_OBJECT
2503 public:
2504- PowerdMediator(std::string const& bus_addr);
2505+ PowerdMediator();
2506 ~PowerdMediator();
2507
2508- void set_dim_backlight() override;
2509- void set_normal_backlight() override;
2510- void turn_off_backlight() override;
2511- void change_backlight_values(int dim_brightness, int normal_brightness) override;
2512-
2513- void allow_suspend() override;
2514- void disable_suspend() override;
2515-
2516- void enable_auto_brightness(bool flag) override;
2517- bool auto_brightness_supported() override;
2518- void set_brightness(int brightness) override;
2519- int min_brightness() override;
2520- int max_brightness() override;
2521-
2522- bool is_system_suspended();
2523+ void set_dim_backlight();
2524+ void set_normal_backlight();
2525+ void turn_off_backlight();
2526+ void allow_suspend();
2527+ void disable_suspend();
2528+
2529+ void change_backlight_values(int dim_brightness, int normal_brightness);
2530+ void enable_auto_brightness(bool flag);
2531+
2532+ bool auto_brightness_supported();
2533+ int min_brightness();
2534+ int max_brightness();
2535+
2536+ void set_brightness(int brightness);
2537+
2538+private Q_SLOTS:
2539+ void powerd_registered();
2540+ void powerd_state_changed(int state);
2541
2542 private:
2543- enum class BacklightState
2544+ enum BacklightState
2545 {
2546 off,
2547 dim,
2548@@ -57,53 +68,35 @@
2549 automatic
2550 };
2551
2552- enum class SysState
2553+ enum SystemState
2554 {
2555 unknown = -1,
2556- suspend = 0,
2557+ suspended = 0,
2558 active,
2559 };
2560-
2561- enum class ForceDisableSuspend { no, yes };
2562- enum class ForceBacklightState { no, yes };
2563-
2564- static ::DBusHandlerResult handle_dbus_message_thunk(
2565- ::DBusConnection* connection, ::DBusMessage* message, void* user_data);
2566-
2567- ::DBusHandlerResult handle_dbus_message(
2568- ::DBusConnection* connection, ::DBusMessage* message, void* user_data);
2569- void init_powerd_state(ForceDisableSuspend force_disable_suspend);
2570+ void change_backlight_state(BacklightState state, bool force_change = false);
2571 void init_brightness_params();
2572- void change_backlight_state(
2573- BacklightState new_state, ForceBacklightState force_backlight_state);
2574- bool is_valid_brightness(int brightness);
2575- bool request_suspend_block();
2576- void wait_for_sys_state(SysState state);
2577- void update_sys_state(SysState state);
2578- void update_current_brightness_for_state(BacklightState state);
2579- void invoke(char const* method, int first_arg_type, ...);
2580- usc::DBusMessageHandle invoke_with_reply(char const* method, int first_arg_type, ...);
2581-
2582- usc::DBusConnectionHandle connection;
2583- usc::DBusEventLoop dbus_event_loop;
2584- std::thread dbus_loop_thread;
2585-
2586- std::mutex mutex;
2587- bool pending_suspend_block_request;
2588- int dim_brightness_;
2589+ bool request_suspend_blocker();
2590+ void wait_for_state(SystemState state);
2591+
2592+ int dim_brightness;
2593+ int normal_brightness;
2594+ int current_brightness;
2595 int min_brightness_;
2596 int max_brightness_;
2597- int normal_brightness_;
2598- int current_brightness;
2599- BacklightState backlight_state;
2600 bool auto_brightness_supported_;
2601 bool auto_brightness_requested;
2602- std::string suspend_block_cookie;
2603- std::mutex sys_state_mutex;
2604- SysState sys_state;
2605- std::condition_variable sys_state_changed;
2606+ BacklightState backlight_state;
2607+
2608+ QString suspend_block_cookie;
2609+ bool pending_suspend_blocker_request;
2610+
2611+ std::unique_ptr<QDBusInterface> powerd_interface;
2612+ std::unique_ptr<QDBusServiceWatcher> service_watcher;
2613+
2614+ SystemState system_state;
2615+
2616+ std::mutex system_state_mutex;
2617+ std::condition_variable state_change;
2618 };
2619-
2620-}
2621-
2622 #endif
2623
2624=== renamed file 'src/screen_event_handler.cpp' => 'src/powerkey_handler.cpp'
2625--- src/screen_event_handler.cpp 2015-04-07 13:36:48 +0000
2626+++ src/powerkey_handler.cpp 2015-05-12 16:45:46 +0000
2627@@ -1,5 +1,5 @@
2628 /*
2629- * Copyright © 2014-2015 Canonical Ltd.
2630+ * Copyright © 2014 Canonical Ltd.
2631 *
2632 * This program is free software: you can redistribute it and/or modify
2633 * it under the terms of the GNU General Public License version 3 as
2634@@ -14,96 +14,85 @@
2635 * along with this program. If not, see <http://www.gnu.org/licenses/>.
2636 */
2637
2638-#include "screen_event_handler.h"
2639-#include "screen.h"
2640+#include "powerkey_handler.h"
2641+#include "screen_state_handler.h"
2642 #include "power_state_change_reason.h"
2643
2644-#include <mir/time/alarm_factory.h>
2645-#include <mir_toolkit/events/input/input_event.h>
2646+#include <mir/time/timer.h>
2647
2648 #include <cstdio>
2649-
2650-usc::ScreenEventHandler::ScreenEventHandler(
2651- std::shared_ptr<Screen> const& screen,
2652- std::shared_ptr<mir::time::AlarmFactory> const& alarm_factory,
2653- std::chrono::milliseconds power_key_ignore_timeout,
2654- std::chrono::milliseconds shutdown_timeout,
2655- std::function<void()> const& shutdown)
2656- : screen{screen},
2657- alarm_factory{alarm_factory},
2658+#include "dbus_screen.h"
2659+#include "powerd_mediator.h"
2660+
2661+namespace mi = mir::input;
2662+
2663+PowerKeyHandler::PowerKeyHandler(mir::time::Timer& timer,
2664+ std::chrono::milliseconds power_key_ignore_timeout,
2665+ std::chrono::milliseconds shutdown_timeout,
2666+ ScreenStateHandler& screen_state_handler)
2667+ : long_press_detected{false},
2668+ screen_state_handler{&screen_state_handler},
2669 power_key_ignore_timeout{power_key_ignore_timeout},
2670 shutdown_timeout{shutdown_timeout},
2671- shutdown{shutdown},
2672- long_press_detected{false},
2673- shutdown_alarm{alarm_factory->create_alarm([this]{ shutdown_alarm_notification(); })},
2674- long_press_alarm{alarm_factory->create_alarm([this]{ long_press_notification(); })}
2675+ shutdown_alarm{timer.create_alarm([this]{ shutdown_alarm_notification(); })},
2676+ long_press_alarm{timer.create_alarm([this]{ long_press_notification(); })}
2677 {
2678 }
2679
2680-usc::ScreenEventHandler::~ScreenEventHandler() = default;
2681+PowerKeyHandler::~PowerKeyHandler() = default;
2682
2683-bool usc::ScreenEventHandler::handle(MirEvent const& event)
2684+bool PowerKeyHandler::handle(MirEvent const& event)
2685 {
2686 static const int32_t POWER_KEY_CODE = 26;
2687-
2688+
2689 if (mir_event_get_type(&event) != mir_event_type_input)
2690 return false;
2691-
2692- auto const input_event = mir_event_get_input_event(&event);
2693- auto const input_event_type = mir_input_event_get_type(input_event);
2694-
2695- if (input_event_type == mir_input_event_type_key)
2696- {
2697- auto const kev = mir_input_event_get_keyboard_event(input_event);
2698- if (mir_keyboard_event_key_code(kev) != POWER_KEY_CODE)
2699- return false;
2700-
2701- auto const action = mir_keyboard_event_action(kev);
2702- if (action == mir_keyboard_action_down)
2703- power_key_down();
2704- else if (action == mir_keyboard_action_up)
2705- power_key_up();
2706- }
2707- else if (input_event_type == mir_input_event_type_touch ||
2708- input_event_type == mir_input_event_type_pointer)
2709- {
2710- std::lock_guard<std::mutex> lock{guard};
2711- screen->keep_display_on_temporarily();
2712- }
2713+ auto input_event = mir_event_get_input_event(&event);
2714+ if (mir_input_event_get_type(input_event) != mir_input_event_type_key)
2715+ return false;
2716+ auto kev = mir_input_event_get_key_input_event(input_event);
2717+ if (mir_key_input_event_get_key_code(kev) != POWER_KEY_CODE)
2718+ return false;
2719+
2720+ auto action = mir_key_input_event_get_action(kev);
2721+ if (action == mir_key_input_event_action_down)
2722+ power_key_down();
2723+ else if (action == mir_key_input_event_action_up)
2724+ power_key_up();
2725
2726 return false;
2727 }
2728
2729-void usc::ScreenEventHandler::power_key_down()
2730+void PowerKeyHandler::power_key_down()
2731 {
2732 std::lock_guard<std::mutex> lock{guard};
2733- screen->enable_inactivity_timers(false);
2734+ screen_state_handler->enable_inactivity_timers(false);
2735 long_press_detected = false;
2736 long_press_alarm->reschedule_in(power_key_ignore_timeout);
2737 shutdown_alarm->reschedule_in(shutdown_timeout);
2738 }
2739
2740-void usc::ScreenEventHandler::power_key_up()
2741+void PowerKeyHandler::power_key_up()
2742 {
2743 std::lock_guard<std::mutex> lock{guard};
2744 shutdown_alarm->cancel();
2745 long_press_alarm->cancel();
2746 if (!long_press_detected)
2747 {
2748- screen->toggle_screen_power_mode(PowerStateChangeReason::power_key);
2749+ screen_state_handler->toggle_screen_power_mode(PowerStateChangeReason::power_key);
2750 }
2751 }
2752
2753-void usc::ScreenEventHandler::shutdown_alarm_notification()
2754+void PowerKeyHandler::shutdown_alarm_notification()
2755 {
2756- screen->set_screen_power_mode(
2757+ screen_state_handler->set_screen_power_mode(
2758 MirPowerMode::mir_power_mode_off, PowerStateChangeReason::power_key);
2759- shutdown();
2760+ system("shutdown -P now");
2761 }
2762
2763-void usc::ScreenEventHandler::long_press_notification()
2764+void PowerKeyHandler::long_press_notification()
2765 {
2766- screen->set_screen_power_mode(
2767+ screen_state_handler->set_screen_power_mode(
2768 MirPowerMode::mir_power_mode_on, PowerStateChangeReason::power_key);
2769 long_press_detected = true;
2770 }
2771
2772=== renamed file 'src/screen_event_handler.h' => 'src/powerkey_handler.h'
2773--- src/screen_event_handler.h 2015-04-07 13:36:48 +0000
2774+++ src/powerkey_handler.h 2015-05-12 16:45:46 +0000
2775@@ -1,5 +1,5 @@
2776 /*
2777- * Copyright © 2014-2015 Canonical Ltd.
2778+ * Copyright © 2014 Canonical Ltd.
2779 *
2780 * This program is free software: you can redistribute it and/or modify
2781 * it under the terms of the GNU General Public License version 3 as
2782@@ -14,8 +14,8 @@
2783 * along with this program. If not, see <http://www.gnu.org/licenses/>.
2784 */
2785
2786-#ifndef USC_SCREEN_EVENT_HANDLER_H_
2787-#define USC_SCREEN_EVENT_HANDLER_H_
2788+#ifndef POWERKEY_HANDLER_H_
2789+#define POWERKEY_HANDLER_H_
2790
2791 #include "mir/input/event_filter.h"
2792
2793@@ -29,25 +29,21 @@
2794 namespace time
2795 {
2796 class Alarm;
2797-class AlarmFactory;
2798-}
2799-}
2800-
2801-namespace usc
2802-{
2803-class Screen;
2804-
2805-class ScreenEventHandler : public mir::input::EventFilter
2806+class Timer;
2807+}
2808+}
2809+
2810+class ScreenStateHandler;
2811+
2812+class PowerKeyHandler : public mir::input::EventFilter
2813 {
2814 public:
2815- ScreenEventHandler(
2816- std::shared_ptr<Screen> const& screen,
2817- std::shared_ptr<mir::time::AlarmFactory> const& alarm_factory,
2818- std::chrono::milliseconds power_key_ignore_timeout,
2819- std::chrono::milliseconds shutdown_timeout,
2820- std::function<void()> const& shutdown);
2821+ PowerKeyHandler(mir::time::Timer& timer,
2822+ std::chrono::milliseconds power_key_ignore_timeout,
2823+ std::chrono::milliseconds shutdown_timeout,
2824+ ScreenStateHandler& screen_state_handler);
2825
2826- ~ScreenEventHandler();
2827+ ~PowerKeyHandler();
2828
2829 bool handle(MirEvent const& event) override;
2830
2831@@ -58,17 +54,16 @@
2832 void long_press_notification();
2833
2834 std::mutex guard;
2835- std::shared_ptr<Screen> const screen;
2836- std::shared_ptr<mir::time::AlarmFactory> const alarm_factory;
2837- std::chrono::milliseconds const power_key_ignore_timeout;
2838- std::chrono::milliseconds const shutdown_timeout;
2839- std::function<void()> const shutdown;
2840-
2841 std::atomic<bool> long_press_detected;
2842+
2843+ ScreenStateHandler* screen_state_handler;
2844+
2845+ std::chrono::milliseconds power_key_ignore_timeout;
2846+ std::chrono::milliseconds shutdown_timeout;
2847+
2848 std::unique_ptr<mir::time::Alarm> shutdown_alarm;
2849 std::unique_ptr<mir::time::Alarm> long_press_alarm;
2850+
2851 };
2852
2853-}
2854-
2855 #endif
2856
2857=== removed file 'src/scoped_dbus_error.h'
2858--- src/scoped_dbus_error.h 2015-03-18 11:49:36 +0000
2859+++ src/scoped_dbus_error.h 1970-01-01 00:00:00 +0000
2860@@ -1,57 +0,0 @@
2861-/*
2862- * Copyright © 2015 Canonical Ltd.
2863- *
2864- * This program is free software: you can redistribute it and/or modify
2865- * it under the terms of the GNU General Public License version 3 as
2866- * published by the Free Software Foundation.
2867- *
2868- * This program is distributed in the hope that it will be useful,
2869- * but WITHOUT ANY WARRANTY; without even the implied warranty of
2870- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2871- * GNU General Public License for more details.
2872- *
2873- * You should have received a copy of the GNU General Public License
2874- * along with this program. If not, see <http://www.gnu.org/licenses/>.
2875- *
2876- * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>
2877- */
2878-
2879-#ifndef USC_SCOPED_DBUS_ERROR_H_
2880-#define USC_SCOPED_DBUS_ERROR_H_
2881-
2882-#include <dbus/dbus.h>
2883-#include <string>
2884-
2885-namespace usc
2886-{
2887-
2888-struct ScopedDBusError : ::DBusError
2889-{
2890- ScopedDBusError()
2891- {
2892- dbus_error_init(this);
2893- }
2894-
2895- ~ScopedDBusError()
2896- {
2897- if (dbus_error_is_set(this) == TRUE)
2898- dbus_error_free(this);
2899- }
2900-
2901- std::string message_str() const
2902- {
2903- return message;
2904- }
2905-
2906- operator bool() const
2907- {
2908- return dbus_error_is_set(this) == TRUE;
2909- }
2910-
2911- ScopedDBusError(ScopedDBusError const&) = delete;
2912- ScopedDBusError& operator=(ScopedDBusError const&) = delete;
2913-};
2914-
2915-}
2916-
2917-#endif
2918
2919=== removed file 'src/screen_hardware.h'
2920--- src/screen_hardware.h 2015-02-18 14:40:29 +0000
2921+++ src/screen_hardware.h 1970-01-01 00:00:00 +0000
2922@@ -1,49 +0,0 @@
2923-/*
2924- * Copyright © 2015 Canonical Ltd.
2925- *
2926- * This program is free software: you can redistribute it and/or modify
2927- * it under the terms of the GNU General Public License version 3 as
2928- * published by the Free Software Foundation.
2929- *
2930- * This program is distributed in the hope that it will be useful,
2931- * but WITHOUT ANY WARRANTY; without even the implied warranty of
2932- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2933- * GNU General Public License for more details.
2934- *
2935- * You should have received a copy of the GNU General Public License
2936- * along with this program. If not, see <http://www.gnu.org/licenses/>.
2937- */
2938-
2939-#ifndef USC_SCREEN_HARDWARE_H_
2940-#define USC_SCREEN_HARDWARE_H_
2941-
2942-namespace usc
2943-{
2944-
2945-class ScreenHardware
2946-{
2947-public:
2948- virtual ~ScreenHardware() = default;
2949-
2950- virtual void set_dim_backlight() = 0;
2951- virtual void set_normal_backlight() = 0;
2952- virtual void turn_off_backlight() = 0;
2953- virtual void change_backlight_values(int dim_brightness, int normal_brightness) = 0;
2954-
2955- virtual void allow_suspend() = 0;
2956- virtual void disable_suspend() = 0;
2957-
2958- virtual void enable_auto_brightness(bool flag) = 0;
2959- virtual bool auto_brightness_supported() = 0;
2960- virtual void set_brightness(int brightness) = 0;
2961- virtual int min_brightness() = 0;
2962- virtual int max_brightness() = 0;
2963-
2964-protected:
2965- ScreenHardware() = default;
2966- ScreenHardware(ScreenHardware const&) = delete;
2967- ScreenHardware& operator=(ScreenHardware const&) = delete;
2968-};
2969-
2970-}
2971-#endif
2972
2973=== renamed file 'src/mir_screen.cpp' => 'src/screen_state_handler.cpp'
2974--- src/mir_screen.cpp 2015-03-16 10:24:45 +0000
2975+++ src/screen_state_handler.cpp 2015-05-12 16:45:46 +0000
2976@@ -1,5 +1,5 @@
2977 /*
2978- * Copyright © 2014-2015 Canonical Ltd.
2979+ * Copyright © 2014 Canonical Ltd.
2980 *
2981 * This program is free software: you can redistribute it and/or modify
2982 * it under the terms of the GNU General Public License version 3 as
2983@@ -14,72 +14,80 @@
2984 * along with this program. If not, see <http://www.gnu.org/licenses/>.
2985 */
2986
2987-#include "mir_screen.h"
2988+#include "screen_state_handler.h"
2989
2990 #include <mir/main_loop.h>
2991-#include <mir/time/alarm_factory.h>
2992+#include <mir/time/timer.h>
2993 #include <mir/compositor/compositor.h>
2994 #include <mir/graphics/display.h>
2995 #include <mir/graphics/display_configuration.h>
2996 #include <mir/input/touch_visualizer.h>
2997
2998 #include <cstdio>
2999-#include "screen_hardware.h"
3000+#include "dbus_screen.h"
3001+#include "dbus_screen_observer.h"
3002+#include "powerd_mediator.h"
3003 #include "power_state_change_reason.h"
3004 #include "server.h"
3005
3006 namespace mi = mir::input;
3007+namespace mc = mir::compositor;
3008 namespace mg = mir::graphics;
3009
3010-usc::MirScreen::MirScreen(
3011- std::shared_ptr<usc::ScreenHardware> const& screen_hardware,
3012- std::shared_ptr<mir::compositor::Compositor> const& compositor,
3013- std::shared_ptr<mir::graphics::Display> const& display,
3014- std::shared_ptr<mir::input::TouchVisualizer> const& touch_visualizer,
3015- std::shared_ptr<mir::time::AlarmFactory> const& alarm_factory,
3016- std::chrono::milliseconds power_off_timeout,
3017- std::chrono::milliseconds dimmer_timeout)
3018- : screen_hardware{screen_hardware},
3019- compositor{compositor},
3020- display{display},
3021- touch_visualizer{touch_visualizer},
3022- alarm_factory{alarm_factory},
3023- power_off_alarm{alarm_factory->create_alarm(
3024- std::bind(&usc::MirScreen::power_off_alarm_notification, this))},
3025- dimmer_alarm{alarm_factory->create_alarm(
3026- std::bind(&usc::MirScreen::dimmer_alarm_notification, this))},
3027- power_off_timeout{power_off_timeout},
3028+ScreenStateHandler::ScreenStateHandler(std::shared_ptr<usc::Server> const& server,
3029+ std::chrono::milliseconds poweroff_timeout,
3030+ std::chrono::milliseconds dimmer_timeout)
3031+ : current_power_mode{MirPowerMode::mir_power_mode_on},
3032+ restart_timers{true},
3033+ power_off_timeout{poweroff_timeout},
3034 dimming_timeout{dimmer_timeout},
3035- current_power_mode{MirPowerMode::mir_power_mode_on},
3036- restart_timers{true},
3037- power_state_change_handler{[](MirPowerMode,PowerStateChangeReason){}}
3038+ powerd_mediator{new PowerdMediator()},
3039+ server{server},
3040+ power_off_alarm{server->the_main_loop()->create_alarm(
3041+ std::bind(&ScreenStateHandler::power_off_alarm_notification, this))},
3042+ dimmer_alarm{server->the_main_loop()->create_alarm(
3043+ std::bind(&ScreenStateHandler::dimmer_alarm_notification, this))},
3044+ dbus_screen{new DBusScreen(*this)}
3045 {
3046 /*
3047 * Make sure the compositor is running as certain conditions can
3048 * cause Mir to tear down the compositor threads before we get
3049 * to this point. See bug #1410381.
3050 */
3051- compositor->start();
3052+ server->the_compositor()->start();
3053 reset_timers_l();
3054 }
3055
3056-usc::MirScreen::~MirScreen() = default;
3057+ScreenStateHandler::~ScreenStateHandler() = default;
3058
3059-void usc::MirScreen::keep_display_on_temporarily()
3060+bool ScreenStateHandler::handle(MirEvent const& event)
3061 {
3062+ if (mir_event_get_type(&event) != mir_event_type_input)
3063+ return false;
3064+
3065+ auto input_event_type = mir_input_event_get_type(mir_event_get_input_event(&event));
3066+ // TODO: We should consider resetting the timer for key events too
3067+ // we have to make sure we wont introduce a bug where pressing the power
3068+ // key (to turn screen off) or just the volume keys will wake the screen though!
3069+ if (!(input_event_type == mir_input_event_type_touch
3070+ || input_event_type == mir_input_event_type_pointer))
3071+ return false;
3072+
3073 std::lock_guard<std::mutex> lock{guard};
3074 reset_timers_l();
3075 if (current_power_mode == MirPowerMode::mir_power_mode_on)
3076- screen_hardware->set_normal_backlight();
3077+ powerd_mediator->set_normal_backlight();
3078+
3079+ return false;
3080 }
3081
3082-void usc::MirScreen::enable_inactivity_timers(bool enable)
3083+void ScreenStateHandler::enable_inactivity_timers(bool enable)
3084 {
3085 std::lock_guard<std::mutex> lock{guard};
3086 enable_inactivity_timers_l(enable);
3087 }
3088
3089-void usc::MirScreen::toggle_screen_power_mode(PowerStateChangeReason reason)
3090+void ScreenStateHandler::toggle_screen_power_mode(PowerStateChangeReason reason)
3091 {
3092 std::lock_guard<std::mutex> lock{guard};
3093 MirPowerMode new_mode = (current_power_mode == MirPowerMode::mir_power_mode_on) ?
3094@@ -88,13 +96,13 @@
3095 set_screen_power_mode_l(new_mode, reason);
3096 }
3097
3098-void usc::MirScreen::set_screen_power_mode(MirPowerMode mode, PowerStateChangeReason reason)
3099+void ScreenStateHandler::set_screen_power_mode(MirPowerMode mode, PowerStateChangeReason reason)
3100 {
3101 std::lock_guard<std::mutex> lock{guard};
3102 set_screen_power_mode_l(mode, reason);
3103 }
3104
3105-void usc::MirScreen::keep_display_on(bool on)
3106+void ScreenStateHandler::keep_display_on(bool on)
3107 {
3108 std::lock_guard<std::mutex> lock{guard};
3109 restart_timers = !on;
3110@@ -104,19 +112,19 @@
3111 set_screen_power_mode_l(MirPowerMode::mir_power_mode_on, PowerStateChangeReason::unknown);
3112 }
3113
3114-void usc::MirScreen::set_brightness(int brightness)
3115-{
3116- std::lock_guard<std::mutex> lock{guard};
3117- screen_hardware->set_brightness(brightness);
3118-}
3119-
3120-void usc::MirScreen::enable_auto_brightness(bool enable)
3121-{
3122- std::lock_guard<std::mutex> lock{guard};
3123- screen_hardware->enable_auto_brightness(enable);
3124-}
3125-
3126-void usc::MirScreen::set_inactivity_timeouts(int raw_poweroff_timeout, int raw_dimmer_timeout)
3127+void ScreenStateHandler::set_brightness(int brightness)
3128+{
3129+ std::lock_guard<std::mutex> lock{guard};
3130+ powerd_mediator->set_brightness(brightness);
3131+}
3132+
3133+void ScreenStateHandler::enable_auto_brightness(bool enable)
3134+{
3135+ std::lock_guard<std::mutex> lock{guard};
3136+ powerd_mediator->enable_auto_brightness(enable);
3137+}
3138+
3139+void ScreenStateHandler::set_inactivity_timeouts(int raw_poweroff_timeout, int raw_dimmer_timeout)
3140 {
3141 std::lock_guard<std::mutex> lock{guard};
3142
3143@@ -133,13 +141,13 @@
3144 reset_timers_l();
3145 }
3146
3147-void usc::MirScreen::set_screen_power_mode_l(MirPowerMode mode, PowerStateChangeReason reason)
3148+void ScreenStateHandler::set_screen_power_mode_l(MirPowerMode mode, PowerStateChangeReason reason)
3149 {
3150 if (mode == MirPowerMode::mir_power_mode_on)
3151 {
3152 /* The screen may be dim, but on - make sure to reset backlight */
3153 if (current_power_mode == MirPowerMode::mir_power_mode_on)
3154- screen_hardware->set_normal_backlight();
3155+ powerd_mediator->set_normal_backlight();
3156 configure_display_l(mode, reason);
3157 reset_timers_l();
3158 }
3159@@ -150,12 +158,14 @@
3160 }
3161 }
3162
3163-void usc::MirScreen::configure_display_l(MirPowerMode mode, PowerStateChangeReason reason)
3164+void ScreenStateHandler::configure_display_l(MirPowerMode mode, PowerStateChangeReason reason)
3165 {
3166 if (current_power_mode == mode)
3167 return;
3168
3169+ std::shared_ptr<mg::Display> display = server->the_display();
3170 std::shared_ptr<mg::DisplayConfiguration> displayConfig = display->configuration();
3171+ std::shared_ptr<mc::Compositor> compositor = server->the_compositor();
3172
3173 displayConfig->for_each_output(
3174 [&](const mg::UserDisplayConfigurationOutput displayConfigOutput) {
3175@@ -169,11 +179,11 @@
3176 if (power_on)
3177 {
3178 //Some devices do not turn screen on properly from suspend mode
3179- screen_hardware->disable_suspend();
3180+ powerd_mediator->disable_suspend();
3181 }
3182 else
3183 {
3184- screen_hardware->turn_off_backlight();
3185+ powerd_mediator->turn_off_backlight();
3186 }
3187
3188 display->configure(*displayConfig.get());
3189@@ -181,25 +191,24 @@
3190 if (power_on)
3191 {
3192 compositor->start();
3193- screen_hardware->set_normal_backlight();
3194+ powerd_mediator->set_normal_backlight();
3195 }
3196
3197 current_power_mode = mode;
3198
3199- // TODO: Don't call this under lock
3200- power_state_change_handler(mode, reason);
3201+ dbus_screen->emit_power_state_change(mode, reason);
3202
3203 if (!power_on)
3204- screen_hardware->allow_suspend();
3205+ powerd_mediator->allow_suspend();
3206 }
3207
3208-void usc::MirScreen::cancel_timers_l()
3209+void ScreenStateHandler::cancel_timers_l()
3210 {
3211 power_off_alarm->cancel();
3212 dimmer_alarm->cancel();
3213 }
3214
3215-void usc::MirScreen::reset_timers_l()
3216+void ScreenStateHandler::reset_timers_l()
3217 {
3218 if (restart_timers && current_power_mode != MirPowerMode::mir_power_mode_off)
3219 {
3220@@ -211,7 +220,7 @@
3221 }
3222 }
3223
3224-void usc::MirScreen::enable_inactivity_timers_l(bool enable)
3225+void ScreenStateHandler::enable_inactivity_timers_l(bool enable)
3226 {
3227 if (enable)
3228 reset_timers_l();
3229@@ -219,32 +228,25 @@
3230 cancel_timers_l();
3231 }
3232
3233-void usc::MirScreen::power_off_alarm_notification()
3234+void ScreenStateHandler::power_off_alarm_notification()
3235 {
3236 std::lock_guard<std::mutex> lock{guard};
3237 configure_display_l(MirPowerMode::mir_power_mode_off, PowerStateChangeReason::inactivity);
3238 }
3239
3240-void usc::MirScreen::dimmer_alarm_notification()
3241+void ScreenStateHandler::dimmer_alarm_notification()
3242 {
3243 std::lock_guard<std::mutex> lock{guard};
3244- screen_hardware->set_dim_backlight();
3245+ powerd_mediator->set_dim_backlight();
3246 }
3247
3248-void usc::MirScreen::set_touch_visualization_enabled(bool enabled)
3249+void ScreenStateHandler::set_touch_visualization_enabled(bool enabled)
3250 {
3251 std::lock_guard<std::mutex> lock{guard};
3252-
3253+
3254+ auto visualizer = server->the_touch_visualizer();
3255 if (enabled)
3256- touch_visualizer->enable();
3257+ visualizer->enable();
3258 else
3259- touch_visualizer->disable();
3260-}
3261-
3262-void usc::MirScreen::register_power_state_change_handler(
3263- PowerStateChangeHandler const& handler)
3264-{
3265- std::lock_guard<std::mutex> lock{guard};
3266-
3267- power_state_change_handler = handler;
3268+ visualizer->disable();
3269 }
3270
3271=== renamed file 'src/mir_screen.h' => 'src/screen_state_handler.h'
3272--- src/mir_screen.h 2015-03-16 10:24:45 +0000
3273+++ src/screen_state_handler.h 2015-05-12 16:45:46 +0000
3274@@ -1,5 +1,5 @@
3275 /*
3276- * Copyright © 2014-2015 Canonical Ltd.
3277+ * Copyright © 2014 Canonical Ltd.
3278 *
3279 * This program is free software: you can redistribute it and/or modify
3280 * it under the terms of the GNU General Public License version 3 as
3281@@ -14,55 +14,51 @@
3282 * along with this program. If not, see <http://www.gnu.org/licenses/>.
3283 */
3284
3285-#ifndef USC_MIR_SCREEN_H_
3286-#define USC_MIR_SCREEN_H_
3287+#ifndef SCREEN_STATE_HANDLER_
3288+#define SCREEN_STATE_HANDLER_
3289
3290-#include "screen.h"
3291+#include "mir/input/event_filter.h"
3292+#include "dbus_screen_observer.h"
3293
3294 #include <chrono>
3295 #include <memory>
3296 #include <mutex>
3297
3298+class DBusScreen;
3299+class PowerdMediator;
3300 enum class PowerStateChangeReason;
3301+namespace usc { class Server; }
3302
3303 namespace mir
3304 {
3305-namespace compositor { class Compositor; }
3306-namespace graphics {class Display;}
3307-namespace input { class TouchVisualizer; }
3308-namespace time { class AlarmFactory; class Alarm; }
3309-}
3310-
3311-namespace usc
3312+namespace time
3313 {
3314-class Server;
3315-class ScreenHardware;
3316+class Alarm;
3317+class Timer;
3318+}
3319+}
3320
3321-class MirScreen: public Screen
3322+class ScreenStateHandler: public mir::input::EventFilter, public DBusScreenObserver
3323 {
3324 public:
3325- MirScreen(std::shared_ptr<usc::ScreenHardware> const& screen_hardware,
3326- std::shared_ptr<mir::compositor::Compositor> const& compositor,
3327- std::shared_ptr<mir::graphics::Display> const& display,
3328- std::shared_ptr<mir::input::TouchVisualizer> const& touch_visualizer,
3329- std::shared_ptr<mir::time::AlarmFactory> const& alarm_factory,
3330- std::chrono::milliseconds power_off_timeout,
3331- std::chrono::milliseconds dimmer_timeout);
3332- ~MirScreen();
3333-
3334- void enable_inactivity_timers(bool enable) override;
3335- void toggle_screen_power_mode(PowerStateChangeReason reason) override;
3336- void keep_display_on_temporarily() override;
3337+ ScreenStateHandler(std::shared_ptr<usc::Server> const& server,
3338+ std::chrono::milliseconds power_off_timeout,
3339+ std::chrono::milliseconds dimmer_timeout);
3340+ virtual ~ScreenStateHandler();
3341+
3342+ //from EventFilter
3343+ bool handle(MirEvent const& event) override;
3344+
3345+ void enable_inactivity_timers(bool enable);
3346+ void toggle_screen_power_mode(PowerStateChangeReason reason);
3347
3348 void set_screen_power_mode(MirPowerMode mode, PowerStateChangeReason reason) override;
3349 void keep_display_on(bool on) override;
3350 void set_brightness(int brightness) override;
3351 void enable_auto_brightness(bool enable) override;
3352 void set_inactivity_timeouts(int power_off_timeout, int dimmer_timeout) override;
3353-
3354+
3355 void set_touch_visualization_enabled(bool enabled) override;
3356- void register_power_state_change_handler(
3357- PowerStateChangeHandler const& power_state_change_handler) override;
3358
3359 private:
3360 void set_screen_power_mode_l(MirPowerMode mode, PowerStateChangeReason reason);
3361@@ -76,22 +72,21 @@
3362 void dimmer_alarm_notification();
3363 void long_press_alarm_notification();
3364
3365- std::shared_ptr<usc::ScreenHardware> const screen_hardware;
3366- std::shared_ptr<mir::compositor::Compositor> const compositor;
3367- std::shared_ptr<mir::graphics::Display> const display;
3368- std::shared_ptr<mir::input::TouchVisualizer> const touch_visualizer;
3369- std::shared_ptr<mir::time::AlarmFactory> const alarm_factory;
3370- std::unique_ptr<mir::time::Alarm> const power_off_alarm;
3371- std::unique_ptr<mir::time::Alarm> const dimmer_alarm;
3372-
3373 std::mutex guard;
3374+
3375+ MirPowerMode current_power_mode;
3376+ bool restart_timers;
3377+
3378 std::chrono::milliseconds power_off_timeout;
3379 std::chrono::milliseconds dimming_timeout;
3380- MirPowerMode current_power_mode;
3381- bool restart_timers;
3382- PowerStateChangeHandler power_state_change_handler;
3383+
3384+ std::unique_ptr<PowerdMediator> powerd_mediator;
3385+ std::shared_ptr<usc::Server> server;
3386+
3387+ std::unique_ptr<mir::time::Alarm> power_off_alarm;
3388+ std::unique_ptr<mir::time::Alarm> dimmer_alarm;
3389+
3390+ std::unique_ptr<DBusScreen> dbus_screen;
3391 };
3392
3393-}
3394-
3395 #endif
3396
3397=== modified file 'src/server.cpp'
3398--- src/server.cpp 2015-04-07 13:36:48 +0000
3399+++ src/server.cpp 2015-05-12 16:45:46 +0000
3400@@ -18,19 +18,14 @@
3401
3402 #include "server.h"
3403 #include "external_spinner.h"
3404+#include "shell.h"
3405 #include "asio_dm_connection.h"
3406 #include "session_switcher.h"
3407-#include "window_manager.h"
3408-#include "mir_screen.h"
3409-#include "screen_event_handler.h"
3410-#include "powerd_mediator.h"
3411-#include "unity_screen_service.h"
3412
3413 #include <mir/input/cursor_listener.h>
3414 #include <mir/server_status_listener.h>
3415 #include <mir/shell/focus_controller.h>
3416 #include <mir/scene/session.h>
3417-#include <mir/main_loop.h>
3418
3419 #include <iostream>
3420
3421@@ -87,7 +82,7 @@
3422
3423 std::weak_ptr<ms::Session> weak_active_session()
3424 {
3425- return focus_controller->focused_session();
3426+ return focus_controller->focussed_application();
3427 }
3428
3429 std::shared_ptr<msh::FocusController> const focus_controller;
3430@@ -107,38 +102,24 @@
3431 add_configuration_option("inactivity-display-dim-timeout", "The time in seconds before the screen is dimmed when there are no active sessions", mir::OptionType::integer);
3432 add_configuration_option("shutdown-timeout", "The time in milli-seconds the power key must be held to initiate a clean system shutdown", mir::OptionType::integer);
3433 add_configuration_option("power-key-ignore-timeout", "The time in milli-seconds the power key must be held to ignore - must be less than shutdown-timeout", mir::OptionType::integer);
3434+ add_configuration_option("remove_pointer_timeout", "The time in milli-seconds the cursor image stays visible after touch screen is used again - by default the cursor image stays visible", mir::OptionType::integer);
3435 add_configuration_option("disable-inactivity-policy", "Disables handling user inactivity and power key", mir::OptionType::boolean);
3436
3437 set_command_line(argc, const_cast<char const **>(argv));
3438
3439 set_command_line_handler(&ignore_unknown_arguments);
3440
3441- wrap_cursor_listener([this](std::shared_ptr<mir::input::CursorListener> const& default_)
3442- -> std::shared_ptr<mir::input::CursorListener>
3443- {
3444- // This is a workaround for u8 desktop preview in 14.04 for the lack of client cursor API.
3445- // We need to disable the cursor for XMir but leave it on for the desktop preview.
3446- // Luckily as it stands they run inside seperate instances of USC. ~racarr
3447- if (enable_hardware_cursor())
3448- return default_;
3449- else
3450- return std::make_shared<NullCursorListener>();
3451- });
3452-
3453 override_the_server_status_listener([this]()
3454 -> std::shared_ptr<mir::ServerStatusListener>
3455 {
3456 return std::make_shared<ServerStatusListener>(the_focus_controller());
3457 });
3458
3459- override_the_window_manager_builder([this](msh::FocusController* focus_controller)
3460- {
3461- return std::make_shared<WindowManager>(
3462- focus_controller,
3463- the_shell_display_layout(),
3464- the_session_coordinator(),
3465- the_session_switcher());
3466- });
3467+ wrap_shell([this](std::shared_ptr<msh::Shell> const& wrapped)
3468+ -> std::shared_ptr<msh::Shell>
3469+ {
3470+ return std::make_shared<Shell>(wrapped, the_session_switcher());
3471+ });
3472
3473 set_config_filename("unity-system-compositor.conf");
3474
3475@@ -182,64 +163,3 @@
3476 the_dm_message_handler());
3477 });
3478 }
3479-
3480-std::shared_ptr<usc::Screen> usc::Server::the_screen()
3481-{
3482- return screen(
3483- [this]
3484- {
3485- return std::make_shared<MirScreen>(
3486- the_screen_hardware(),
3487- the_compositor(),
3488- the_display(),
3489- the_touch_visualizer(),
3490- the_main_loop(),
3491- inactivity_display_off_timeout(),
3492- inactivity_display_dim_timeout());
3493- });
3494-}
3495-
3496-std::shared_ptr<mi::EventFilter> usc::Server::the_screen_event_handler()
3497-{
3498- return screen_event_handler(
3499- [this]
3500- {
3501- return std::make_shared<ScreenEventHandler>(
3502- the_screen(),
3503- the_main_loop(),
3504- power_key_ignore_timeout(),
3505- shutdown_timeout(),
3506- [] { if (system("shutdown -P now")); }); // ignore warning
3507- });
3508-}
3509-
3510-std::shared_ptr<usc::ScreenHardware> usc::Server::the_screen_hardware()
3511-{
3512- return screen_hardware(
3513- [this]
3514- {
3515- return std::make_shared<usc::PowerdMediator>(dbus_bus_address());
3516- });
3517-}
3518-
3519-std::shared_ptr<usc::UnityScreenService> usc::Server::the_unity_screen_service()
3520-{
3521- return unity_screen_service(
3522- [this]
3523- {
3524- return std::make_shared<UnityScreenService>(
3525- dbus_bus_address(),
3526- the_screen());
3527- });
3528-}
3529-
3530-std::string usc::Server::dbus_bus_address()
3531-{
3532- static char const* const default_bus_address{"unix:path=/var/run/dbus/system_bus_socket"};
3533-
3534- char const* bus = getenv("DBUS_SYSTEM_BUS_ADDRESS");
3535- if (!bus)
3536- bus = default_bus_address;
3537-
3538- return std::string{bus};
3539-}
3540
3541=== modified file 'src/server.h'
3542--- src/server.h 2015-04-24 14:40:28 +0000
3543+++ src/server.h 2015-05-12 16:45:46 +0000
3544@@ -23,25 +23,12 @@
3545 #include <mir/cached_ptr.h>
3546 #include <mir/options/option.h>
3547
3548-#include <chrono>
3549-
3550-namespace mir
3551-{
3552-namespace input
3553-{
3554-class EventFilter;
3555-}
3556-}
3557-
3558 namespace usc
3559 {
3560 class Spinner;
3561 class SessionSwitcher;
3562 class DMMessageHandler;
3563 class DMConnection;
3564-class Screen;
3565-class ScreenHardware;
3566-class UnityScreenService;
3567
3568 class Server : private mir::Server
3569 {
3570@@ -55,20 +42,47 @@
3571 using mir::Server::the_display;
3572 using mir::Server::the_compositor;
3573 using mir::Server::the_touch_visualizer;
3574+ using mir::Server::the_cursor;
3575
3576 virtual std::shared_ptr<Spinner> the_spinner();
3577 virtual std::shared_ptr<DMMessageHandler> the_dm_message_handler();
3578 virtual std::shared_ptr<DMConnection> the_dm_connection();
3579- virtual std::shared_ptr<Screen> the_screen();
3580- virtual std::shared_ptr<mir::input::EventFilter> the_screen_event_handler();
3581- virtual std::shared_ptr<ScreenHardware> the_screen_hardware();
3582- virtual std::shared_ptr<UnityScreenService> the_unity_screen_service();
3583
3584 bool show_version()
3585 {
3586 return the_options()->is_set("version");
3587 }
3588
3589+ int inactivity_display_off_timeout()
3590+ {
3591+ return the_options()->get("inactivity-display-off-timeout", 60);
3592+ }
3593+
3594+ int inactivity_display_dim_timeout()
3595+ {
3596+ return the_options()->get("inactivity-display-dim-timeout", 45);
3597+ }
3598+
3599+ int shutdown_timeout()
3600+ {
3601+ return the_options()->get("shutdown-timeout", 5000);
3602+ }
3603+
3604+ int power_key_ignore_timeout()
3605+ {
3606+ return the_options()->get("power-key-ignore-timeout", 2000);
3607+ }
3608+
3609+ int remove_pointer_timeout()
3610+ {
3611+ return the_options()->get("remove-pointer-timeout", 0);
3612+ }
3613+
3614+ bool enable_hardware_cursor()
3615+ {
3616+ return the_options()->get("enable-hardware-cursor", false);
3617+ }
3618+
3619 bool disable_inactivity_policy()
3620 {
3621 return the_options()->get("disable-inactivity-policy", false);
3622@@ -77,6 +91,16 @@
3623 std::string blacklist()
3624 {
3625 auto x = the_options()->get("blacklist", "");
3626+ //boost::trim(x);
3627+ return x;
3628+ }
3629+
3630+ std::string spinner_executable()
3631+ {
3632+ // TODO: once our default spinner is ready for use everywhere, replace
3633+ // default value with DEFAULT_SPINNER instead of the empty string.
3634+ auto x = the_options()->get("spinner", "");
3635+ //boost::trim(x);
3636 return x;
3637 }
3638
3639@@ -96,55 +120,11 @@
3640 -> decltype(mir::Server::get_options())
3641 { return mir::Server::get_options(); }
3642
3643- std::chrono::milliseconds inactivity_display_off_timeout()
3644- {
3645- using namespace std::chrono;
3646- return duration_cast<milliseconds>(
3647- seconds{the_options()->get("inactivity-display-off-timeout", 60)});
3648- }
3649-
3650- std::chrono::milliseconds inactivity_display_dim_timeout()
3651- {
3652- using namespace std::chrono;
3653- return duration_cast<milliseconds>(
3654- seconds{the_options()->get("inactivity-display-dim-timeout", 45)});
3655- }
3656-
3657- std::chrono::milliseconds shutdown_timeout()
3658- {
3659- return std::chrono::milliseconds{
3660- the_options()->get("shutdown-timeout", 5000)};
3661- }
3662-
3663- std::chrono::milliseconds power_key_ignore_timeout()
3664- {
3665- return std::chrono::milliseconds{
3666- the_options()->get("power-key-ignore-timeout", 2000)};
3667- }
3668-
3669- bool enable_hardware_cursor()
3670- {
3671- return the_options()->get("enable-hardware-cursor", false);
3672- }
3673-
3674- std::string spinner_executable()
3675- {
3676- // TODO: once our default spinner is ready for use everywhere, replace
3677- // default value with DEFAULT_SPINNER instead of the empty string.
3678- auto x = the_options()->get("spinner", "");
3679- return x;
3680- }
3681-
3682 virtual std::shared_ptr<SessionSwitcher> the_session_switcher();
3683- std::string dbus_bus_address();
3684
3685 mir::CachedPtr<Spinner> spinner;
3686 mir::CachedPtr<DMConnection> dm_connection;
3687 mir::CachedPtr<SessionSwitcher> session_switcher;
3688- mir::CachedPtr<Screen> screen;
3689- mir::CachedPtr<mir::input::EventFilter> screen_event_handler;
3690- mir::CachedPtr<ScreenHardware> screen_hardware;
3691- mir::CachedPtr<UnityScreenService> unity_screen_service;
3692 };
3693
3694 }
3695
3696=== added file 'src/shell.cpp'
3697--- src/shell.cpp 1970-01-01 00:00:00 +0000
3698+++ src/shell.cpp 2015-05-12 16:45:46 +0000
3699@@ -0,0 +1,157 @@
3700+/*
3701+ * Copyright © 2014-2015 Canonical Ltd.
3702+ *
3703+ * This program is free software: you can redistribute it and/or modify
3704+ * it under the terms of the GNU General Public License version 3 as
3705+ * published by the Free Software Foundation.
3706+ *
3707+ * This program is distributed in the hope that it will be useful,
3708+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3709+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3710+ * GNU General Public License for more details.
3711+ *
3712+ * You should have received a copy of the GNU General Public License
3713+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3714+ *
3715+ * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>
3716+ */
3717+
3718+#include "shell.h"
3719+#include "session_switcher.h"
3720+
3721+#include <mir/scene/null_surface_observer.h>
3722+#include <mir/scene/session.h>
3723+#include <mir/scene/surface.h>
3724+#include <mir/frontend/session.h>
3725+
3726+#include <iostream>
3727+
3728+namespace msh = mir::shell;
3729+namespace ms = mir::scene;
3730+namespace mf = mir::frontend;
3731+
3732+namespace
3733+{
3734+
3735+class UscSession : public usc::Session
3736+{
3737+public:
3738+ UscSession(
3739+ std::shared_ptr<ms::Session> const& scene_session,
3740+ msh::FocusController& focus_controller)
3741+ : scene_session{scene_session},
3742+ focus_controller(focus_controller)
3743+ {
3744+ }
3745+
3746+ std::string name()
3747+ {
3748+ return scene_session->name();
3749+ }
3750+
3751+ void show() override
3752+ {
3753+ scene_session->show();
3754+ }
3755+
3756+ void hide() override
3757+ {
3758+ scene_session->hide();
3759+ }
3760+
3761+ void raise_and_focus() override
3762+ {
3763+ focus_controller.set_focus_to(scene_session);
3764+ }
3765+
3766+ bool corresponds_to(mir::frontend::Session const* s) override
3767+ {
3768+ return scene_session.get() == s;
3769+ }
3770+
3771+ std::shared_ptr<ms::Session> const scene_session;
3772+ msh::FocusController& focus_controller;
3773+};
3774+
3775+
3776+struct SessionReadyObserver : ms::NullSurfaceObserver,
3777+ std::enable_shared_from_this<SessionReadyObserver>
3778+{
3779+ SessionReadyObserver(
3780+ std::shared_ptr<usc::SessionSwitcher> const& switcher,
3781+ std::shared_ptr<ms::Surface> const& surface,
3782+ ms::Session const* session)
3783+ : switcher{switcher},
3784+ surface{surface},
3785+ session{session}
3786+ {
3787+ }
3788+
3789+ void frame_posted(int) override
3790+ {
3791+ ++num_frames_posted;
3792+ if (num_frames_posted == num_frames_for_session_ready)
3793+ {
3794+ switcher->mark_ready(session);
3795+ surface->remove_observer(shared_from_this());
3796+ }
3797+ }
3798+
3799+ std::shared_ptr<usc::SessionSwitcher> const switcher;
3800+ std::shared_ptr<ms::Surface> const surface;
3801+ ms::Session const* const session;
3802+ // We need to wait for the second frame before marking the session
3803+ // as ready. The first frame posted from sessions is a blank frame.
3804+ // TODO: Solve this issue at its root and remove this workaround
3805+ int const num_frames_for_session_ready{2};
3806+ int num_frames_posted{0};
3807+};
3808+
3809+}
3810+
3811+usc::Shell::Shell(
3812+ std::shared_ptr<msh::Shell> const& wrapped,
3813+ std::shared_ptr<SessionSwitcher> const& session_switcher)
3814+ : msh::ShellWrapper{wrapped},
3815+ session_switcher{session_switcher}
3816+{
3817+}
3818+
3819+std::shared_ptr<ms::Session>
3820+usc::Shell::open_session(
3821+ pid_t client_pid,
3822+ std::string const& name,
3823+ std::shared_ptr<mf::EventSink> const& sink)
3824+{
3825+ std::cerr << "Opening session " << name << std::endl;
3826+
3827+ auto orig = msh::ShellWrapper::open_session(client_pid, name, sink);
3828+
3829+ auto const usc_session = std::make_shared<UscSession>(orig, *this);
3830+
3831+ session_switcher->add(usc_session, client_pid);
3832+
3833+ return orig;
3834+}
3835+
3836+void usc::Shell::close_session(std::shared_ptr<ms::Session> const& session)
3837+{
3838+ std::cerr << "Closing session " << session->name() << std::endl;
3839+
3840+ msh::ShellWrapper::close_session(session);
3841+
3842+ session_switcher->remove(session);
3843+}
3844+
3845+mf::SurfaceId usc::Shell::create_surface(std::shared_ptr<ms::Session> const& session, ms::SurfaceCreationParameters const& params)
3846+{
3847+ auto const id = msh::ShellWrapper::create_surface(session, params);
3848+
3849+ auto const surface = session->surface(id);
3850+ auto const session_ready_observer = std::make_shared<SessionReadyObserver>(
3851+ session_switcher, surface, session.get());
3852+
3853+ surface->add_observer(session_ready_observer);
3854+
3855+ return id;
3856+}
3857
3858=== added file 'src/shell.h'
3859--- src/shell.h 1970-01-01 00:00:00 +0000
3860+++ src/shell.h 2015-05-12 16:45:46 +0000
3861@@ -0,0 +1,54 @@
3862+/*
3863+ * Copyright © 2014-2015 Canonical Ltd.
3864+ *
3865+ * This program is free software: you can redistribute it and/or modify
3866+ * it under the terms of the GNU General Public License version 3 as
3867+ * published by the Free Software Foundation.
3868+ *
3869+ * This program is distributed in the hope that it will be useful,
3870+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3871+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3872+ * GNU General Public License for more details.
3873+ *
3874+ * You should have received a copy of the GNU General Public License
3875+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3876+ *
3877+ * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>
3878+ */
3879+
3880+#ifndef USC_SHELL_H_
3881+#define USC_SHELL_H_
3882+
3883+#include <mir/shell/shell_wrapper.h>
3884+
3885+#include <memory>
3886+
3887+
3888+namespace usc
3889+{
3890+class SessionSwitcher;
3891+
3892+class Shell : public mir::shell::ShellWrapper
3893+{
3894+public:
3895+ Shell(
3896+ std::shared_ptr<mir::shell::Shell> const& wrapped,
3897+ std::shared_ptr<SessionSwitcher> const& session_switcher);
3898+
3899+private:
3900+ std::shared_ptr<mir::scene::Session> open_session(
3901+ pid_t client_pid,
3902+ std::string const& name,
3903+ std::shared_ptr<mir::frontend::EventSink> const& sink) override;
3904+ void close_session(std::shared_ptr<mir::scene::Session> const& session) override;
3905+
3906+ mir::frontend::SurfaceId create_surface(
3907+ std::shared_ptr<mir::scene::Session> const& session,
3908+ mir::scene::SurfaceCreationParameters const& params) override;
3909+
3910+ std::shared_ptr<SessionSwitcher> const session_switcher;
3911+};
3912+
3913+}
3914+
3915+#endif
3916
3917=== modified file 'src/system_compositor.cpp'
3918--- src/system_compositor.cpp 2015-04-07 13:36:48 +0000
3919+++ src/system_compositor.cpp 2015-05-12 16:45:46 +0000
3920@@ -17,18 +17,31 @@
3921 * Alexandros Frantzis <alexandros.frantzis@canonical.com>
3922 */
3923
3924+
3925 #include "system_compositor.h"
3926 #include "server.h"
3927 #include "dm_connection.h"
3928+#include "spinner.h"
3929+#include "screen_state_handler.h"
3930+#include "powerkey_handler.h"
3931+#include "cursor_enabler.h"
3932+
3933+// Qt headers will introduce a #define of "signals"
3934+// but some mir headers use "signals" as a variable name in
3935+// method declarations
3936+#undef signals
3937
3938 #include <mir/input/composite_event_filter.h>
3939 #include <mir/abnormal_exit.h>
3940+#include <mir/main_loop.h>
3941
3942 #include <cerrno>
3943 #include <iostream>
3944 #include <sys/stat.h>
3945+#include <thread>
3946 #include <regex.h>
3947 #include <GLES2/gl2.h>
3948+#include <QCoreApplication>
3949
3950 namespace
3951 {
3952@@ -87,21 +100,31 @@
3953 return;
3954 }
3955
3956+ struct ScopeGuard
3957+ {
3958+ ~ScopeGuard()
3959+ {
3960+ if (qt_thread.joinable())
3961+ {
3962+ QCoreApplication::quit();
3963+ qt_thread.join();
3964+ }
3965+ }
3966+
3967+ std::thread qt_thread;
3968+ } guard;
3969+
3970 server->add_init_callback([&]
3971 {
3972 auto vendor = (char *) glGetString(GL_VENDOR);
3973 auto renderer = (char *) glGetString (GL_RENDERER);
3974 auto version = (char *) glGetString (GL_VERSION);
3975-
3976 std::cerr << "GL_VENDOR = " << vendor << std::endl;
3977 std::cerr << "GL_RENDERER = " << renderer << std::endl;
3978 std::cerr << "GL_VERSION = " << version << std::endl;
3979
3980 if (!check_blacklist(server->blacklist(), vendor, renderer, version))
3981- {
3982- BOOST_THROW_EXCEPTION(
3983- mir::AbnormalExit("Video driver is blacklisted, exiting"));
3984- }
3985+ throw mir::AbnormalExit ("Video driver is blacklisted, exiting");
3986
3987 dm_connection = server->the_dm_connection();
3988
3989@@ -113,17 +136,50 @@
3990
3991 dm_connection->start();
3992
3993- if (!server->disable_inactivity_policy())
3994- {
3995- screen = server->the_screen();
3996- screen_event_handler = server->the_screen_event_handler();
3997-
3998- auto composite_filter = server->the_composite_event_filter();
3999- composite_filter->append(screen_event_handler);
4000-
4001- unity_screen_service = server->the_unity_screen_service();
4002- }
4003+ guard.qt_thread = std::thread(&SystemCompositor::qt_main, this);
4004 });
4005
4006 server->run();
4007 }
4008+
4009+void usc::SystemCompositor::qt_main()
4010+{
4011+ int argc{0};
4012+ QCoreApplication app(argc, nullptr);
4013+
4014+ if (!server->disable_inactivity_policy())
4015+ {
4016+ std::chrono::seconds inactivity_display_off_timeout{server->inactivity_display_off_timeout()};
4017+ std::chrono::seconds inactivity_display_dim_timeout{server->inactivity_display_dim_timeout()};
4018+ std::chrono::milliseconds power_key_ignore_timeout{server->power_key_ignore_timeout()};
4019+ std::chrono::milliseconds shutdown_timeout{server->shutdown_timeout()};
4020+ std::chrono::milliseconds remove_pointer_timeout{server->remove_pointer_timeout()};
4021+
4022+ screen_state_handler = std::make_shared<ScreenStateHandler>(server,
4023+ std::chrono::duration_cast<std::chrono::milliseconds>(inactivity_display_off_timeout),
4024+ std::chrono::duration_cast<std::chrono::milliseconds>(inactivity_display_dim_timeout));
4025+
4026+ power_key_handler = std::make_shared<PowerKeyHandler>(*(server->the_main_loop()),
4027+ power_key_ignore_timeout,
4028+ shutdown_timeout,
4029+ *screen_state_handler);
4030+
4031+ cursor_image_enabler = std::make_shared<CursorEnabler>(
4032+ server->the_cursor(),
4033+ remove_pointer_timeout);
4034+
4035+ auto composite_filter = server->the_composite_event_filter();
4036+ composite_filter->append(screen_state_handler);
4037+ composite_filter->append(power_key_handler);
4038+ if (server->enable_hardware_cursor())
4039+ composite_filter->append(cursor_image_enabler);
4040+ }
4041+
4042+ app.exec();
4043+
4044+ // Destroy components that depend on Qt event handling inside the Qt thread,
4045+ // to silence warnings during shutdown
4046+
4047+ // ScreenStateHandler uses the Qt DBus infrastructure
4048+ screen_state_handler.reset();
4049+}
4050
4051=== modified file 'src/system_compositor.h'
4052--- src/system_compositor.h 2015-04-07 13:36:48 +0000
4053+++ src/system_compositor.h 2015-05-12 16:45:46 +0000
4054@@ -22,13 +22,9 @@
4055
4056 #include <memory>
4057
4058-namespace mir
4059-{
4060-namespace input
4061-{
4062-class EventFilter;
4063-}
4064-}
4065+class ScreenStateHandler;
4066+class PowerKeyHandler;
4067+class CursorEnabler;
4068
4069 namespace usc
4070 {
4071@@ -36,9 +32,6 @@
4072 class Server;
4073 class DMConnection;
4074 class Spinner;
4075-class ScreenEventHandler;
4076-class Screen;
4077-class UnityScreenService;
4078
4079 class SystemCompositor
4080 {
4081@@ -47,12 +40,14 @@
4082 void run();
4083
4084 private:
4085+ void qt_main();
4086+
4087 std::shared_ptr<Server> const server;
4088 std::shared_ptr<DMConnection> dm_connection;
4089 std::shared_ptr<Spinner> const spinner;
4090- std::shared_ptr<Screen> screen;
4091- std::shared_ptr<mir::input::EventFilter> screen_event_handler;
4092- std::shared_ptr<UnityScreenService> unity_screen_service;
4093+ std::shared_ptr<ScreenStateHandler> screen_state_handler;
4094+ std::shared_ptr<PowerKeyHandler> power_key_handler;
4095+ std::shared_ptr<CursorEnabler> cursor_image_enabler;
4096 };
4097
4098 }
4099
4100=== removed file 'src/thread_name.cpp'
4101--- src/thread_name.cpp 2015-03-18 13:06:10 +0000
4102+++ src/thread_name.cpp 1970-01-01 00:00:00 +0000
4103@@ -1,32 +0,0 @@
4104-/*
4105- * Copyright © 2014-2015 Canonical Ltd.
4106- *
4107- * This program is free software: you can redistribute it and/or modify it
4108- * under the terms of the GNU Lesser General Public License version 3,
4109- * as published by the Free Software Foundation.
4110- *
4111- * This program is distributed in the hope that it will be useful,
4112- * but WITHOUT ANY WARRANTY; without even the implied warranty of
4113- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4114- * GNU Lesser General Public License for more details.
4115- *
4116- * You should have received a copy of the GNU Lesser General Public License
4117- * along with this program. If not, see <http://www.gnu.org/licenses/>.
4118- *
4119- * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>
4120- */
4121-
4122-#include "thread_name.h"
4123-
4124-#ifndef _GNU_SOURCE
4125-#define _GNU_SOURCE
4126-#endif
4127-#include <pthread.h>
4128-
4129-void usc::set_thread_name(std::string const& name)
4130-{
4131- static size_t const max_name_len = 15;
4132- auto const proper_name = name.substr(0, max_name_len);
4133-
4134- pthread_setname_np(pthread_self(), proper_name.c_str());
4135-}
4136
4137=== removed file 'src/thread_name.h'
4138--- src/thread_name.h 2015-03-18 13:06:10 +0000
4139+++ src/thread_name.h 1970-01-01 00:00:00 +0000
4140@@ -1,29 +0,0 @@
4141-/*
4142- * Copyright © 2015 Canonical Ltd.
4143- *
4144- * This program is free software: you can redistribute it and/or modify it
4145- * under the terms of the GNU Lesser General Public License version 3,
4146- * as published by the Free Software Foundation.
4147- *
4148- * This program is distributed in the hope that it will be useful,
4149- * but WITHOUT ANY WARRANTY; without even the implied warranty of
4150- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4151- * GNU Lesser General Public License for more details.
4152- *
4153- * You should have received a copy of the GNU Lesser General Public License
4154- * along with this program. If not, see <http://www.gnu.org/licenses/>.
4155- *
4156- * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>
4157- */
4158-
4159-#ifndef USC_THREAD_NAME_H_
4160-#define USC_THREAD_NAME_H_
4161-
4162-#include <string>
4163-
4164-namespace usc
4165-{
4166-void set_thread_name(std::string const& name);
4167-}
4168-
4169-#endif
4170
4171=== removed file 'src/unity_screen_service.cpp'
4172--- src/unity_screen_service.cpp 2015-03-18 13:06:10 +0000
4173+++ src/unity_screen_service.cpp 1970-01-01 00:00:00 +0000
4174@@ -1,358 +0,0 @@
4175-/*
4176- * Copyright © 2015 Canonical Ltd.
4177- *
4178- * This program is free software: you can redistribute it and/or modify
4179- * it under the terms of the GNU General Public License version 3 as
4180- * published by the Free Software Foundation.
4181- *
4182- * This program is distributed in the hope that it will be useful,
4183- * but WITHOUT ANY WARRANTY; without even the implied warranty of
4184- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4185- * GNU General Public License for more details.
4186- *
4187- * You should have received a copy of the GNU General Public License
4188- * along with this program. If not, see <http://www.gnu.org/licenses/>.
4189- *
4190- * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>
4191- */
4192-
4193-#include "unity_screen_service.h"
4194-#include "screen.h"
4195-#include "dbus_message_handle.h"
4196-#include "thread_name.h"
4197-#include "scoped_dbus_error.h"
4198-
4199-#include "unity_screen_service_introspection.h" // autogenerated
4200-
4201-namespace
4202-{
4203-
4204-char const* const dbus_screen_interface = "com.canonical.Unity.Screen";
4205-char const* const dbus_screen_path = "/com/canonical/Unity/Screen";
4206-char const* const dbus_screen_service_name = "com.canonical.Unity.Screen";
4207-
4208-}
4209-
4210-usc::UnityScreenService::UnityScreenService(
4211- std::string const& bus_addr,
4212- std::shared_ptr<usc::Screen> const& screen)
4213- : connection{bus_addr.c_str()},
4214- screen{screen},
4215- dbus_event_loop{connection},
4216- request_id{0}
4217-{
4218- connection.request_name(dbus_screen_service_name);
4219- connection.add_match(
4220- "type='signal',"
4221- "sender='org.freedesktop.DBus',"
4222- "interface='org.freedesktop.DBus',"
4223- "member='NameOwnerChanged'");
4224- connection.add_filter(handle_dbus_message_thunk, this);
4225-
4226- screen->register_power_state_change_handler(
4227- [this](MirPowerMode mode, PowerStateChangeReason reason)
4228- {
4229- dbus_emit_DisplayPowerStateChange(mode, reason);
4230- });
4231-
4232- std::promise<void> event_loop_started;
4233- auto event_loop_started_future = event_loop_started.get_future();
4234-
4235- dbus_loop_thread = std::thread(
4236- [this,&event_loop_started]
4237- {
4238- usc::set_thread_name("USC/DBusScreen");
4239- dbus_event_loop.run(event_loop_started);
4240- });
4241-
4242- event_loop_started_future.wait();
4243-}
4244-
4245-usc::UnityScreenService::~UnityScreenService()
4246-{
4247- dbus_event_loop.stop();
4248- dbus_loop_thread.join();
4249-}
4250-
4251-::DBusHandlerResult usc::UnityScreenService::handle_dbus_message_thunk(
4252- ::DBusConnection* connection, DBusMessage* message, void* user_data)
4253-{
4254- auto const dbus_screen_service = static_cast<usc::UnityScreenService*>(user_data);
4255- return dbus_screen_service->handle_dbus_message(connection, message, user_data);
4256-}
4257-
4258-DBusHandlerResult usc::UnityScreenService::handle_dbus_message(
4259- ::DBusConnection* connection, DBusMessage* message, void* user_data)
4260-{
4261- auto const sender = dbus_message_get_sender(message);
4262- ScopedDBusError args_error;
4263-
4264- if (dbus_message_is_method_call(message, "org.freedesktop.DBus.Introspectable", "Introspect"))
4265- {
4266- DBusMessageHandle reply{
4267- dbus_message_new_method_return(message),
4268- DBUS_TYPE_STRING, &unity_screen_service_introspection,
4269- DBUS_TYPE_INVALID};
4270-
4271- dbus_connection_send(connection, reply, nullptr);
4272- }
4273- else if (dbus_message_is_method_call(message, dbus_screen_interface, "setUserBrightness"))
4274- {
4275- int32_t brightness{0};
4276- dbus_message_get_args(
4277- message, &args_error, DBUS_TYPE_INT32, &brightness, DBUS_TYPE_INVALID);
4278-
4279- if (!args_error)
4280- {
4281- dbus_setUserBrightness(brightness);
4282-
4283- DBusMessageHandle reply{dbus_message_new_method_return(message)};
4284- dbus_connection_send(connection, reply, nullptr);
4285- }
4286- }
4287- else if (dbus_message_is_method_call(message, dbus_screen_interface, "userAutobrightnessEnable"))
4288- {
4289- dbus_bool_t enable{false};
4290- dbus_message_get_args(
4291- message, &args_error, DBUS_TYPE_BOOLEAN, &enable, DBUS_TYPE_INVALID);
4292-
4293- if (!args_error)
4294- {
4295- dbus_userAutobrightnessEnable(enable);
4296-
4297- DBusMessageHandle reply{dbus_message_new_method_return(message)};
4298- dbus_connection_send(connection, reply, nullptr);
4299- }
4300- }
4301- else if (dbus_message_is_method_call(message, dbus_screen_interface, "setInactivityTimeouts"))
4302- {
4303- int32_t poweroff_timeout{-1};
4304- int32_t dimmer_timeout{-1};
4305- dbus_message_get_args(
4306- message, &args_error,
4307- DBUS_TYPE_INT32, &poweroff_timeout,
4308- DBUS_TYPE_INT32, &dimmer_timeout,
4309- DBUS_TYPE_INVALID);
4310-
4311- if (!args_error)
4312- {
4313- dbus_setInactivityTimeouts(poweroff_timeout, dimmer_timeout);
4314-
4315- DBusMessageHandle reply{dbus_message_new_method_return(message)};
4316- dbus_connection_send(connection, reply, nullptr);
4317- }
4318- }
4319- else if (dbus_message_is_method_call(message, dbus_screen_interface, "setTouchVisualizationEnabled"))
4320- {
4321- dbus_bool_t enable{false};
4322- dbus_message_get_args(
4323- message, &args_error, DBUS_TYPE_BOOLEAN, &enable, DBUS_TYPE_INVALID);
4324-
4325- if (!args_error)
4326- {
4327- dbus_setTouchVisualizationEnabled(enable);
4328-
4329- DBusMessageHandle reply{dbus_message_new_method_return(message)};
4330- dbus_connection_send(connection, reply, nullptr);
4331- }
4332- }
4333- else if (dbus_message_is_method_call(message, dbus_screen_interface, "setScreenPowerMode"))
4334- {
4335- char const* mode = nullptr;
4336- int32_t reason{-1};
4337-
4338- dbus_message_get_args(
4339- message, &args_error,
4340- DBUS_TYPE_STRING, &mode,
4341- DBUS_TYPE_INT32, &reason,
4342- DBUS_TYPE_INVALID);
4343-
4344- if (!args_error)
4345- {
4346- auto const result = dbus_setScreenPowerMode(mode, reason);
4347- dbus_bool_t bresult = (result == true);
4348-
4349- DBusMessageHandle reply{
4350- dbus_message_new_method_return(message),
4351- DBUS_TYPE_BOOLEAN, &bresult,
4352- DBUS_TYPE_INVALID};
4353-
4354- dbus_connection_send(connection, reply, nullptr);
4355- }
4356- }
4357- else if (dbus_message_is_method_call(message, dbus_screen_interface, "keepDisplayOn"))
4358- {
4359- auto const id = dbus_keepDisplayOn(sender);
4360-
4361- DBusMessageHandle reply{
4362- dbus_message_new_method_return(message),
4363- DBUS_TYPE_INT32, &id,
4364- DBUS_TYPE_INVALID};
4365-
4366- dbus_connection_send(connection, reply, nullptr);
4367- }
4368- else if (dbus_message_is_method_call(message, dbus_screen_interface, "removeDisplayOnRequest"))
4369- {
4370- int32_t id{-1};
4371- dbus_message_get_args(
4372- message, &args_error,
4373- DBUS_TYPE_INT32, &id,
4374- DBUS_TYPE_INVALID);
4375-
4376- if (!args_error)
4377- {
4378- dbus_removeDisplayOnRequest(sender, id);
4379-
4380- DBusMessageHandle reply{dbus_message_new_method_return(message)};
4381- dbus_connection_send(connection, reply, nullptr);
4382- }
4383- }
4384- else if (dbus_message_is_signal(message, "org.freedesktop.DBus", "NameOwnerChanged"))
4385- {
4386- char const* name = nullptr;
4387- char const* old_owner = nullptr;
4388- char const* new_owner = nullptr;
4389-
4390- dbus_message_get_args(
4391- message, &args_error,
4392- DBUS_TYPE_STRING, &name,
4393- DBUS_TYPE_STRING, &old_owner,
4394- DBUS_TYPE_STRING, &new_owner,
4395- DBUS_TYPE_INVALID);
4396-
4397- if (!args_error)
4398- dbus_NameOwnerChanged(name, old_owner, new_owner);
4399- }
4400- else if (dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_METHOD_CALL)
4401- {
4402- DBusMessageHandle reply{
4403- dbus_message_new_error(message, DBUS_ERROR_FAILED, "Not supported")};
4404-
4405- dbus_connection_send(connection, reply, nullptr);
4406- }
4407-
4408- if (args_error)
4409- {
4410- DBusMessageHandle reply{
4411- dbus_message_new_error(message, DBUS_ERROR_FAILED, "Invalid arguments")};
4412-
4413- dbus_connection_send(connection, reply, nullptr);
4414- }
4415-
4416- return DBUS_HANDLER_RESULT_HANDLED;
4417-}
4418-
4419-void usc::UnityScreenService::dbus_setUserBrightness(int32_t brightness)
4420-{
4421- screen->set_brightness(brightness);
4422-}
4423-
4424-void usc::UnityScreenService::dbus_userAutobrightnessEnable(dbus_bool_t enable)
4425-{
4426- screen->enable_auto_brightness(enable == TRUE);
4427-}
4428-
4429-void usc::UnityScreenService::dbus_setInactivityTimeouts(
4430- int32_t poweroff_timeout, int32_t dimmer_timeout)
4431-{
4432- screen->set_inactivity_timeouts(poweroff_timeout, dimmer_timeout);
4433-}
4434-
4435-void usc::UnityScreenService::dbus_setTouchVisualizationEnabled(dbus_bool_t enable)
4436-{
4437- screen->set_touch_visualization_enabled(enable == TRUE);
4438-}
4439-
4440-bool usc::UnityScreenService::dbus_setScreenPowerMode(
4441- std::string const& mode,
4442- int32_t reason)
4443-{
4444- MirPowerMode new_power_mode;
4445-
4446- // Note: the "standby" and "suspend" modes are mostly unused
4447- if (mode == "on")
4448- new_power_mode = MirPowerMode::mir_power_mode_on;
4449- else if (mode == "standby") // higher power "off" mode (fastest resume)
4450- new_power_mode = MirPowerMode::mir_power_mode_standby;
4451- else if (mode == "suspend") // medium power "off" mode
4452- new_power_mode = MirPowerMode::mir_power_mode_suspend;
4453- else if (mode == "off") // lowest power "off" mode (slowest resume)
4454- new_power_mode = MirPowerMode::mir_power_mode_off;
4455- else
4456- return false;
4457-
4458- screen->set_screen_power_mode(
4459- new_power_mode, static_cast<PowerStateChangeReason>(reason));
4460-
4461- return true;
4462-}
4463-
4464-int32_t usc::UnityScreenService::dbus_keepDisplayOn(
4465- std::string const& sender)
4466-{
4467- std::lock_guard<std::mutex> lock{keep_display_on_mutex};
4468-
4469- auto const id = ++request_id;
4470-
4471- keep_display_on_ids.emplace(sender, id);
4472- screen->keep_display_on(true);
4473-
4474- return id;
4475-}
4476-
4477-void usc::UnityScreenService::dbus_removeDisplayOnRequest(
4478- std::string const& sender, int32_t id)
4479-{
4480- std::lock_guard<std::mutex> lock{keep_display_on_mutex};
4481-
4482- auto range = keep_display_on_ids.equal_range(sender);
4483- for (auto iter = range.first;
4484- iter != range.second;
4485- ++iter)
4486- {
4487- if (iter->second == id)
4488- {
4489- keep_display_on_ids.erase(iter);
4490- break;
4491- }
4492- }
4493-
4494- if (keep_display_on_ids.empty())
4495- screen->keep_display_on(false);
4496-}
4497-
4498-void usc::UnityScreenService::dbus_NameOwnerChanged(
4499- std::string const& name,
4500- std::string const& old_owner,
4501- std::string const& new_owner)
4502-{
4503- if (new_owner.empty() && old_owner == name)
4504- {
4505- std::lock_guard<std::mutex> lock{keep_display_on_mutex};
4506- keep_display_on_ids.erase(name);
4507- if (keep_display_on_ids.empty())
4508- screen->keep_display_on(false);
4509- }
4510-}
4511-
4512-void usc::UnityScreenService::dbus_emit_DisplayPowerStateChange(
4513- MirPowerMode power_mode, PowerStateChangeReason reason)
4514-{
4515- int32_t const power_state = (power_mode == MirPowerMode::mir_power_mode_off) ? 0 : 1;
4516- int32_t const reason_int = static_cast<int32_t>(reason);
4517-
4518- dbus_event_loop.enqueue(
4519- [this, power_state, reason_int]
4520- {
4521- DBusMessageHandle signal{
4522- dbus_message_new_signal(
4523- dbus_screen_path,
4524- dbus_screen_interface,
4525- "DisplayPowerStateChange"),
4526- DBUS_TYPE_INT32, &power_state,
4527- DBUS_TYPE_INT32, &reason_int,
4528- DBUS_TYPE_INVALID};
4529-
4530- dbus_connection_send(connection, signal, nullptr);
4531- });
4532-}
4533
4534=== removed file 'src/unity_screen_service.h'
4535--- src/unity_screen_service.h 2015-03-18 13:06:10 +0000
4536+++ src/unity_screen_service.h 1970-01-01 00:00:00 +0000
4537@@ -1,83 +0,0 @@
4538-/*
4539- * Copyright © 2015 Canonical Ltd.
4540- *
4541- * This program is free software: you can redistribute it and/or modify
4542- * it under the terms of the GNU General Public License version 3 as
4543- * published by the Free Software Foundation.
4544- *
4545- * This program is distributed in the hope that it will be useful,
4546- * but WITHOUT ANY WARRANTY; without even the implied warranty of
4547- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4548- * GNU General Public License for more details.
4549- *
4550- * You should have received a copy of the GNU General Public License
4551- * along with this program. If not, see <http://www.gnu.org/licenses/>.
4552- *
4553- * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>
4554- */
4555-
4556-#ifndef USC_UNITY_SCREEN_SERVICE_H_
4557-#define USC_UNITY_SCREEN_SERVICE_H_
4558-
4559-#include "dbus_event_loop.h"
4560-#include "dbus_connection_handle.h"
4561-
4562-#include <mir_toolkit/common.h>
4563-
4564-#include <cstdint>
4565-#include <memory>
4566-#include <thread>
4567-#include <atomic>
4568-#include <mutex>
4569-#include <unordered_map>
4570-
4571-enum class PowerStateChangeReason;
4572-
4573-namespace usc
4574-{
4575-class Screen;
4576-class WorkerThread;
4577-
4578-class UnityScreenService
4579-{
4580-public:
4581- UnityScreenService(
4582- std::string const& bus_addr,
4583- std::shared_ptr<usc::Screen> const& screen);
4584- ~UnityScreenService();
4585-
4586-private:
4587- void dbus_loop();
4588- void stop_loop();
4589- static ::DBusHandlerResult handle_dbus_message_thunk(
4590- DBusConnection* connection, DBusMessage* message, void* user_data);
4591- ::DBusHandlerResult handle_dbus_message(
4592- DBusConnection* connection, DBusMessage* message, void* user_data);
4593-
4594- void dbus_setUserBrightness(int32_t brightness);
4595- void dbus_userAutobrightnessEnable(dbus_bool_t enable);
4596- void dbus_setInactivityTimeouts(int32_t poweroff_timeout, int32_t dimmer_timeout);
4597- void dbus_setTouchVisualizationEnabled(dbus_bool_t enable);
4598- bool dbus_setScreenPowerMode(std::string const& mode, int32_t reason);
4599- int32_t dbus_keepDisplayOn(std::string const& sender);
4600- void dbus_removeDisplayOnRequest(std::string const& sender, int32_t id);
4601- void dbus_NameOwnerChanged(
4602- std::string const& name,
4603- std::string const& old_owner,
4604- std::string const& new_owner);
4605- void dbus_emit_DisplayPowerStateChange(
4606- MirPowerMode power_mode, PowerStateChangeReason reason);
4607-
4608- DBusConnectionHandle const connection;
4609- std::shared_ptr<usc::Screen> const screen;
4610-
4611- DBusEventLoop dbus_event_loop;
4612- std::thread dbus_loop_thread;
4613- std::mutex keep_display_on_mutex;
4614- std::unordered_multimap<std::string,int32_t> keep_display_on_ids;
4615- int32_t request_id;
4616-};
4617-
4618-}
4619-
4620-#endif
4621
4622=== removed file 'src/window_manager.cpp'
4623--- src/window_manager.cpp 2015-04-09 11:27:06 +0000
4624+++ src/window_manager.cpp 1970-01-01 00:00:00 +0000
4625@@ -1,234 +0,0 @@
4626-/*
4627- * Copyright © 2015 Canonical Ltd.
4628- *
4629- * This program is free software: you can redistribute it and/or modify it
4630- * under the terms of the GNU General Public License version 3,
4631- * as published by the Free Software Foundation.
4632- *
4633- * This program is distributed in the hope that it will be useful,
4634- * but WITHOUT ANY WARRANTY; without even the implied warranty of
4635- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4636- * GNU General Public License for more details.
4637- *
4638- * You should have received a copy of the GNU General Public License
4639- * along with this program. If not, see <http://www.gnu.org/licenses/>.
4640- *
4641- * Authored By: Alan Griffiths <alan@octopull.co.uk>
4642- */
4643-
4644-#include "window_manager.h"
4645-
4646-#include "session_switcher.h"
4647-
4648-#include "mir/geometry/rectangle.h"
4649-#include "mir/scene/null_surface_observer.h"
4650-#include "mir/scene/session.h"
4651-#include "mir/scene/session_coordinator.h"
4652-#include "mir/scene/surface.h"
4653-#include "mir/scene/surface_creation_parameters.h"
4654-#include "mir/shell/display_layout.h"
4655-#include "mir/shell/focus_controller.h"
4656-#include "mir/shell/surface_specification.h"
4657-
4658-#include "mir_toolkit/client_types.h"
4659-
4660-#include <iostream>
4661-
4662-namespace mf = mir::frontend;
4663-namespace ms = mir::scene;
4664-namespace msh = mir::shell;
4665-
4666-namespace
4667-{
4668-
4669-class UscSession : public usc::Session
4670-{
4671-public:
4672- UscSession(
4673- std::shared_ptr<ms::Session> const& scene_session,
4674- msh::FocusController& focus_controller)
4675- : scene_session{scene_session},
4676- focus_controller(focus_controller)
4677- {
4678- }
4679-
4680- std::string name()
4681- {
4682- return scene_session->name();
4683- }
4684-
4685- void show() override
4686- {
4687- scene_session->show();
4688- }
4689-
4690- void hide() override
4691- {
4692- scene_session->hide();
4693- }
4694-
4695- void raise_and_focus() override
4696- {
4697- auto const surface = scene_session->default_surface();
4698- focus_controller.raise({surface});
4699- focus_controller.set_focus_to(scene_session, surface);
4700- }
4701-
4702- bool corresponds_to(mir::frontend::Session const* s) override
4703- {
4704- return scene_session.get() == s;
4705- }
4706-
4707- std::shared_ptr<ms::Session> const scene_session;
4708- msh::FocusController& focus_controller;
4709-};
4710-
4711-
4712-struct SessionReadyObserver : ms::NullSurfaceObserver,
4713- std::enable_shared_from_this<SessionReadyObserver>
4714-{
4715- SessionReadyObserver(
4716- std::shared_ptr<usc::SessionSwitcher> const& switcher,
4717- std::shared_ptr<ms::Surface> const& surface,
4718- ms::Session const* session)
4719- : switcher{switcher},
4720- surface{surface},
4721- session{session}
4722- {
4723- }
4724-
4725- void frame_posted(int) override
4726- {
4727- ++num_frames_posted;
4728- if (num_frames_posted == num_frames_for_session_ready)
4729- {
4730- switcher->mark_ready(session);
4731- surface->remove_observer(shared_from_this());
4732- }
4733- }
4734-
4735- std::shared_ptr<usc::SessionSwitcher> const switcher;
4736- std::shared_ptr<ms::Surface> const surface;
4737- ms::Session const* const session;
4738- // We need to wait for the second frame before marking the session
4739- // as ready. The first frame posted from sessions is a blank frame.
4740- // TODO: Solve this issue at its root and remove this workaround
4741- int const num_frames_for_session_ready{2};
4742- int num_frames_posted{0};
4743-};
4744-
4745-}
4746-
4747-usc::WindowManager::WindowManager(
4748- mir::shell::FocusController* focus_controller,
4749- std::shared_ptr<mir::shell::DisplayLayout> const& display_layout,
4750- std::shared_ptr<ms::SessionCoordinator> const& session_coordinator,
4751- std::shared_ptr<SessionSwitcher> const& session_switcher) :
4752- focus_controller{focus_controller},
4753- display_layout{display_layout},
4754- session_coordinator{session_coordinator},
4755- session_switcher{session_switcher}
4756-{
4757-}
4758-
4759-void usc::WindowManager::add_session(std::shared_ptr<ms::Session> const& session)
4760-{
4761- std::cerr << "Opening session " << session->name() << std::endl;
4762-
4763- focus_controller->set_focus_to(session, {});
4764-
4765- auto const usc_session = std::make_shared<UscSession>(session, *focus_controller);
4766-
4767- session_switcher->add(usc_session, session->process_id());
4768-}
4769-
4770-void usc::WindowManager::remove_session(std::shared_ptr<ms::Session> const& session)
4771-{
4772- std::cerr << "Closing session " << session->name() << std::endl;
4773-
4774- auto const next_session = session_coordinator->successor_of({});
4775- if (next_session)
4776- focus_controller->set_focus_to(next_session, next_session->default_surface());
4777- else
4778- focus_controller->set_focus_to(next_session, {});
4779-
4780- session_switcher->remove(session);
4781-}
4782-
4783-auto usc::WindowManager::add_surface(
4784- std::shared_ptr<ms::Session> const& session,
4785- ms::SurfaceCreationParameters const& params,
4786- std::function<mf::SurfaceId(std::shared_ptr<ms::Session> const& session, ms::SurfaceCreationParameters const& params)> const& build)
4787--> mf::SurfaceId
4788-{
4789- mir::graphics::DisplayConfigurationOutputId const output_id_invalid{
4790- mir_display_output_id_invalid};
4791- auto placed_parameters = params;
4792-
4793- mir::geometry::Rectangle rect{params.top_left, params.size};
4794-
4795- if (params.output_id != output_id_invalid)
4796- {
4797- display_layout->place_in_output(params.output_id, rect);
4798- }
4799-
4800- placed_parameters.top_left = rect.top_left;
4801- placed_parameters.size = rect.size;
4802-
4803- auto const result = build(session, placed_parameters);
4804- auto const surface = session->surface(result);
4805-
4806- auto const session_ready_observer = std::make_shared<SessionReadyObserver>(
4807- session_switcher, surface, session.get());
4808-
4809- surface->add_observer(session_ready_observer);
4810-
4811- return result;
4812-}
4813-
4814-void usc::WindowManager::modify_surface(
4815- std::shared_ptr<ms::Session> const& /*session*/,
4816- std::shared_ptr<ms::Surface> const& surface,
4817- msh::SurfaceSpecification const& modifications)
4818-{
4819- if (modifications.name.is_set())
4820- surface->rename(modifications.name.value());
4821-}
4822-
4823-void usc::WindowManager::remove_surface(
4824- std::shared_ptr<ms::Session> const& /*session*/,
4825- std::weak_ptr<ms::Surface> const& /*surface*/)
4826-{
4827-}
4828-
4829-void usc::WindowManager::add_display(mir::geometry::Rectangle const& /*area*/)
4830-{
4831-}
4832-
4833-void usc::WindowManager::remove_display(mir::geometry::Rectangle const& /*area*/)
4834-{
4835-}
4836-
4837-bool usc::WindowManager::handle_keyboard_event(MirKeyboardEvent const* /*event*/)
4838-{
4839- return false;
4840-}
4841-
4842-bool usc::WindowManager::handle_touch_event(MirTouchEvent const* /*event*/)
4843-{
4844- return false;
4845-}
4846-
4847-bool usc::WindowManager::handle_pointer_event(MirPointerEvent const* /*event*/)
4848-{
4849- return false;
4850-}
4851-
4852-int usc::WindowManager::set_surface_attribute(
4853- std::shared_ptr<ms::Session> const& /*session*/,
4854- std::shared_ptr<ms::Surface> const& surface,
4855- MirSurfaceAttrib attrib,
4856- int value)
4857-{
4858- return surface->configure(attrib, value);
4859-}
4860
4861=== removed file 'src/window_manager.h'
4862--- src/window_manager.h 2015-04-09 11:27:06 +0000
4863+++ src/window_manager.h 1970-01-01 00:00:00 +0000
4864@@ -1,85 +0,0 @@
4865-/*
4866- * Copyright © 2015 Canonical Ltd.
4867- *
4868- * This program is free software: you can redistribute it and/or modify it
4869- * under the terms of the GNU General Public License version 3,
4870- * as published by the Free Software Foundation.
4871- *
4872- * This program is distributed in the hope that it will be useful,
4873- * but WITHOUT ANY WARRANTY; without even the implied warranty of
4874- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4875- * GNU General Public License for more details.
4876- *
4877- * You should have received a copy of the GNU General Public License
4878- * along with this program. If not, see <http://www.gnu.org/licenses/>.
4879- *
4880- * Authored By: Alan Griffiths <alan@octopull.co.uk>
4881- */
4882-
4883-#ifndef USC_WINDOW_MANAGER_H_
4884-#define USC_WINDOW_MANAGER_H_
4885-
4886-#include <mir/shell/window_manager.h>
4887-
4888-namespace mir
4889-{
4890-namespace scene { class PlacementStrategy; class SessionCoordinator; }
4891-namespace shell { class FocusController; class DisplayLayout; }
4892-}
4893-
4894-namespace usc
4895-{
4896-class SessionSwitcher;
4897-
4898-class WindowManager : public mir::shell::WindowManager
4899-{
4900-public:
4901- explicit WindowManager(
4902- mir::shell::FocusController* focus_controller,
4903- std::shared_ptr<mir::shell::DisplayLayout> const& display_layout,
4904- std::shared_ptr<mir::scene::SessionCoordinator> const& session_coordinator,
4905- std::shared_ptr<SessionSwitcher> const& session_switcher);
4906-
4907- void add_session(std::shared_ptr<mir::scene::Session> const& session) override;
4908-
4909- void remove_session(std::shared_ptr<mir::scene::Session> const& session) override;
4910-
4911- mir::frontend::SurfaceId add_surface(
4912- std::shared_ptr<mir::scene::Session> const& session,
4913- mir::scene::SurfaceCreationParameters const& params,
4914- std::function<mir::frontend::SurfaceId(std::shared_ptr<mir::scene::Session> const& session, mir::scene::SurfaceCreationParameters const& params)> const& build) override;
4915-
4916- void modify_surface(
4917- std::shared_ptr<mir::scene::Session> const& session,
4918- std::shared_ptr<mir::scene::Surface> const& surface,
4919- mir::shell::SurfaceSpecification const& modifications) override;
4920-
4921- void remove_surface(
4922- std::shared_ptr<mir::scene::Session> const& session,
4923- std::weak_ptr<mir::scene::Surface> const& surface) override;
4924-
4925- void add_display(mir::geometry::Rectangle const& area) override;
4926-
4927- void remove_display(mir::geometry::Rectangle const& area) override;
4928-
4929- bool handle_keyboard_event(MirKeyboardEvent const* event) override;
4930-
4931- bool handle_touch_event(MirTouchEvent const* event) override;
4932-
4933- bool handle_pointer_event(MirPointerEvent const* event) override;
4934-
4935- int set_surface_attribute(
4936- std::shared_ptr<mir::scene::Session> const& session,
4937- std::shared_ptr<mir::scene::Surface> const& surface,
4938- MirSurfaceAttrib attrib,
4939- int value) override;
4940-
4941-private:
4942- mir::shell::FocusController* const focus_controller;
4943- std::shared_ptr<mir::shell::DisplayLayout> const display_layout;
4944- std::shared_ptr<mir::scene::SessionCoordinator> const session_coordinator;
4945- std::shared_ptr<SessionSwitcher> const session_switcher;
4946-};
4947-}
4948-
4949-#endif /* USC_WINDOW_MANAGER_H_ */
4950
4951=== added file 'src/worker_thread.cpp'
4952--- src/worker_thread.cpp 1970-01-01 00:00:00 +0000
4953+++ src/worker_thread.cpp 2015-05-12 16:45:46 +0000
4954@@ -0,0 +1,142 @@
4955+/*
4956+ * Copyright © 2014 Canonical Ltd.
4957+ *
4958+ * This program is free software: you can redistribute it and/or modify it
4959+ * under the terms of the GNU General Public License version 3,
4960+ * as published by the Free Software Foundation.
4961+ *
4962+ * This program is distributed in the hope that it will be useful,
4963+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4964+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4965+ * GNU General Public License for more details.
4966+ *
4967+ * You should have received a copy of the GNU General Public License
4968+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4969+ *
4970+ * Authored by: Alberto Aguirre <alberto.aguirre@canonical.com>
4971+ */
4972+
4973+#include "worker_thread.h"
4974+
4975+#include <mir/terminate_with_current_exception.h>
4976+
4977+#include <algorithm>
4978+#include <condition_variable>
4979+#include <deque>
4980+#include <map>
4981+
4982+#ifndef _GNU_SOURCE
4983+#define _GNU_SOURCE
4984+#endif
4985+#include <pthread.h>
4986+
4987+namespace usc
4988+{
4989+
4990+class Worker
4991+{
4992+public:
4993+ explicit Worker(std::string name)
4994+ : name{name.substr(0, 15)}, exiting{false}
4995+ {
4996+ }
4997+
4998+ ~Worker()
4999+ {
5000+ exit();
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches