Merge lp:~thomas-voss/location-service/export-glib-context into lp:location-service

Proposed by Thomas Voß
Status: Merged
Approved by: Thomas Voß
Approved revision: 303
Merged at revision: 303
Proposed branch: lp:~thomas-voss/location-service/export-glib-context
Merge into: lp:location-service
Diff against target: 380 lines (+212/-31)
11 files modified
doc/api.md (+32/-21)
include/location/glib/context.h (+73/-0)
src/location/CMakeLists.txt (+1/-0)
src/location/cmds/monitor.cpp (+2/-1)
src/location/cmds/provider.cpp (+2/-1)
src/location/cmds/run.cpp (+2/-1)
src/location/cmds/status.cpp (+2/-1)
src/location/glib/context.cpp (+64/-0)
src/location/glib/runtime.cpp (+26/-5)
src/location/glib/runtime.h (+7/-0)
tests/serializing_bus_test.cpp (+1/-1)
To merge this branch: bzr merge lp:~thomas-voss/location-service/export-glib-context
Reviewer Review Type Date Requested Status
Simon Fels (community) Approve
Thomas Voß Pending
Review via email: mp+323266@code.launchpad.net

Commit message

Export location::glib::Context and enable clients to connect to the service.

Description of the change

Export location::glib::Context and enable clients to connect to the service.

To post a comment you must log in.
Revision history for this message
Simon Fels (morphis) wrote :

LGTM

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'doc/api.md'
2--- doc/api.md 2017-04-05 08:27:15 +0000
3+++ doc/api.md 2017-04-26 20:01:55 +0000
4@@ -23,25 +23,36 @@
5 the client API:
6
7 ```{cpp}
8-auto service = location::connect_to_service(...);
9-auto session = service->create_session_for_criteria(location::Criteria{});
10-
11-session->updates().position.changed().connect([this](const location::Update<location::Position>& pos)
12-{
13- std::cout << pos << std::endl;
14-});
15-
16-session->updates().heading.changed().connect([this](const location::Update<location::units::Degrees>& heading)
17-{
18- std::cout << pos << std::endl;
19-});
20-
21-session->updates().velocity.changed().connect([this](const location::Update<location::units::MetersPerSecond>& velocity)
22-{
23- std::cout << pos << std::endl;
24-});
25-
26-session->updates().position_status = location::Service::Session::Updates::Status::enabled;
27-session->updates().heading_status = location::Service::Session::Updates::Status::enabled;
28-session->updates().velocity_status = location::Service::Session::Updates::Status::enabled;
29+#include <location/service.h>
30+#include <location/session.h>
31+
32+#include <location/glib/context.h>
33+
34+auto context = location::glib::Context::create_for_system_bus();
35+
36+context->connect_to_service([context](const location::Service::Ptr& service)
37+{
38+ service->create_session_for_criteria(location::Criteria{}, [context, service](const location::Session::Ptr& session)
39+ {
40+ session->updates().position.changed().connect([this](const location::Update<location::Position>& pos)
41+ {
42+ std::cout << pos << std::endl;
43+ });
44+
45+ session->updates().heading.changed().connect([this](const location::Update<location::units::Degrees>& heading)
46+ {
47+ std::cout << pos << std::endl;
48+ });
49+
50+ session->updates().velocity.changed().connect([this](const location::Update<location::units::MetersPerSecond>& velocity)
51+ {
52+ std::cout << pos << std::endl;
53+ });
54+
55+ session->updates().position_status = location::Service::Session::Updates::Status::enabled;
56+ session->updates().heading_status = location::Service::Session::Updates::Status::enabled;
57+ session->updates().velocity_status = location::Service::Session::Updates::Status::enabled;
58+ });
59+});
60+
61 ```
62
63=== added directory 'include/location/glib'
64=== added file 'include/location/glib/context.h'
65--- include/location/glib/context.h 1970-01-01 00:00:00 +0000
66+++ include/location/glib/context.h 2017-04-26 20:01:55 +0000
67@@ -0,0 +1,73 @@
68+/*
69+ * Copyright © 2017 Canonical Ltd.
70+ *
71+ * This program is free software: you can redistribute it and/or modify it
72+ * under the terms of the GNU Lesser General Public License version 3,
73+ * as published by the Free Software Foundation.
74+ *
75+ * This program is distributed in the hope that it will be useful,
76+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
77+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
78+ * GNU Lesser General Public License for more details.
79+ *
80+ * You should have received a copy of the GNU Lesser General Public License
81+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
82+ *
83+ * Authored by: Thomas Voß <thomas.voss@canonical.com>
84+ */
85+#ifndef LOCATION_GLIB_CONTEXT_H_
86+#define LOCATION_GLIB_CONTEXT_H_
87+
88+#include <location/service.h>
89+#include <location/visibility.h>
90+
91+#include <functional>
92+#include <memory>
93+
94+namespace location
95+{
96+namespace glib
97+{
98+
99+/// @brief A Context bundles together runtime resources for
100+/// accessing a locationd service instance.
101+///
102+/// Note that both create_* functions assume that they are invoked
103+/// on a thread with a valid GMainContext. More to this, the resulting
104+/// Context instance will be associated with the GMainContext.
105+class LOCATION_DLL_PUBLIC Context
106+{
107+public:
108+ /// @brief Callback handles receiving of Service instances.
109+ typedef std::function<void(const Service::Ptr&)> Callback;
110+
111+ /// @brief create_for_system_bus connects to a service instance
112+ /// on the system bus.
113+ static std::shared_ptr<Context> create_for_system_bus();
114+
115+ /// @brief create_for_session_bus connects to a service instance
116+ /// on the session bus.
117+ static std::shared_ptr<Context> create_for_session_bus();
118+
119+ /// @cond
120+ Context(const Context&) = delete;
121+ Context(Context&&) = delete;
122+ virtual ~Context();
123+ Context& operator=(const Context&) = delete;
124+ Context& operator=(Context&&) = delete;
125+ /// @endcond
126+
127+ /// @brief connect_to_service tries to establish a connection
128+ /// to a service instance.
129+ virtual void connect_to_service(const Callback& cb) = 0;
130+
131+protected:
132+ /// @cond
133+ Context();
134+ /// @endcond
135+};
136+
137+} // namespace glib
138+} // namespace location
139+
140+#endif // LOCATION_GLIB_CONTEXT_H_
141
142=== modified file 'src/location/CMakeLists.txt'
143--- src/location/CMakeLists.txt 2017-04-05 12:34:53 +0000
144+++ src/location/CMakeLists.txt 2017-04-26 20:01:55 +0000
145@@ -123,6 +123,7 @@
146 events/reference_position_updated.cpp
147 events/wifi_and_cell_id_reporting_state_changed.cpp
148
149+ glib/context.cpp
150 glib/holder.h
151 glib/runtime.h
152 glib/runtime.cpp
153
154=== modified file 'src/location/cmds/monitor.cpp'
155--- src/location/cmds/monitor.cpp 2017-03-07 10:01:34 +0000
156+++ src/location/cmds/monitor.cpp 2017-04-26 20:01:55 +0000
157@@ -55,7 +55,8 @@
158 flag(cli::make_flag(cli::Name{"bus"}, cli::Description{"bus instance to connect to, defaults to system"}, bus));
159 action([this](const Context& ctxt)
160 {
161- glib::Runtime runtime;
162+ glib::Runtime runtime{glib::Runtime::WithOwnMainLoop{}};
163+ runtime.redirect_logging();
164
165 location::dbus::stub::Service::create(bus, [this, &ctxt](const Result<location::dbus::stub::Service::Ptr>& result) mutable
166 {
167
168=== modified file 'src/location/cmds/provider.cpp'
169--- src/location/cmds/provider.cpp 2017-03-07 10:01:34 +0000
170+++ src/location/cmds/provider.cpp 2017-04-26 20:01:55 +0000
171@@ -47,7 +47,8 @@
172 {
173 die_if(not id, ctxt.cout, "name of actual provider implementation is missing");
174
175- glib::Runtime runtime;
176+ glib::Runtime runtime{glib::Runtime::WithOwnMainLoop{}};
177+ runtime.redirect_logging();
178
179 location::dbus::stub::Service::create(bus, [this](const location::Result<location::dbus::stub::Service::Ptr>& result)
180 {
181
182=== modified file 'src/location/cmds/run.cpp'
183--- src/location/cmds/run.cpp 2017-03-23 12:32:38 +0000
184+++ src/location/cmds/run.cpp 2017-04-26 20:01:55 +0000
185@@ -49,7 +49,8 @@
186 {
187 account_for_lp1447110();
188
189- glib::Runtime runtime;
190+ glib::Runtime runtime{glib::Runtime::WithOwnMainLoop{}};
191+ runtime.redirect_logging();
192
193 // The engine instance is the core piece of functionality.
194 auto engine = std::make_shared<location::Engine>(
195
196=== modified file 'src/location/cmds/status.cpp'
197--- src/location/cmds/status.cpp 2017-03-07 10:01:34 +0000
198+++ src/location/cmds/status.cpp 2017-04-26 20:01:55 +0000
199@@ -58,7 +58,8 @@
200 flag(cli::make_flag(cli::Name{"bus"}, cli::Description{"bus instance to connect to, defaults to system"}, bus));
201 action([this](const Context& ctxt)
202 {
203- location::glib::Runtime runtime;
204+ glib::Runtime runtime{glib::Runtime::WithOwnMainLoop{}};
205+ runtime.redirect_logging();
206
207 location::dbus::stub::Service::create(bus, [this, &ctxt](const location::Result<location::dbus::stub::Service::Ptr>& result)
208 {
209
210=== added file 'src/location/glib/context.cpp'
211--- src/location/glib/context.cpp 1970-01-01 00:00:00 +0000
212+++ src/location/glib/context.cpp 2017-04-26 20:01:55 +0000
213@@ -0,0 +1,64 @@
214+/*
215+ * Copyright © 2017 Canonical Ltd.
216+ *
217+ * This program is free software: you can redistribute it and/or modify it
218+ * under the terms of the GNU Lesser General Public License version 3,
219+ * as published by the Free Software Foundation.
220+ *
221+ * This program is distributed in the hope that it will be useful,
222+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
223+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
224+ * GNU Lesser General Public License for more details.
225+ *
226+ * You should have received a copy of the GNU Lesser General Public License
227+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
228+ *
229+ * Authored by: Thomas Voß <thomas.voss@canonical.com>
230+ */
231+
232+#include <location/glib/context.h>
233+
234+#include <location/result.h>
235+#include <location/dbus/stub/service.h>
236+#include <location/glib/runtime.h>
237+
238+#include <thread>
239+
240+namespace
241+{
242+
243+class Context : public location::glib::Context
244+{
245+public:
246+ Context(location::dbus::Bus bus) : bus_{bus}
247+ {
248+ }
249+
250+ void connect_to_service(const Callback& cb) override
251+ {
252+ location::dbus::stub::Service::create(bus_, [this, cb](const location::Result<location::dbus::stub::Service::Ptr>& result)
253+ {
254+ if (result)
255+ cb(result.value());
256+ });
257+ }
258+
259+private:
260+ location::dbus::Bus bus_;
261+ location::glib::Runtime runtime_;
262+};
263+
264+} // namespace
265+
266+std::shared_ptr<location::glib::Context> location::glib::Context::create_for_system_bus()
267+{
268+ return std::make_shared<::Context>(location::dbus::Bus::system);
269+}
270+
271+std::shared_ptr<location::glib::Context> location::glib::Context::create_for_session_bus()
272+{
273+ return std::make_shared<::Context>(location::dbus::Bus::session);
274+}
275+
276+location::glib::Context::~Context() = default;
277+location::glib::Context::Context() = default;
278
279=== modified file 'src/location/glib/runtime.cpp'
280--- src/location/glib/runtime.cpp 2017-03-07 10:01:34 +0000
281+++ src/location/glib/runtime.cpp 2017-04-26 20:01:55 +0000
282@@ -88,36 +88,57 @@
283 }
284
285 location::glib::Runtime::Runtime()
286+ : main_loop_{nullptr},
287+ event_fd_{event_fd_or_throw()},
288+ signal_fd_{-1},
289+ event_fd_input_stream{make_shared_object(g_unix_input_stream_new(event_fd_, true))}
290+{
291+ g_input_stream_read_async(event_fd_input_stream.get(), &event_fd_buffer, sizeof(event_fd_buffer), G_PRIORITY_LOW,
292+ nullptr, Runtime::on_event_fd_read_finished, this);
293+
294+ runtime = this;
295+}
296+
297+location::glib::Runtime::Runtime(WithOwnMainLoop)
298 : main_loop_{g_main_loop_new(nullptr, false)},
299 event_fd_{event_fd_or_throw()},
300 signal_fd_{signal_fd_or_throw()},
301 event_fd_input_stream{make_shared_object(g_unix_input_stream_new(event_fd_, true))},
302 signal_fd_input_stream{make_shared_object(g_unix_input_stream_new(signal_fd_, true))}
303 {
304- g_log_set_default_handler(handle_log_message, nullptr);
305+ g_input_stream_read_async(event_fd_input_stream.get(), &event_fd_buffer, sizeof(event_fd_buffer), G_PRIORITY_LOW,
306+ nullptr, Runtime::on_event_fd_read_finished, this);
307
308 g_input_stream_read_async(signal_fd_input_stream.get(), &signal_fd_buffer, sizeof(signal_fd_buffer), G_PRIORITY_LOW,
309 nullptr, Runtime::on_signal_fd_read_finished, this);
310- g_input_stream_read_async(event_fd_input_stream.get(), &event_fd_buffer, sizeof(event_fd_buffer), G_PRIORITY_LOW,
311- nullptr, Runtime::on_event_fd_read_finished, this);
312-
313 runtime = this;
314 }
315
316 location::glib::Runtime::~Runtime()
317 {
318- g_main_loop_unref(main_loop_);
319+ if (main_loop_)
320+ g_main_loop_unref(main_loop_);
321 runtime = nullptr;
322 }
323
324+void location::glib::Runtime::redirect_logging()
325+{
326+ g_log_set_default_handler(handle_log_message, nullptr);
327+}
328+
329 int location::glib::Runtime::run()
330 {
331+ if (!main_loop_)
332+ throw std::runtime_error{"Missing main loop"};
333 g_main_loop_run(main_loop_);
334+
335 return EXIT_SUCCESS;
336 }
337
338 void location::glib::Runtime::stop()
339 {
340+ if (!main_loop_)
341+ throw std::runtime_error{"Missing main loop"};
342 g_main_loop_quit(main_loop_);
343 }
344
345
346=== modified file 'src/location/glib/runtime.h'
347--- src/location/glib/runtime.h 2017-03-04 21:43:23 +0000
348+++ src/location/glib/runtime.h 2017-04-26 20:01:55 +0000
349@@ -37,11 +37,18 @@
350 class LOCATION_DLL_PUBLIC Runtime
351 {
352 public:
353+ struct WithOwnMainLoop {};
354+
355 static Runtime* instance();
356
357 Runtime();
358+ explicit Runtime(WithOwnMainLoop);
359 ~Runtime();
360
361+ // redirect_logging interacts with the glib runtime
362+ // to redirect logging to location::Logging facilities.
363+ void redirect_logging();
364+
365 // executes the underlying event loop and blocks until
366 // the runtime is stopped or a SIGINT/SIGTERM is delivered
367 // to the application.
368
369=== modified file 'tests/serializing_bus_test.cpp'
370--- tests/serializing_bus_test.cpp 2017-03-04 21:43:23 +0000
371+++ tests/serializing_bus_test.cpp 2017-04-26 20:01:55 +0000
372@@ -52,7 +52,7 @@
373 {
374 using namespace ::testing;
375
376- location::glib::Runtime runtime;
377+ location::glib::Runtime runtime{location::glib::Runtime::WithOwnMainLoop{}};
378
379 auto sb = location::glib::SerializingBus::create();
380 auto receiver = std::make_shared<NiceMock<MockEventReceiver>>();

Subscribers

People subscribed via source and target branches

to all changes: