Merge lp:~thomas-voss/location-service/simplify-provider-interface into lp:location-service

Proposed by Thomas Voß
Status: Merged
Approved by: Thomas Voß
Approved revision: 263
Merged at revision: 263
Proposed branch: lp:~thomas-voss/location-service/simplify-provider-interface
Merge into: lp:location-service
Prerequisite: lp:~thomas-voss/location-service/remove-obsolete-code-and-targets
Diff against target: 8744 lines (+2869/-4340)
84 files modified
include/location/criteria.h (+6/-23)
include/location/event.h (+106/-0)
include/location/events/reference_position_updated.h (+59/-0)
include/location/events/wifi_and_cell_id_reporting_state_changed.h (+58/-0)
include/location/features.h (+49/-0)
include/location/provider.h (+50/-232)
src/location/CMakeLists.txt (+15/-8)
src/location/bus.h (+45/-0)
src/location/cmds/provider.cpp (+1/-1)
src/location/cmds/run.cpp (+7/-4)
src/location/criteria.cpp (+0/-99)
src/location/dbus/codec.h (+320/-53)
src/location/dbus/skeleton/service.cpp (+13/-3)
src/location/dbus/skeleton/session.cpp (+6/-6)
src/location/dbus/skeleton/session.h (+1/-0)
src/location/dbus/stub/service.cpp (+1/-0)
src/location/default_provider_selection_policy.cpp (+0/-135)
src/location/default_provider_selection_policy.h (+0/-49)
src/location/dummy_service.cpp (+0/-55)
src/location/dummy_service.h (+0/-55)
src/location/engine.cpp (+32/-64)
src/location/engine.h (+6/-7)
src/location/event.cpp (+26/-0)
src/location/events/all.h (+46/-0)
src/location/events/reference_position_updated.cpp (+55/-0)
src/location/events/registry.cpp (+65/-0)
src/location/events/registry.h (+65/-0)
src/location/events/wifi_and_cell_id_reporting_state_changed.cpp (+55/-0)
src/location/fusion_provider_selection_policy.cpp (+6/-3)
src/location/non_selecting_provider_selection_policy.cpp (+5/-6)
src/location/provider.cpp (+0/-191)
src/location/provider_selection.h (+0/-14)
src/location/providers/CMakeLists.txt (+1/-2)
src/location/providers/config.cpp (+0/-25)
src/location/providers/dummy/provider.cpp (+64/-68)
src/location/providers/dummy/provider.h (+29/-10)
src/location/providers/fusion/CMakeLists.txt (+4/-0)
src/location/providers/fusion/newer_or_more_accurate_update_selector.h (+11/-5)
src/location/providers/fusion/newer_update_selector.h (+1/-1)
src/location/providers/fusion/provider.cpp (+105/-113)
src/location/providers/fusion/provider.h (+40/-22)
src/location/providers/fusion/update_selector.h (+1/-1)
src/location/providers/geoclue/CMakeLists.txt (+0/-24)
src/location/providers/geoclue/geoclue.h (+0/-257)
src/location/providers/geoclue/provider.cpp (+0/-165)
src/location/providers/geoclue/provider.h (+0/-106)
src/location/providers/gps/provider.cpp (+43/-26)
src/location/providers/gps/provider.h (+21/-11)
src/location/providers/proxy.cpp (+95/-0)
src/location/providers/proxy.h (+59/-0)
src/location/providers/remote/interface.h (+24/-147)
src/location/providers/remote/provider.cpp (+400/-596)
src/location/providers/remote/provider.h (+83/-58)
src/location/providers/remote/stub.cpp (+2/-2)
src/location/providers/remote/stub.h (+9/-2)
src/location/providers/skyhook/CMakeLists.txt (+0/-40)
src/location/providers/skyhook/provider.cpp (+0/-206)
src/location/providers/skyhook/provider.h (+0/-96)
src/location/providers/state_tracking_provider.cpp (+139/-0)
src/location/providers/state_tracking_provider.h (+93/-0)
src/location/proxy_provider.cpp (+0/-79)
src/location/proxy_provider.h (+0/-58)
src/location/runtime.h (+1/-1)
src/location/serializing_bus.cpp (+47/-0)
src/location/serializing_bus.h (+52/-0)
src/location/service_with_engine.cpp (+12/-18)
src/location/session_with_provider.cpp (+9/-9)
src/location/state_tracking_provider.h (+0/-156)
src/location/util/flags.h (+53/-0)
tests/CMakeLists.txt (+4/-6)
tests/acceptance_tests.cpp (+25/-15)
tests/controller_test.cpp (+0/-132)
tests/criteria_test.cpp (+0/-48)
tests/engine_test.cpp (+19/-45)
tests/espoo_provider_test.cpp (+11/-3)
tests/event_test.cpp (+57/-0)
tests/mock_provider.h (+21/-32)
tests/provider_selection_policy_test.cpp (+0/-217)
tests/provider_test.cpp (+0/-441)
tests/reference_position_updated_test.cpp (+59/-0)
tests/remote_provider_test.cpp (+30/-51)
tests/serializing_bus_test.cpp (+78/-0)
tests/state_tracking_provider_test.cpp (+31/-38)
tests/wifi_and_cell_id_reporting_state_changed_test.cpp (+38/-0)
To merge this branch: bzr merge lp:~thomas-voss/location-service/simplify-provider-interface
Reviewer Review Type Date Requested Status
Simon Fels (community) Approve
Thomas Voß Pending
Review via email: mp+302795@code.launchpad.net

Commit message

Simplify the location::Provider interface.

Move all state-machine semantics into the implementation and
only expose a pure virtual interface for providers to implement.
Remove specific event-handlers and instead go fo an extensible location::Event
with location::Provider extending on location::Event::Receiver. With that, we
can easily extend events going forward in an ABI compatible way.

Description of the change

Simplify the location::Provider interface.

Move all state-machine semantics into the implementation and
only expose a pure virtual interface for providers to implement.
Remove specific event-handlers and instead go fo an extensible location::Event
with location::Provider extending on location::Event::Receiver. With that, we
can easily extend events going forward in an ABI compatible way.

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 'include/location/criteria.h'
2--- include/location/criteria.h 2016-06-26 21:17:03 +0000
3+++ include/location/criteria.h 2016-08-12 12:03:50 +0000
4@@ -18,6 +18,7 @@
5 #ifndef LOCATION_CRITERIA_H_
6 #define LOCATION_CRITERIA_H_
7
8+#include <location/features.h>
9 #include <location/optional.h>
10 #include <location/units/units.h>
11
12@@ -29,34 +30,16 @@
13 */
14 struct Criteria
15 {
16- /**
17- * @brief satisfies checks whether this instance also satisfies another criteria instance.
18- * @param rhs The other criteria instance
19- * @return true iff this instance also satisfies the other instance, else false.
20- */
21- bool satisfies(const Criteria& rhs) const;
22-
23- struct Requires
24- {
25- bool position = true; ///< The client needs position measurements.
26- bool altitude = false; ///< The client needs altitude measurements.
27- bool velocity = false; ///< The client needs velocity measurments.
28- bool heading = false; ///< The client needs heading measurements.
29- } requires = Requires{};
30+ Features requirements; ///< These features are required.
31
32 struct Accuracy
33 {
34- units::Quantity<units::Length> horizontal = 3000 * units::Meters; ///< The client requires measurements of at least this horizontal accuracy.
35- Optional<units::Quantity<units::Length>> vertical; ///< The client requires measurements of at least this vertical accuracy.
36- Optional<units::Quantity<units::Velocity>> velocity; ///< The client requires measurements of at least this velocity accuracy.
37- Optional<units::Quantity<units::PlaneAngle>> heading; ///< The client requires measurements of at least this heading accuracy.
38+ Optional<units::Quantity<units::Length>> horizontal; ///< The client requires measurements of at least this horizontal accuracy.
39+ Optional<units::Quantity<units::Length>> vertical; ///< The client requires measurements of at least this vertical accuracy.
40+ Optional<units::Quantity<units::Velocity>> velocity; ///< The client requires measurements of at least this velocity accuracy.
41+ Optional<units::Quantity<units::PlaneAngle>> heading; ///< The client requires measurements of at least this heading accuracy.
42 } accuracy = Accuracy{};
43 };
44-
45-/**
46- * @brief operator + merges lhs and rhs such that satisfying the new criteria satisfies lhs and rhs.
47- */
48-Criteria operator+(const Criteria& lhs, const Criteria& rhs);
49 }
50
51 #endif // LOCATION_CRITERIA_H_
52
53=== added file 'include/location/event.h'
54--- include/location/event.h 1970-01-01 00:00:00 +0000
55+++ include/location/event.h 2016-08-12 12:03:50 +0000
56@@ -0,0 +1,106 @@
57+/*
58+ * Copyright © 2016 Canonical Ltd.
59+ *
60+ * This program is free software: you can redistribute it and/or modify it
61+ * under the terms of the GNU Lesser General Public License version 3,
62+ * as published by the Free Software Foundation.
63+ *
64+ * This program is distributed in the hope that it will be useful,
65+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
66+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
67+ * GNU Lesser General Public License for more details.
68+ *
69+ * You should have received a copy of the GNU Lesser General Public License
70+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
71+ *
72+ * Authored by: Thomas Voß <thomas.voss@canonical.com>
73+ */
74+#ifndef LOCATION_EVENT_H_
75+#define LOCATION_EVENT_H_
76+
77+#include <memory>
78+
79+namespace location
80+{
81+/// @brief Event models the base of an event hierarchy used to pass
82+/// system- and session-wide events to providers and sessions.
83+class Event
84+{
85+public:
86+ // Safe us some typing
87+ typedef std::shared_ptr<Event> Ptr;
88+
89+ /// @brief Receiver models handling of incoming messages.
90+ class Receiver
91+ {
92+ public:
93+ // Safe us some typing.
94+ typedef std::shared_ptr<Receiver> Ptr;
95+
96+ /// @cond
97+ virtual ~Receiver() = default;
98+ Receiver(const Receiver&) = delete;
99+ Receiver(Receiver&&) = delete;
100+ Receiver& operator=(const Receiver&) = delete;
101+ Receiver& operator=(Receiver&&) = delete;
102+ /// @endcond
103+
104+ /// on_new_event is invoked for every new event.
105+ virtual void on_new_event(const Event& event) = 0;
106+
107+ protected:
108+ Receiver() = default;
109+ };
110+
111+ /// @brief Type enumerates all known types.
112+ ///
113+ /// Not an enum class on purpose.
114+ enum Type
115+ {
116+ first_user_defined_type = 1024
117+ };
118+
119+ /// @brief next_user_defined_type returns the next available slot for a user-defined type.
120+ static Type next_user_defined_type(const std::string& name);
121+
122+ /// @brief register_type makes T known to the bus and assigns it a unique Type.
123+ template<typename T>
124+ static Type register_type(const std::string& name);
125+
126+ /// @cond
127+ virtual ~Event() = default;
128+
129+ Event(const Event&) = delete;
130+ Event(Event&&) = delete;
131+ Event& operator=(const Event&) = delete;
132+ Event& operator=(Event&&) = delete;
133+ /// @endcond
134+
135+ /// @brief type returns the Type of the message.
136+ virtual Type type() const = 0;
137+
138+ /// @cond
139+ Event() = default;
140+ /// @endcond
141+};
142+
143+/// @brief TypeOf enables calling code to check for a specific event type.
144+template<typename T>
145+struct TypeOf
146+{
147+ /// @brief Query returns the Event::Type registered for T.
148+ ///
149+ /// Left unimplemented on purpose, to provoke linker errors.
150+ /// in the non-specialized case.
151+ static Event::Type query();
152+};
153+
154+template<typename T>
155+Event::Type Event::register_type(const std::string& name)
156+{
157+ static Event::Type type{Event::next_user_defined_type(name)};
158+ return type;
159+}
160+}
161+
162+#endif // LOCATION_EVENT_H_
163
164=== added directory 'include/location/events'
165=== added file 'include/location/events/reference_position_updated.h'
166--- include/location/events/reference_position_updated.h 1970-01-01 00:00:00 +0000
167+++ include/location/events/reference_position_updated.h 2016-08-12 12:03:50 +0000
168@@ -0,0 +1,59 @@
169+/*
170+ * Copyright © 2016 Canonical Ltd.
171+ *
172+ * This program is free software: you can redistribute it and/or modify it
173+ * under the terms of the GNU Lesser General Public License version 3,
174+ * as published by the Free Software Foundation.
175+ *
176+ * This program is distributed in the hope that it will be useful,
177+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
178+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
179+ * GNU Lesser General Public License for more details.
180+ *
181+ * You should have received a copy of the GNU Lesser General Public License
182+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
183+ *
184+ * Authored by: Thomas Voß <thomas.voss@canonical.com>
185+ */
186+
187+#ifndef LOCATION_EVENTS_REFERENCE_POSITION_UPDATED_H_
188+#define LOCATION_EVENTS_REFERENCE_POSITION_UPDATED_H_
189+
190+#include <location/event.h>
191+
192+#include <location/position.h>
193+#include <location/update.h>
194+
195+namespace location
196+{
197+namespace events
198+{
199+/// @brief ReferencePositionUpdated is sent if the reference position has been updated.
200+class ReferencePositionUpdated : public Event
201+{
202+public:
203+ /// @brief ReferencePositionUpdated initializes a new instance with update.
204+ ReferencePositionUpdated(const Update<Position>& update);
205+ /// @brief ReferencePositionUpdated initializes a new instance from rhs.
206+ ReferencePositionUpdated(const ReferencePositionUpdated& rhs);
207+ /// @brief operator= assigns rhs to this instance.
208+ ReferencePositionUpdated& operator=(const ReferencePositionUpdated& rhs);
209+
210+ /// @brief update returns the contained update.
211+ const Update<Position>& update() const;
212+
213+ // From Bus::Message
214+ Type type() const override;
215+
216+private:
217+ Update<Position> update_;
218+};
219+}
220+template<>
221+struct TypeOf<events::ReferencePositionUpdated>
222+{
223+ static Event::Type query();
224+};
225+}
226+
227+#endif // LOCATION_EVENTS_REFERENCE_POSITION_UPDATED_H_
228
229=== added file 'include/location/events/wifi_and_cell_id_reporting_state_changed.h'
230--- include/location/events/wifi_and_cell_id_reporting_state_changed.h 1970-01-01 00:00:00 +0000
231+++ include/location/events/wifi_and_cell_id_reporting_state_changed.h 2016-08-12 12:03:50 +0000
232@@ -0,0 +1,58 @@
233+/*
234+ * Copyright © 2016 Canonical Ltd.
235+ *
236+ * This program is free software: you can redistribute it and/or modify it
237+ * under the terms of the GNU Lesser General Public License version 3,
238+ * as published by the Free Software Foundation.
239+ *
240+ * This program is distributed in the hope that it will be useful,
241+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
242+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
243+ * GNU Lesser General Public License for more details.
244+ *
245+ * You should have received a copy of the GNU Lesser General Public License
246+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
247+ *
248+ * Authored by: Thomas Voß <thomas.voss@canonical.com>
249+ */
250+
251+#ifndef LOCATION_EVENTS_WIFI_AND_CELL_ID_REPORTING_STATE_CHANGED_H_
252+#define LOCATION_EVENTS_WIFI_AND_CELL_ID_REPORTING_STATE_CHANGED_H_
253+
254+#include <location/event.h>
255+
256+#include <location/wifi_and_cell_reporting_state.h>
257+
258+namespace location
259+{
260+namespace events
261+{
262+/// @brief WifiAndCellIdReportingStateChanged is sent if the WifiAndCellIdReportingState changed.
263+class WifiAndCellIdReportingStateChanged : public Event
264+{
265+public:
266+ /// @brief WifiAndCellIdReportingStateChanged initializes a new instance with new_state.
267+ WifiAndCellIdReportingStateChanged(WifiAndCellIdReportingState new_state);
268+ /// @brief WifiAndCellIdReportingStateChanged initializes a new instance from rhs.
269+ WifiAndCellIdReportingStateChanged(const WifiAndCellIdReportingStateChanged& rhs);
270+ /// @brief operator= assigns rhs to this instance.
271+ WifiAndCellIdReportingStateChanged& operator=(const WifiAndCellIdReportingStateChanged& rhs);
272+
273+ /// @brief new_state returns the new state.
274+ WifiAndCellIdReportingState new_state() const;
275+
276+ // From Bus::Message
277+ Type type() const override;
278+
279+private:
280+ WifiAndCellIdReportingState new_state_;
281+};
282+}
283+template<>
284+struct TypeOf<events::WifiAndCellIdReportingStateChanged>
285+{
286+ static Event::Type query();
287+};
288+}
289+
290+#endif // LOCATION_EVENTS_WIFI_AND_CELL_ID_REPORTING_STATE_CHANGED_H_
291
292=== added file 'include/location/features.h'
293--- include/location/features.h 1970-01-01 00:00:00 +0000
294+++ include/location/features.h 2016-08-12 12:03:50 +0000
295@@ -0,0 +1,49 @@
296+/*
297+ * Copyright © 2016 Canonical Ltd.
298+ *
299+ * This program is free software: you can redistribute it and/or modify it
300+ * under the terms of the GNU Lesser General Public License version 3,
301+ * as published by the Free Software Foundation.
302+ *
303+ * This program is distributed in the hope that it will be useful,
304+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
305+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
306+ * GNU Lesser General Public License for more details.
307+ *
308+ * You should have received a copy of the GNU Lesser General Public License
309+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
310+ *
311+ * Authored by: Thomas Voß <thomas.voss@canonical.com>
312+ */
313+
314+#ifndef LOCATION_FEATURES_H_
315+#define LOCATION_FEATURES_H_
316+
317+#include <iosfwd>
318+
319+namespace location
320+{
321+/**
322+ * @brief Enumerates the known features that can be supported by providers.
323+ */
324+enum class Features : std::size_t
325+{
326+ none = 0, ///< The provider does not support any feature.
327+ position = 1 << 0, ///< The provider features position updates.
328+ velocity = 1 << 1, ///< The provider features velocity updates.
329+ heading = 1 << 2 ///< The provider features heading updates.
330+};
331+
332+/** @brief operator| returns the bitwise or of lhs and rhs. */
333+Features operator|(Features lhs, Features rhs);
334+/** @brief operator& returns the bitwise and of lhs and rhs. */
335+Features operator&(Features lhs, Features rhs);
336+
337+/** @brief operator<< inserts features into out. */
338+std::ostream& operator<<(std::ostream& out, Features features);
339+
340+/** @brief operator>> extracts features from in. */
341+std::istream& operator>>(std::istream& in, Features& features);
342+}
343+
344+#endif // LOCATION_FEATURES_H_
345
346=== modified file 'include/location/provider.h'
347--- include/location/provider.h 2016-06-26 21:17:03 +0000
348+++ include/location/provider.h 2016-08-12 12:03:50 +0000
349@@ -18,7 +18,9 @@
350 #ifndef LOCATION_PROVIDER_H_
351 #define LOCATION_PROVIDER_H_
352
353+#include <location/configuration.h>
354 #include <location/criteria.h>
355+#include <location/event.h>
356 #include <location/heading.h>
357 #include <location/position.h>
358 #include <location/space_vehicle.h>
359@@ -35,251 +37,67 @@
360
361 namespace location
362 {
363-/**
364- * @brief The Provider class is the abstract base of all positioning providers.
365- */
366-class Provider
367+/// @brief The Provider class is the abstract base of all positioning providers.
368+class Provider : public Event::Receiver
369 {
370 public:
371- typedef std::shared_ptr<Provider> Ptr;
372-
373- /**
374- * @brief Enumerates the known features that can be supported by providers.
375- */
376- enum class Features : std::size_t
377- {
378- none = 0, ///< The provider does not support any feature.
379- position = 1 << 0, ///< The provider features position updates.
380- velocity = 1 << 1, ///< The provider features velocity updates.
381- heading = 1 << 2 ///< The provider features heading updates.
382- };
383-
384- /**
385- * @brief Enumerates the requirements of a provider implementation.
386- */
387+ typedef std::shared_ptr<Provider> Ptr;
388+
389+ /// @brief Enumerates the requirements of a provider implementation.
390 enum class Requirements : std::size_t
391 {
392- none = 0, ///< The provider does not require anything.
393- satellites = 1 << 0, ///< The provider requires satellites to be visible.
394- cell_network = 1 << 1, ///< The provider requires a cell-network to work correctly.
395- data_network = 1 << 2, ///< The provider requires a data-network to work correctly.
396- monetary_spending = 1 << 3 ///< Using the provider results in monetary cost.
397- };
398-
399- /**
400- * @brief Facade for controlling the state of position/heading/velocity updates.
401- *
402- * Multiple observers can request state changes for updates. This class ensures
403- * that the specific updates are started and stopped if at least one observer
404- * requests them and stopped when the last observer issues a stop request.
405- */
406- class Controller
407- {
408- public:
409- typedef std::shared_ptr<Controller> Ptr;
410-
411- virtual ~Controller() = default;
412- Controller(const Controller&) = delete;
413- Controller& operator=(const Controller&) = delete;
414-
415- /**
416- * @brief disable switches the provider to a disabled state, such that subsequent
417- * calls to start* methods fail.
418- */
419- void disable();
420-
421- /**
422- * @brief enable switches the provider to an enabled state, such that subsequent
423- * calls to start* methods succeed.
424- */
425- void enable();
426-
427- /**
428- * @brief Request to start position updates if not already running.
429- */
430- virtual void start_position_updates();
431-
432- /**
433- * @brief Request to stop position updates. Only stops the provider when the last observer calls this function.
434- */
435- virtual void stop_position_updates();
436-
437- /**
438- * @brief Checks if position updates are currently running.
439- * @return true iff position updates are currently running.
440- */
441- bool are_position_updates_running() const;
442-
443- /**
444- * @brief Request to start heading updates if not already running.
445- */
446- virtual void start_heading_updates();
447-
448- /**
449- * @brief Request to stop heading updates. Only stops the provider when the last observer calls this function.
450- */
451- virtual void stop_heading_updates();
452-
453- /**
454- * @brief Checks if position updates are currently running.
455- * @return true iff position updates are currently running.
456- */
457- bool are_heading_updates_running() const;
458-
459- /**
460- * @brief Request to start velocity updates if not already running.
461- */
462- virtual void start_velocity_updates();
463-
464- /**
465- * @brief Request to stop velocity updates. Only stops the provider when the last observer calls this function.
466- */
467- virtual void stop_velocity_updates();
468-
469- /**
470- * @brief Checks if velocity updates are currently running.
471- * @return true iff velocity updates are currently running.
472- */
473- bool are_velocity_updates_running() const;
474-
475- protected:
476- friend class Provider;
477- explicit Controller(Provider& instance);
478-
479- private:
480- Provider& instance;
481- std::atomic<int> position_updates_counter;
482- std::atomic<int> heading_updates_counter;
483- std::atomic<int> velocity_updates_counter;
484- };
485-
486- /**
487- * @brief Wraps all updates that can be delivered by a provider.
488- */
489- struct Updates
490- {
491- /** Position updates. */
492- core::Signal<Update<Position>> position;
493- /** Heading updates. */
494- core::Signal<Update<Heading>> heading;
495- /** Velocity updates. */
496- core::Signal<Update<Velocity>> velocity;
497- /** Space vehicle visibility updates. */
498- core::Signal<Update<std::set<SpaceVehicle>>> svs;
499- };
500-
501+ none = 0, ///< The provider does not require anything.
502+ satellites = 1 << 0, ///< The provider requires satellites to be visible.
503+ cell_network = 1 << 1, ///< The provider requires a cell-network to work correctly.
504+ data_network = 1 << 2, ///< The provider requires a data-network to work correctly.
505+ monetary_spending = 1 << 3 ///< Using the provider results in monetary cost.
506+ };
507+
508+ /// @cond
509 virtual ~Provider() = default;
510
511 Provider(const Provider&) = delete;
512+ Provider(Provider&&) = delete;
513 Provider& operator=(const Provider&) = delete;
514-
515- /**
516- * @brief Provides non-mutable access to this provider's updates.
517- * @return A non-mutable reference to the updates.
518- */
519- virtual const Updates& updates() const;
520-
521- /**
522- * @brief Access to the controller facade of this provider instance.
523- */
524- virtual const Controller::Ptr& state_controller() const;
525-
526- /**
527- * @brief Checks if the provider supports a specific feature.
528- * @param f Feature to test for
529- * @return true iff the provider supports the feature.
530- */
531- virtual bool supports(const Features& f) const;
532-
533- /**
534- * @brief Checks if the provider has got a specific requirement.
535- * @param r Requirement to test for.
536- * @return true iff the provider has the specific requirement.
537- */
538- virtual bool requires(const Requirements& r) const;
539-
540- /**
541- * @brief Checks if a provider satisfies a set of accuracy criteria.
542- * @param [in] criteria The criteria to check.
543- * @return true iff the provider satisfies the given criteria.
544- */
545- virtual bool matches_criteria(const Criteria& criteria);
546-
547- /**
548- * @brief Called by the engine whenever the wifi and cell ID reporting state changes.
549- * @param state The new state.
550- */
551- virtual void on_wifi_and_cell_reporting_state_changed(WifiAndCellIdReportingState state);
552-
553- /**
554- * @brief Called by the engine whenever the reference location changed.
555- * @param position The new reference location.
556- */
557- virtual void on_reference_location_updated(const Update<Position>& position);
558-
559- /**
560- * @brief Called by the engine whenever the reference velocity changed.
561- * @param velocity The new reference velocity.
562- */
563- virtual void on_reference_velocity_updated(const Update<Velocity>& velocity);
564-
565- /**
566- * @brief Called by the engine whenever the reference heading changed.
567- * @param heading The new reference heading.
568- */
569- virtual void on_reference_heading_updated(const Update<Heading>& heading);
570+ Provider& operator=(Provider&&) = delete;
571+ /// @endcond
572+
573+ /// @brief enable enables the provider, throws in case of issues.
574+ virtual void enable() = 0;
575+
576+ /// @brief start disables the provider, throws in case of issues.
577+ virtual void disable() = 0;
578+
579+ /// @brief activate triggers a state transition from enabled to active.
580+ virtual void activate() = 0;
581+
582+ /// @brief deactivate triggers a state transition from active to enabled.
583+ virtual void deactivate() = 0;
584+
585+ /// @brief requirements returns the requirements of the provider.
586+ virtual Requirements requirements() const = 0;
587+
588+ /// @brief Checks if a provider satisfies criteria.
589+ /// @param [in] criteria The criteria to check.
590+ /// @return true iff the provider satisfies the given criteria.
591+ virtual bool satisfies(const Criteria& criteria) = 0;
592+
593+ /// @brief position_updates returns a signal delivering position updates.
594+ virtual const core::Signal<Update<Position>>& position_updates() const = 0;
595+
596+ /// @brief heading_updates returns a signal delivering heading updates.
597+ virtual const core::Signal<Update<Heading>>& heading_updates() const = 0;
598+
599+ /// @brief velocity_updates returns a signal delivering velocity updates.
600+ virtual const core::Signal<Update<Velocity>>& velocity_updates() const = 0;
601
602 protected:
603- explicit Provider(
604- const Features& features = Features::none,
605- const Requirements& requirements = Requirements::none);
606-
607- virtual Updates& mutable_updates();
608-
609- /**
610- * @brief Implementation-specific, empty by default.
611- */
612- virtual void start_position_updates();
613-
614- /**
615- * @brief Implementation-specific, empty by default.
616- */
617- virtual void stop_position_updates();
618-
619- /**
620- * @brief Implementation-specific, empty by default.
621- */
622- virtual void start_heading_updates();
623-
624- /**
625- * @brief Implementation-specific, empty by default.
626- */
627- virtual void stop_heading_updates();
628-
629- /**
630- * @brief Implementation-specific, empty by default.
631- */
632- virtual void start_velocity_updates();
633-
634- /**
635- * @brief Implementation-specific, empty by default.
636- */
637- virtual void stop_velocity_updates();
638-
639-private:
640- struct
641- {
642- Features features = Features::none;
643- Requirements requirements = Requirements::none;
644- Updates updates;
645- Controller::Ptr controller = Controller::Ptr{};
646- } d;
647+ Provider() = default;
648 };
649
650-Provider::Features operator|(Provider::Features lhs, Provider::Features rhs);
651-Provider::Features operator&(Provider::Features lhs, Provider::Features rhs);
652-
653+/// @brief operator| returns the bitwise or of lhs and rhs.
654 Provider::Requirements operator|(Provider::Requirements lhs, Provider::Requirements rhs);
655+/// @brief operator& returns the bitwise and of lhs and rhs.
656 Provider::Requirements operator&(Provider::Requirements lhs, Provider::Requirements rhs);
657 }
658
659
660=== modified file 'src/location/CMakeLists.txt'
661--- src/location/CMakeLists.txt 2016-08-12 12:03:49 +0000
662+++ src/location/CMakeLists.txt 2016-08-12 12:03:50 +0000
663@@ -15,20 +15,16 @@
664
665 ${UBUNTU_LOCATION_SERVICE_PUBLIC_HEADERS}
666
667- default_provider_selection_policy.cpp
668 fusion_provider_selection_policy.cpp
669 non_selecting_provider_selection_policy.cpp
670
671- criteria.cpp
672 engine.cpp
673- fusion_provider.cpp
674+ event.cpp
675 position.cpp
676 provider.cpp
677 provider_factory.cpp
678- proxy_provider.cpp
679 satellite_based_positioning_state.cpp
680 settings.cpp
681- state_tracking_provider.h
682 time_based_update_policy.cpp
683 set_name_for_thread.cpp
684 time_since_boot.cpp
685@@ -40,14 +36,13 @@
686 daemon.cpp
687 service.cpp
688
689- dummy_service.h
690- dummy_service.cpp
691-
692 permission_manager.h
693 runtime.h
694 runtime.cpp
695 runtime_tests.h
696 runtime_tests.cpp
697+ serializing_bus.h
698+ serializing_bus.cpp
699 service_with_engine.h
700 service_with_engine.cpp
701 session_with_provider.h
702@@ -85,11 +80,23 @@
703 dbus/stub/session.h
704 dbus/stub/session.cpp
705
706+ events/all.h
707+ events/registry.h
708+ events/registry.cpp
709+ events/reference_position_updated.cpp
710+ events/wifi_and_cell_id_reporting_state_changed.cpp
711+
712 providers/config.cpp
713
714+ providers/fusion/provider.h
715+ providers/fusion/provider.cpp
716 providers/remote/provider.cpp
717 providers/remote/skeleton.cpp
718 providers/remote/stub.cpp
719+ providers/proxy.h
720+ providers/proxy.cpp
721+ providers/state_tracking_provider.h
722+ providers/state_tracking_provider.cpp
723 )
724
725 add_library(
726
727=== added file 'src/location/bus.h'
728--- src/location/bus.h 1970-01-01 00:00:00 +0000
729+++ src/location/bus.h 2016-08-12 12:03:50 +0000
730@@ -0,0 +1,45 @@
731+/*
732+ * Copyright © 2016 Canonical Ltd.
733+ *
734+ * This program is free software: you can redistribute it and/or modify it
735+ * under the terms of the GNU Lesser General Public License version 3,
736+ * as published by the Free Software Foundation.
737+ *
738+ * This program is distributed in the hope that it will be useful,
739+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
740+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
741+ * GNU Lesser General Public License for more details.
742+ *
743+ * You should have received a copy of the GNU Lesser General Public License
744+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
745+ *
746+ * Authored by: Thomas Voß <thomas.voss@canonical.com>
747+ */
748+#ifndef LOCATION_BUS_H_
749+#define LOCATION_BUS_H_
750+
751+#include <location/event.h>
752+
753+#include <memory>
754+
755+namespace location
756+{
757+/// @brief Bus provides a simple way for distributing events to multiple listeners.
758+class Bus
759+{
760+public:
761+ // Safe us some typing
762+ typedef std::shared_ptr<Bus> Ptr;
763+
764+ /// @brief subscribe makes receiver known to the bus.
765+ virtual void subscribe(const Event::Receiver::Ptr& receiver) = 0;
766+
767+ /// @brief unsubscribe removes receiver from the bus.
768+ virtual void unsubscribe(const Event::Receiver::Ptr& receiver) = 0;
769+
770+ /// @brief dispatch takes eventand hands it to all subscribed receivers.
771+ virtual void dispatch(const Event::Ptr& event) = 0;
772+};
773+}
774+
775+#endif // LOCATION_BUS_H_
776
777=== modified file 'src/location/cmds/provider.cpp'
778--- src/location/cmds/provider.cpp 2016-08-12 12:03:49 +0000
779+++ src/location/cmds/provider.cpp 2016-08-12 12:03:50 +0000
780@@ -51,7 +51,7 @@
781 die_if(not id, ctxt.cout, "name of actual provider implementation is missing");
782
783 // We exit cleanly for SIGINT and SIGTERM.
784- auto trap = core::posix::trap_signals_for_all_subsequent_threads({core::posix::Signal::sig_int, core::posix::Signal::sig_term});
785+ auto trap = core::posix::trap_signals_for_all_subsequent_threads({core::posix::Signal::sig_term});
786 trap->signal_raised().connect([trap](core::posix::Signal)
787 {
788 trap->stop();
789
790=== modified file 'src/location/cmds/run.cpp'
791--- src/location/cmds/run.cpp 2016-08-12 12:03:49 +0000
792+++ src/location/cmds/run.cpp 2016-08-12 12:03:50 +0000
793@@ -22,6 +22,7 @@
794 #include <location/boost_ptree_settings.h>
795 #include <location/fusion_provider_selection_policy.h>
796 #include <location/runtime.h>
797+#include <location/serializing_bus.h>
798 #include <location/service_with_engine.h>
799 #include <location/settings.h>
800 #include <location/trust_store_permission_manager.h>
801@@ -51,17 +52,21 @@
802 account_for_lp1447110();
803
804 // We exit cleanly for SIGINT and SIGTERM.
805- auto trap = core::posix::trap_signals_for_all_subsequent_threads({core::posix::Signal::sig_int, core::posix::Signal::sig_term});
806+ auto trap = core::posix::trap_signals_for_all_subsequent_threads({core::posix::Signal::sig_term});
807 trap->signal_raised().connect([trap](core::posix::Signal)
808 {
809 trap->stop();
810 });
811
812+ auto rt = location::Runtime::create();
813+
814 // The engine instance is the core piece of functionality.
815 auto engine = std::make_shared<location::Engine>(
816 // We default to a fusion provider selection policy, providing
817 // fusioned and filtered updates to sessions.
818 std::make_shared<location::FusionProviderSelectionPolicy>(),
819+ // We serialize all messages passed through our internal bus via a specific strand on the runtime.
820+ location::SerializingBus::create(rt),
821 // We default to a location::Settings implementation that reads state from
822 // an ini file, immediately syncing back changes to the underlying file whenever
823 // parameters change.
824@@ -72,9 +77,7 @@
825 {
826 ctxt.cout << "Running under testing..." << std::endl;
827 engine->add_provider(std::make_shared<location::providers::dummy::Provider>());
828- }
829-
830- auto rt = location::Runtime::create();
831+ }
832
833 auto incoming = std::make_shared<core::dbus::Bus>(bus);
834 auto outgoing = std::make_shared<core::dbus::Bus>(bus);
835
836=== removed file 'src/location/criteria.cpp'
837--- src/location/criteria.cpp 2016-06-26 21:17:03 +0000
838+++ src/location/criteria.cpp 1970-01-01 00:00:00 +0000
839@@ -1,99 +0,0 @@
840-/*
841- * Copyright © 2012-2013 Canonical Ltd.
842- *
843- * This program is free software: you can redistribute it and/or modify it
844- * under the terms of the GNU Lesser General Public License version 3,
845- * as published by the Free Software Foundation.
846- *
847- * This program is distributed in the hope that it will be useful,
848- * but WITHOUT ANY WARRANTY; without even the implied warranty of
849- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
850- * GNU Lesser General Public License for more details.
851- *
852- * You should have received a copy of the GNU Lesser General Public License
853- * along with this program. If not, see <http://www.gnu.org/licenses/>.
854- *
855- * Authored by: Thomas Voß <thomas.voss@canonical.com>
856- */
857-
858-#include <location/criteria.h>
859-
860-bool location::Criteria::satisfies(const location::Criteria& rhs) const
861-{
862- bool result = false;
863-
864- if (rhs.requires.position)
865- result &= requires.position;
866-
867- if (rhs.requires.altitude)
868- result &= requires.altitude;
869-
870- if (rhs.requires.heading)
871- result &= requires.heading;
872-
873- if (rhs.requires.velocity)
874- result &= requires.velocity;
875-
876- result &= accuracy.horizontal <= rhs.accuracy.horizontal;
877-
878- if (rhs.accuracy.vertical)
879- result &= accuracy.vertical && accuracy.vertical <= rhs.accuracy.vertical;
880-
881- if (rhs.accuracy.heading)
882- result &= accuracy.heading && accuracy.heading <= rhs.accuracy.heading;
883-
884- if (rhs.accuracy.velocity)
885- result &= accuracy.velocity && accuracy.velocity <= rhs.accuracy.velocity;
886-
887- return result;
888-}
889-
890-location::Criteria location::operator+(
891- const location::Criteria& lhs,
892- const location::Criteria& rhs)
893-{
894- Criteria result{lhs};
895-
896- result.requires.position |= rhs.requires.position;
897- result.requires.velocity |= rhs.requires.velocity;
898- result.requires.heading |= rhs.requires.heading;
899- result.requires.altitude |= rhs.requires.altitude;
900-
901- if (rhs.accuracy.horizontal < result.accuracy.horizontal)
902- result.accuracy.horizontal = rhs.accuracy.horizontal;
903-
904- if (result.accuracy.vertical)
905- {
906- if (rhs.accuracy.vertical && rhs.accuracy.vertical < result.accuracy.vertical)
907- {
908- result.accuracy.vertical = rhs.accuracy.vertical;
909- }
910- } else
911- {
912- result.accuracy.vertical = rhs.accuracy.vertical;
913- }
914-
915- if (result.accuracy.velocity)
916- {
917- if (rhs.accuracy.velocity && rhs.accuracy.velocity < result.accuracy.velocity)
918- {
919- result.accuracy.velocity = rhs.accuracy.velocity;
920- }
921- } else
922- {
923- result.accuracy.velocity = rhs.accuracy.velocity;
924- }
925-
926- if (result.accuracy.heading)
927- {
928- if (rhs.accuracy.heading && rhs.accuracy.heading < result.accuracy.heading)
929- {
930- result.accuracy.heading = rhs.accuracy.heading;
931- }
932- } else
933- {
934- result.accuracy.heading = rhs.accuracy.heading;
935- }
936-
937- return result;
938-}
939
940=== modified file 'src/location/dbus/codec.h'
941--- src/location/dbus/codec.h 2016-08-12 12:03:49 +0000
942+++ src/location/dbus/codec.h 2016-08-12 12:03:50 +0000
943@@ -19,6 +19,7 @@
944 #define LOCATION_CODEC_H_
945
946 #include <location/criteria.h>
947+#include <location/features.h>
948 #include <location/heading.h>
949 #include <location/position.h>
950 #include <location/provider.h>
951@@ -26,6 +27,10 @@
952 #include <location/update.h>
953 #include <location/velocity.h>
954 #include <location/service.h>
955+#include <location/events/all.h>
956+#include <location/events/registry.h>
957+#include <location/events/reference_position_updated.h>
958+#include <location/events/wifi_and_cell_id_reporting_state_changed.h>
959 #include <location/units/units.h>
960 #include <location/wgs84/altitude.h>
961 #include <location/wgs84/latitude.h>
962@@ -107,6 +112,31 @@
963 return s;
964 }
965 };
966+
967+template<typename T>
968+struct TypeMapper<location::Optional<T>>
969+{
970+ constexpr static ArgumentType type_value()
971+ {
972+ return ArgumentType::structure;
973+ }
974+
975+ constexpr static bool is_basic_type()
976+ {
977+ return false;
978+ }
979+
980+ constexpr static bool requires_signature()
981+ {
982+ return true;
983+ }
984+
985+ static std::string signature()
986+ {
987+ static const std::string s = DBUS_STRUCT_BEGIN_CHAR_AS_STRING + TypeMapper<bool>::signature() + DBUS_TYPE_VARIANT_AS_STRING + DBUS_STRUCT_END_CHAR_AS_STRING;
988+ return s;
989+ }
990+};
991 }
992
993 template<typename T>
994@@ -114,24 +144,43 @@
995 {
996 static void encode_argument(Message::Writer& writer, const location::Optional<T>& in)
997 {
998- bool has_value{in};
999- Codec<bool>::encode_argument(writer, has_value);
1000- if (has_value)
1001- Codec<typename location::Optional<T>::value_type>::encode_argument(writer, *in);
1002+ auto sw = writer.open_structure();
1003+ {
1004+ bool has_value{in};
1005+ Codec<bool>::encode_argument(sw, has_value);
1006+
1007+ if (has_value)
1008+ {
1009+ auto vw = sw.open_variant(types::Signature{helper::TypeMapper<T>::signature()});
1010+ Codec<T>::encode_argument(vw, *in);
1011+ sw.close_variant(std::move(vw));
1012+ }
1013+ else
1014+ {
1015+ auto vw = sw.open_variant(types::Signature{helper::TypeMapper<bool>::signature()});
1016+ Codec<bool>::encode_argument(vw, false);
1017+ sw.close_variant(std::move(vw));
1018+ }
1019+ }
1020+ writer.close_structure(std::move(sw));
1021 }
1022
1023 static void decode_argument(Message::Reader& reader, location::Optional<T>& in)
1024 {
1025- bool has_value{false};
1026- Codec<bool>::decode_argument(reader, has_value);
1027- if (has_value)
1028- {
1029- typename location::Optional<T>::value_type value;
1030- Codec<typename location::Optional<T>::value_type>::decode_argument(reader, value);
1031- in = value;
1032- } else
1033- {
1034- in.reset();
1035+ auto sr = reader.pop_structure();
1036+ {
1037+ bool has_value{false};
1038+ Codec<bool>::decode_argument(sr, has_value);
1039+ auto vr = sr.pop_variant();
1040+ if (has_value)
1041+ {
1042+ T value;
1043+ Codec<T>::decode_argument(vr, value);
1044+ in = value;
1045+ } else
1046+ {
1047+ in.reset();
1048+ }
1049 }
1050 }
1051 };
1052@@ -152,6 +201,33 @@
1053 }
1054 };
1055
1056+namespace helper
1057+{
1058+template<typename T, typename U>
1059+struct TypeMapper<location::wgs84::Coordinate<T, U>>
1060+{
1061+ constexpr static ArgumentType type_value()
1062+ {
1063+ return TypeMapper<location::units::Quantity<U>>::type_value();
1064+ }
1065+
1066+ constexpr static bool is_basic_type()
1067+ {
1068+ return true;
1069+ }
1070+ constexpr static bool requires_signature()
1071+ {
1072+ return true;
1073+ }
1074+
1075+ static std::string signature()
1076+ {
1077+ static const std::string s = TypeMapper<location::units::Quantity<U>>::signature();
1078+ return s;
1079+ }
1080+};
1081+}
1082+
1083 template<typename T, typename U>
1084 struct Codec<location::wgs84::Coordinate<T,U>>
1085 {
1086@@ -166,6 +242,40 @@
1087 }
1088 };
1089
1090+namespace helper
1091+{
1092+template<>
1093+struct TypeMapper<location::Position>
1094+{
1095+ constexpr static ArgumentType type_value()
1096+ {
1097+ return ArgumentType::structure;
1098+ }
1099+
1100+ constexpr static bool is_basic_type()
1101+ {
1102+ return false;
1103+ }
1104+ constexpr static bool requires_signature()
1105+ {
1106+ return true;
1107+ }
1108+
1109+ static std::string signature()
1110+ {
1111+ static const std::string s =
1112+ DBUS_STRUCT_BEGIN_CHAR_AS_STRING +
1113+ TypeMapper<location::wgs84::Latitude>::signature() +
1114+ TypeMapper<location::wgs84::Longitude>::signature() +
1115+ TypeMapper<location::Optional<location::wgs84::Altitude>>::signature() +
1116+ TypeMapper<location::Optional<location::Position::Accuracy::Horizontal>>::signature() +
1117+ TypeMapper<location::Optional<location::Position::Accuracy::Vertical>>::signature() +
1118+ DBUS_STRUCT_END_CHAR_AS_STRING;
1119+ return s;
1120+ }
1121+};
1122+}
1123+
1124 template<>
1125 struct Codec<location::Position>
1126 {
1127@@ -174,22 +284,29 @@
1128
1129 static void encode_argument(Message::Writer& writer, const location::Position& in)
1130 {
1131- Codec<location::wgs84::Latitude>::encode_argument(writer, in.latitude);
1132- Codec<location::wgs84::Longitude>::encode_argument(writer, in.longitude);
1133- Codec<location::Optional<location::wgs84::Altitude>>::encode_argument(writer, in.altitude);
1134+ auto vw = writer.open_structure();
1135+ {
1136+ Codec<location::wgs84::Latitude>::encode_argument(vw, in.latitude);
1137+ Codec<location::wgs84::Longitude>::encode_argument(vw, in.longitude);
1138+ Codec<location::Optional<location::wgs84::Altitude>>::encode_argument(vw, in.altitude);
1139
1140- Codec<location::Optional<HorizontalAccuracy>>::encode_argument(writer, in.accuracy.horizontal);
1141- Codec<location::Optional<VerticalAccuracy>>::encode_argument(writer, in.accuracy.vertical);
1142+ Codec<location::Optional<HorizontalAccuracy>>::encode_argument(vw, in.accuracy.horizontal);
1143+ Codec<location::Optional<VerticalAccuracy>>::encode_argument(vw, in.accuracy.vertical);
1144+ }
1145+ writer.close_structure(std::move(vw));
1146 }
1147
1148 static void decode_argument(Message::Reader& reader, location::Position& in)
1149 {
1150- Codec<location::wgs84::Latitude>::decode_argument(reader, in.latitude);
1151- Codec<location::wgs84::Longitude>::decode_argument(reader, in.longitude);
1152- Codec<location::Optional<location::wgs84::Altitude>>::decode_argument(reader, in.altitude);
1153+ auto vr = reader.pop_structure();
1154+ {
1155+ Codec<location::wgs84::Latitude>::decode_argument(vr, in.latitude);
1156+ Codec<location::wgs84::Longitude>::decode_argument(vr, in.longitude);
1157+ Codec<location::Optional<location::wgs84::Altitude>>::decode_argument(vr, in.altitude);
1158
1159- Codec<location::Optional<HorizontalAccuracy>>::decode_argument(reader, in.accuracy.horizontal);
1160- Codec<location::Optional<VerticalAccuracy>>::decode_argument(reader, in.accuracy.vertical);
1161+ Codec<location::Optional<HorizontalAccuracy>>::decode_argument(vr, in.accuracy.horizontal);
1162+ Codec<location::Optional<VerticalAccuracy>>::decode_argument(vr, in.accuracy.vertical);
1163+ }
1164 }
1165 };
1166
1167@@ -355,6 +472,53 @@
1168 };
1169
1170 template<>
1171+struct Codec<location::Features>
1172+{
1173+ static void encode_argument(Message::Writer& writer, const location::Features& in)
1174+ {
1175+ writer.push_int32(static_cast<std::int32_t>(in));
1176+ }
1177+
1178+ static void decode_argument(Message::Reader& reader, location::Features& in)
1179+ {
1180+ in = static_cast<location::Features>(reader.pop_int32());
1181+ }
1182+};
1183+
1184+namespace helper
1185+{
1186+template<>
1187+struct TypeMapper<location::Criteria>
1188+{
1189+ constexpr static ArgumentType type_value()
1190+ {
1191+ return ArgumentType::structure;
1192+ }
1193+ constexpr static bool is_basic_type()
1194+ {
1195+ return false;
1196+ }
1197+ constexpr static bool requires_signature()
1198+ {
1199+ return true;
1200+ }
1201+
1202+ inline static std::string signature()
1203+ {
1204+ std::string s =
1205+ DBUS_STRUCT_BEGIN_CHAR_AS_STRING +
1206+ TypeMapper<std::int32_t>::signature() +
1207+ TypeMapper<location::Optional<location::Position::Accuracy::Horizontal>>::signature() +
1208+ TypeMapper<location::Optional<location::Position::Accuracy::Vertical>>::signature() +
1209+ TypeMapper<location::Optional<location::units::Quantity<location::units::Velocity>>>::signature() +
1210+ TypeMapper<location::Optional<location::units::Quantity<location::units::PlaneAngle>>>::signature() +
1211+ DBUS_STRUCT_END_CHAR_AS_STRING;
1212+ return s;
1213+ }
1214+};
1215+}
1216+
1217+template<>
1218 struct Codec<location::Criteria>
1219 {
1220 typedef location::units::Quantity<location::units::Length> HorizontalAccuracy;
1221@@ -364,12 +528,9 @@
1222
1223 static void encode_argument(Message::Writer& writer, const location::Criteria& in)
1224 {
1225- Codec<bool>::encode_argument(writer, in.requires.position);
1226- Codec<bool>::encode_argument(writer, in.requires.altitude);
1227- Codec<bool>::encode_argument(writer, in.requires.heading);
1228- Codec<bool>::encode_argument(writer, in.requires.velocity);
1229+ Codec<location::Features>::encode_argument(writer, in.requirements);
1230
1231- Codec<HorizontalAccuracy>::encode_argument(writer, in.accuracy.horizontal);
1232+ Codec<location::Optional<HorizontalAccuracy>>::encode_argument(writer, in.accuracy.horizontal);
1233 Codec<location::Optional<VerticalAccuracy>>::encode_argument(writer, in.accuracy.vertical);
1234 Codec<location::Optional<VelocityAccuracy>>::encode_argument(writer, in.accuracy.velocity);
1235 Codec<location::Optional<HeadingAccuracy>>::encode_argument(writer, in.accuracy.heading);
1236@@ -377,12 +538,9 @@
1237
1238 static void decode_argument(Message::Reader& reader, location::Criteria& in)
1239 {
1240- Codec<bool>::decode_argument(reader, in.requires.position);
1241- Codec<bool>::decode_argument(reader, in.requires.altitude);
1242- Codec<bool>::decode_argument(reader, in.requires.heading);
1243- Codec<bool>::decode_argument(reader, in.requires.velocity);
1244+ Codec<location::Features>::decode_argument(reader, in.requirements);
1245
1246- Codec<HorizontalAccuracy>::decode_argument(reader, in.accuracy.horizontal);
1247+ Codec<location::Optional<HorizontalAccuracy>>::decode_argument(reader, in.accuracy.horizontal);
1248 Codec<location::Optional<VerticalAccuracy>>::decode_argument(reader, in.accuracy.vertical);
1249 Codec<location::Optional<VelocityAccuracy>>::decode_argument(reader, in.accuracy.velocity);
1250 Codec<location::Optional<HeadingAccuracy>>::decode_argument(reader, in.accuracy.heading);
1251@@ -390,20 +548,6 @@
1252 };
1253
1254 template<>
1255-struct Codec<location::Provider::Features>
1256-{
1257- static void encode_argument(Message::Writer& writer, const location::Provider::Features& in)
1258- {
1259- writer.push_int32(static_cast<std::int32_t>(in));
1260- }
1261-
1262- static void decode_argument(Message::Reader& reader, location::Provider::Features& in)
1263- {
1264- in = static_cast<location::Provider::Features>(reader.pop_int32());
1265- }
1266-};
1267-
1268-template<>
1269 struct Codec<location::Provider::Requirements>
1270 {
1271 static void encode_argument(Message::Writer& writer, const location::Provider::Requirements& in)
1272@@ -417,6 +561,33 @@
1273 }
1274 };
1275
1276+namespace helper
1277+{
1278+template<>
1279+struct TypeMapper<location::WifiAndCellIdReportingState>
1280+{
1281+ constexpr static ArgumentType type_value()
1282+ {
1283+ return ArgumentType::int32;
1284+ }
1285+ constexpr static bool is_basic_type()
1286+ {
1287+ return true;
1288+ }
1289+
1290+ constexpr static bool requires_signature()
1291+ {
1292+ return true;
1293+ }
1294+
1295+ static std::string signature()
1296+ {
1297+ static const std::string s = helper::TypeMapper<std::int32_t>::signature();
1298+ return s;
1299+ }
1300+};
1301+}
1302+
1303 template<>
1304 struct Codec<location::WifiAndCellIdReportingState>
1305 {
1306@@ -452,8 +623,10 @@
1307 static std::string signature()
1308 {
1309 static const std::string s =
1310+ DBUS_STRUCT_BEGIN_CHAR_AS_STRING +
1311 helper::TypeMapper<T>::signature() +
1312- helper::TypeMapper<uint64_t>::signature();
1313+ helper::TypeMapper<int64_t>::signature() +
1314+ DBUS_STRUCT_END_CHAR_AS_STRING;
1315 return s;
1316 }
1317 };
1318@@ -464,16 +637,110 @@
1319 {
1320 static void encode_argument(Message::Writer& writer, const location::Update<T>& in)
1321 {
1322- Codec<T>::encode_argument(writer, in.value);
1323- Codec<int64_t>::encode_argument(writer, in.when.time_since_epoch().count());
1324+ auto sw = writer.open_structure();
1325+ {
1326+ Codec<T>::encode_argument(sw, in.value);
1327+ Codec<int64_t>::encode_argument(sw, in.when.time_since_epoch().count());
1328+ }
1329+ writer.close_structure(std::move(sw));
1330 }
1331
1332 static void decode_argument(Message::Reader& reader, location::Update<T>& in)
1333 {
1334- Codec<T>::decode_argument(reader, in.value);
1335- in.when = location::Clock::Timestamp(location::Clock::Duration(reader.pop_int64()));
1336+ auto sr = reader.pop_structure();
1337+ Codec<T>::decode_argument(sr, in.value);
1338+ in.when = location::Clock::Timestamp(location::Clock::Duration(sr.pop_int64()));
1339 }
1340 };
1341+
1342+template<>
1343+struct Codec<location::events::ReferencePositionUpdated>
1344+{
1345+ static void encode_argument(Message::Writer& out, const location::events::ReferencePositionUpdated& event)
1346+ {
1347+ Codec<location::Update<location::Position>>::encode_argument(out, event.update());
1348+ }
1349+
1350+ static void decode_argument(Message::Reader& in, location::events::ReferencePositionUpdated& event)
1351+ {
1352+ location::Update<location::Position> update;
1353+ Codec<location::Update<location::Position>>::decode_argument(in, update);
1354+ event = location::events::ReferencePositionUpdated{update};
1355+ }
1356+};
1357+
1358+template<>
1359+struct Codec<location::events::WifiAndCellIdReportingStateChanged>
1360+{
1361+ static void encode_argument(Message::Writer& out, const location::events::WifiAndCellIdReportingStateChanged& event)
1362+ {
1363+ Codec<location::WifiAndCellIdReportingState>::encode_argument(out, event.new_state());
1364+ }
1365+
1366+ static void decode_argument(Message::Reader& in, location::events::WifiAndCellIdReportingStateChanged& event)
1367+ {
1368+ location::WifiAndCellIdReportingState new_state;
1369+ Codec<location::WifiAndCellIdReportingState>::decode_argument(in, new_state);
1370+ event = location::events::WifiAndCellIdReportingStateChanged{new_state};
1371+ }
1372+};
1373+
1374+template<>
1375+struct Codec<location::events::All>
1376+{
1377+ static void encode_argument(Message::Writer& out, const location::events::All& event)
1378+ {
1379+ switch (event.which())
1380+ {
1381+ case 1:
1382+ {
1383+ const auto& ev = boost::get<location::events::ReferencePositionUpdated>(event);
1384+ auto name = location::events::Registry::instance().find(ev.type());
1385+ out.push_stringn(name.c_str(), name.size());
1386+ auto vw = out.open_variant(types::Signature{helper::TypeMapper<location::Update<location::Position>>::signature()});
1387+ {
1388+ Codec<location::events::ReferencePositionUpdated>::encode_argument(vw, ev);
1389+ }
1390+ out.close_variant(std::move(vw));
1391+ break;
1392+ }
1393+ case 2:
1394+ {
1395+ const auto& ev = boost::get<location::events::WifiAndCellIdReportingStateChanged>(event);
1396+ auto name = location::events::Registry::instance().find(ev.type());
1397+ out.push_stringn(name.c_str(), name.size());
1398+ auto vw = out.open_variant(types::Signature{helper::TypeMapper<location::WifiAndCellIdReportingState>::signature()});
1399+ {
1400+ Codec<location::events::WifiAndCellIdReportingStateChanged>::encode_argument(vw, ev);
1401+ }
1402+ out.close_variant(std::move(vw));
1403+ break;
1404+ }
1405+ }
1406+ }
1407+
1408+ static void decode_argument(Message::Reader& in, location::events::All& event)
1409+ {
1410+ std::string name{in.pop_string()};
1411+
1412+ auto type = location::events::Registry::instance().find(name);
1413+
1414+ if (type == location::TypeOf<location::events::ReferencePositionUpdated>::query())
1415+ {
1416+ location::events::ReferencePositionUpdated ev{location::Update<location::Position>{}};
1417+ auto vr = in.pop_variant();
1418+ Codec<location::events::ReferencePositionUpdated>::decode_argument(vr, ev);
1419+ event = ev;
1420+ }
1421+ else if (type == location::TypeOf<location::events::WifiAndCellIdReportingStateChanged>::query())
1422+ {
1423+ location::events::WifiAndCellIdReportingStateChanged ev{location::WifiAndCellIdReportingState::off};
1424+ auto vr = in.pop_variant();
1425+ Codec<location::events::WifiAndCellIdReportingStateChanged>::decode_argument(vr, ev);
1426+ event = ev;
1427+ }
1428+ }
1429+};
1430 }
1431 }
1432
1433
1434=== modified file 'src/location/dbus/skeleton/service.cpp'
1435--- src/location/dbus/skeleton/service.cpp 2016-08-12 12:03:49 +0000
1436+++ src/location/dbus/skeleton/service.cpp 2016-08-12 12:03:50 +0000
1437@@ -150,13 +150,22 @@
1438
1439 try
1440 {
1441+ auto thiz = shared_from_this(); std::weak_ptr<Service> wp{thiz};
1442+
1443 std::string sender = msg->sender();
1444 core::dbus::types::ObjectPath path; msg->reader() >> path;
1445- auto service = core::dbus::Service::use_service(configuration.outgoing, sender);
1446+ auto service = core::dbus::Service::use_service(configuration.incoming, sender);
1447 auto object = service->object_for_path(path);
1448
1449- add_provider(location::providers::remote::stub::create_with_configuration({object}));
1450- configuration.outgoing->send(core::dbus::Message::make_method_return(msg));
1451+ location::providers::remote::stub::create_with_configuration({configuration.outgoing, service, object}, [wp, msg](const Provider::Ptr& provider)
1452+ {
1453+ if (auto sp = wp.lock())
1454+ {
1455+ sp->add_provider(provider);
1456+ sp->configuration.outgoing->send(core::dbus::Message::make_method_return(msg));
1457+ }
1458+ });
1459+
1460 }
1461 catch(...)
1462 {
1463@@ -215,6 +224,7 @@
1464 auto watcher = daemon.make_service_watcher(sender);
1465 watcher->owner_changed().connect([thiz, path](const std::string&, const std::string&)
1466 {
1467+ LOG(INFO) << "Purging session for path: " << path.as_string();
1468 thiz->remove_from_session_store_for_path(path);
1469 });
1470
1471
1472=== modified file 'src/location/dbus/skeleton/session.cpp'
1473--- src/location/dbus/skeleton/session.cpp 2016-08-12 12:03:49 +0000
1474+++ src/location/dbus/skeleton/session.cpp 2016-08-12 12:03:50 +0000
1475@@ -269,10 +269,10 @@
1476 // Invoked whenever the actual session impl. for the session reports a position update.
1477 void location::dbus::skeleton::Session::on_position_changed(const location::Update<location::Position>& position)
1478 {
1479- VLOG(10) << __PRETTY_FUNCTION__;
1480 try
1481 {
1482- configuration.remote.object->invoke_method_asynchronously_with_callback<location::dbus::Session::UpdatePosition, void>([](const core::dbus::Result<void>& result)
1483+ auto sp = configuration.remote.object;
1484+ configuration.remote.object->invoke_method_asynchronously_with_callback<location::dbus::Session::UpdatePosition, void>([sp](const core::dbus::Result<void>& result)
1485 {
1486 if (result.is_error())
1487 {
1488@@ -292,10 +292,10 @@
1489 // Invoked whenever the actual session impl. reports a heading update.
1490 void location::dbus::skeleton::Session::on_heading_changed(const location::Update<location::Heading>& heading)
1491 {
1492- VLOG(10) << __PRETTY_FUNCTION__;
1493 try
1494 {
1495- configuration.remote.object->invoke_method_asynchronously_with_callback<location::dbus::Session::UpdateHeading, void>([](const core::dbus::Result<void>& result)
1496+ auto sp = configuration.remote.object;
1497+ configuration.remote.object->invoke_method_asynchronously_with_callback<location::dbus::Session::UpdateHeading, void>([sp](const core::dbus::Result<void>& result)
1498 {
1499 if (result.is_error())
1500 {
1501@@ -315,10 +315,10 @@
1502 // Invoked whenever the actual session impl. reports a velocity update.
1503 void location::dbus::skeleton::Session::on_velocity_changed(const location::Update<location::Velocity>& velocity)
1504 {
1505- VLOG(10) << __PRETTY_FUNCTION__;
1506 try
1507 {
1508- configuration.remote.object->invoke_method_asynchronously_with_callback<location::dbus::Session::UpdateVelocity, void>([](const core::dbus::Result<void>& result)
1509+ auto sp = configuration.remote.object;
1510+ sp->invoke_method_asynchronously_with_callback<location::dbus::Session::UpdateVelocity, void>([sp](const core::dbus::Result<void>& result)
1511 {
1512 if (result.is_error())
1513 {
1514
1515=== modified file 'src/location/dbus/skeleton/session.h'
1516--- src/location/dbus/skeleton/session.h 2016-06-28 11:53:34 +0000
1517+++ src/location/dbus/skeleton/session.h 2016-08-12 12:03:50 +0000
1518@@ -100,6 +100,7 @@
1519
1520 // Stores all attributes passed at creation time.
1521 Configuration configuration;
1522+
1523 // Scoped connections for automatically disconnecting on destruction
1524 struct
1525 {
1526
1527=== modified file 'src/location/dbus/stub/service.cpp'
1528--- src/location/dbus/stub/service.cpp 2016-08-12 12:03:49 +0000
1529+++ src/location/dbus/stub/service.cpp 2016-08-12 12:03:50 +0000
1530@@ -22,6 +22,7 @@
1531 #include <location/dbus/codec.h>
1532 #include <location/dbus/service.h>
1533
1534+#include <location/providers/remote/interface.h>
1535 #include <location/providers/remote/skeleton.h>
1536
1537 #include <location/logging.h>
1538
1539=== removed file 'src/location/default_provider_selection_policy.cpp'
1540--- src/location/default_provider_selection_policy.cpp 2016-06-26 21:17:03 +0000
1541+++ src/location/default_provider_selection_policy.cpp 1970-01-01 00:00:00 +0000
1542@@ -1,135 +0,0 @@
1543-/*
1544- * Copyright © 2012-2013 Canonical Ltd.
1545- *
1546- * This program is free software: you can redistribute it and/or modify it
1547- * under the terms of the GNU Lesser General Public License version 3,
1548- * as published by the Free Software Foundation.
1549- *
1550- * This program is distributed in the hope that it will be useful,
1551- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1552- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1553- * GNU Lesser General Public License for more details.
1554- *
1555- * You should have received a copy of the GNU Lesser General Public License
1556- * along with this program. If not, see <http://www.gnu.org/licenses/>.
1557- *
1558- * Authored by: Thomas Voß <thomas.voss@canonical.com>
1559- */
1560-#include <location/default_provider_selection_policy.h>
1561-
1562-#include <location/engine.h>
1563-
1564-namespace
1565-{
1566-struct NullProvider : public location::Provider
1567-{
1568- NullProvider() = default;
1569-};
1570-
1571-std::shared_ptr<location::Provider> null_provider_instance
1572-{
1573- new NullProvider{}
1574-};
1575-}
1576-
1577-const location::Provider::Ptr& location::ProviderSelectionPolicy::null_provider()
1578-{
1579- return null_provider_instance;
1580-}
1581-
1582-location::DefaultProviderSelectionPolicy::DefaultProviderSelectionPolicy()
1583-{
1584-}
1585-
1586-location::DefaultProviderSelectionPolicy::~DefaultProviderSelectionPolicy() noexcept
1587-{
1588-}
1589-
1590-location::ProviderSelection
1591-location::DefaultProviderSelectionPolicy::determine_provider_selection_for_criteria(
1592- const location::Criteria& criteria,
1593- const location::ProviderEnumerator& enumerator)
1594-{
1595- ProviderSelection selection
1596- {
1597- determine_position_updates_provider(criteria, enumerator),
1598- determine_heading_updates_provider(criteria, enumerator),
1599- determine_velocity_updates_provider(criteria, enumerator)
1600- };
1601-
1602- return selection;
1603-}
1604-
1605-location::Provider::Ptr
1606-location::DefaultProviderSelectionPolicy::determine_position_updates_provider(
1607- const location::Criteria& criteria,
1608- const location::ProviderEnumerator& enumerator)
1609-{
1610- auto less =
1611- [](const Provider::Ptr& lhs, const Provider::Ptr& rhs)
1612- {
1613- return
1614- lhs->state_controller()->are_position_updates_running() && !rhs->state_controller()->are_position_updates_running();
1615- };
1616-
1617- std::set<
1618- Provider::Ptr,
1619- std::function<bool(const Provider::Ptr&, const Provider::Ptr&)>> matching_providers(less);
1620-
1621- enumerator.for_each_provider(
1622- [&](const Provider::Ptr& provider)
1623- {
1624- if (provider->matches_criteria(criteria))
1625- matching_providers.insert(provider);
1626- });
1627-
1628- return matching_providers.empty() ? null_provider() : *matching_providers.begin();
1629-}
1630-
1631-location::Provider::Ptr location::DefaultProviderSelectionPolicy::determine_heading_updates_provider(
1632- const location::Criteria& criteria,
1633- const location::ProviderEnumerator& enumerator)
1634-{
1635- auto less =
1636- [](const Provider::Ptr& lhs, const Provider::Ptr& rhs)
1637- {
1638- return lhs->state_controller()->are_heading_updates_running() && !rhs->state_controller()->are_heading_updates_running();
1639- };
1640-
1641- std::set<
1642- Provider::Ptr,
1643- std::function<bool(const Provider::Ptr&, const Provider::Ptr&)>> matching_providers(less);
1644-
1645- enumerator.for_each_provider(
1646- [&](const Provider::Ptr& provider)
1647- {
1648- if (provider->matches_criteria(criteria))
1649- matching_providers.insert(provider);
1650- });
1651-
1652- return matching_providers.empty() ? null_provider() : *matching_providers.begin();
1653-}
1654-
1655-location::Provider::Ptr location::DefaultProviderSelectionPolicy::determine_velocity_updates_provider(
1656- const location::Criteria& criteria,
1657- const location::ProviderEnumerator& enumerator)
1658-{
1659- auto less =
1660- [](const Provider::Ptr& lhs, const Provider::Ptr& rhs)
1661- {
1662- return lhs->state_controller()->are_velocity_updates_running() && !rhs->state_controller()->are_velocity_updates_running();
1663- };
1664-
1665- std::set<
1666- Provider::Ptr,
1667- std::function<bool(const Provider::Ptr&, const Provider::Ptr&)>> matching_providers(less);
1668-
1669- enumerator.for_each_provider(
1670- [&](const Provider::Ptr& provider)
1671- {
1672- if (provider->matches_criteria(criteria))
1673- matching_providers.insert(provider);
1674- });
1675-
1676- return matching_providers.empty() ? null_provider() : *matching_providers.begin();
1677-}
1678
1679=== removed file 'src/location/default_provider_selection_policy.h'
1680--- src/location/default_provider_selection_policy.h 2016-06-28 11:53:34 +0000
1681+++ src/location/default_provider_selection_policy.h 1970-01-01 00:00:00 +0000
1682@@ -1,49 +0,0 @@
1683-/*
1684- * Copyright © 2012-2013 Canonical Ltd.
1685- *
1686- * This program is free software: you can redistribute it and/or modify it
1687- * under the terms of the GNU Lesser General Public License version 3,
1688- * as published by the Free Software Foundation.
1689- *
1690- * This program is distributed in the hope that it will be useful,
1691- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1692- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1693- * GNU Lesser General Public License for more details.
1694- *
1695- * You should have received a copy of the GNU Lesser General Public License
1696- * along with this program. If not, see <http://www.gnu.org/licenses/>.
1697- *
1698- * Authored by: Thomas Voß <thomas.voss@canonical.com>
1699- */
1700-#ifndef DEFAULT_PROVIDER_SELECTION_POLICY_H_
1701-#define DEFAULT_PROVIDER_SELECTION_POLICY_H_
1702-
1703-#include <location/provider_selection_policy.h>
1704-
1705-namespace location
1706-{
1707-class DefaultProviderSelectionPolicy : public ProviderSelectionPolicy
1708-{
1709-public:
1710- DefaultProviderSelectionPolicy();
1711- ~DefaultProviderSelectionPolicy() noexcept;
1712-
1713- ProviderSelection determine_provider_selection_for_criteria(
1714- const Criteria& criteria,
1715- const ProviderEnumerator& enumerator);
1716-
1717- Provider::Ptr determine_position_updates_provider(
1718- const Criteria& criteria,
1719- const ProviderEnumerator& enumerator);
1720-
1721- Provider::Ptr determine_heading_updates_provider(
1722- const Criteria& criteria,
1723- const ProviderEnumerator& enumerator);
1724-
1725- Provider::Ptr determine_velocity_updates_provider(
1726- const Criteria& criteria,
1727- const ProviderEnumerator& enumerator);
1728-};
1729-}
1730-
1731-#endif // DEFAULT_PROVIDER_SELECTION_POLICY_H_
1732
1733=== removed file 'src/location/dummy_service.cpp'
1734--- src/location/dummy_service.cpp 2016-06-30 09:13:21 +0000
1735+++ src/location/dummy_service.cpp 1970-01-01 00:00:00 +0000
1736@@ -1,55 +0,0 @@
1737-/*
1738- * Copyright (C) 2016 Canonical, Ltd.
1739- *
1740- * This program is free software; you can redistribute it and/or modify
1741- * it under the terms of the GNU Lesser General Public License as published by
1742- * the Free Software Foundation; version 3.
1743- *
1744- * This program is distributed in the hope that it will be useful,
1745- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1746- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1747- * GNU Lesser General Public License for more details.
1748- *
1749- * You should have received a copy of the GNU Lesser General Public License
1750- * along with this program. If not, see <http://www.gnu.org/licenses/>.
1751- *
1752- * Authored by: Thomas Voß <thomas.voss@canonical.com>
1753- *
1754- */
1755-
1756-#include <location/dummy_service.h>
1757-
1758-location::Service::Session::Updates& location::DummyService::Session::updates()
1759-{
1760- return updates_;
1761-}
1762-
1763-const core::Property<location::Service::State>& location::DummyService::state() const
1764-{
1765- return state_;
1766-}
1767-
1768-core::Property<bool>& location::DummyService::does_satellite_based_positioning()
1769-{
1770- return does_satellite_based_positioning_;
1771-}
1772-
1773-core::Property<bool>& location::DummyService::is_online()
1774-{
1775- return is_online_;
1776-}
1777-
1778-core::Property<bool>& location::DummyService::does_report_cell_and_wifi_ids()
1779-{
1780- return does_report_cell_and_wifi_ids_;
1781-}
1782-
1783-core::Property<std::map<location::SpaceVehicle::Key, location::SpaceVehicle>>& location::DummyService::visible_space_vehicles()
1784-{
1785- return visible_space_vehicles_;
1786-}
1787-
1788-location::Service::Session::Ptr location::DummyService::create_session_for_criteria(const Criteria&)
1789-{
1790- return std::make_shared<DummyService::Session>();
1791-}
1792
1793=== removed file 'src/location/dummy_service.h'
1794--- src/location/dummy_service.h 2016-06-30 09:13:21 +0000
1795+++ src/location/dummy_service.h 1970-01-01 00:00:00 +0000
1796@@ -1,55 +0,0 @@
1797-/*
1798- * Copyright (C) 2016 Canonical, Ltd.
1799- *
1800- * This program is free software; you can redistribute it and/or modify
1801- * it under the terms of the GNU Lesser General Public License as published by
1802- * the Free Software Foundation; version 3.
1803- *
1804- * This program is distributed in the hope that it will be useful,
1805- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1806- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1807- * GNU Lesser General Public License for more details.
1808- *
1809- * You should have received a copy of the GNU Lesser General Public License
1810- * along with this program. If not, see <http://www.gnu.org/licenses/>.
1811- *
1812- * Authored by: Thomas Voß <thomas.voss@canonical.com>
1813- *
1814- */
1815-
1816-#ifndef LOCATION_DUMMY_SERVICE_H_
1817-#define LOCATION_DUMMY_SERVICE_H_
1818-
1819-#include <location/service.h>
1820-
1821-namespace location
1822-{
1823-class DummyService : public Service
1824-{
1825-public:
1826- class Session : public Service::Session
1827- {
1828- public:
1829- Updates& updates() override;
1830-
1831- private:
1832- Updates updates_;
1833- };
1834-
1835- const core::Property<State>& state() const override;
1836- core::Property<bool>& does_satellite_based_positioning() override;
1837- core::Property<bool>& is_online() override;
1838- core::Property<bool>& does_report_cell_and_wifi_ids() override;
1839- core::Property<std::map<SpaceVehicle::Key, SpaceVehicle>>& visible_space_vehicles() override;
1840- Session::Ptr create_session_for_criteria(const Criteria& criteria) override;
1841-
1842-private:
1843- core::Property<State> state_;
1844- core::Property<bool> does_satellite_based_positioning_;
1845- core::Property<bool> is_online_;
1846- core::Property<bool> does_report_cell_and_wifi_ids_;
1847- core::Property<std::map<SpaceVehicle::Key, SpaceVehicle>> visible_space_vehicles_;
1848-};
1849-}
1850-
1851-#endif // LOCATION_DUMMY_SERVICE_H_
1852
1853=== modified file 'src/location/engine.cpp'
1854--- src/location/engine.cpp 2016-06-26 21:17:03 +0000
1855+++ src/location/engine.cpp 2016-08-12 12:03:50 +0000
1856@@ -19,7 +19,12 @@
1857
1858 #include <location/logging.h>
1859 #include <location/provider_selection_policy.h>
1860-#include <location/state_tracking_provider.h>
1861+
1862+#include <location/events/reference_position_updated.h>
1863+#include <location/events/wifi_and_cell_id_reporting_state_changed.h>
1864+#include <location/providers/state_tracking_provider.h>
1865+
1866+#include <location/util/flags.h>
1867
1868 #include <iostream>
1869 #include <stdexcept>
1870@@ -32,8 +37,10 @@
1871 const location::Engine::Status location::Engine::Configuration::Defaults::engine_state;
1872
1873 location::Engine::Engine(const location::ProviderSelectionPolicy::Ptr& provider_selection_policy,
1874- const location::Settings::Ptr& settings)
1875+ const location::Bus::Ptr& bus,
1876+ const location::Settings::Ptr& settings)
1877 : provider_selection_policy(provider_selection_policy),
1878+ bus(bus),
1879 settings(settings),
1880 update_policy(std::make_shared<location::TimeBasedUpdatePolicy>())
1881 {
1882@@ -52,17 +59,17 @@
1883 {
1884 for_each_provider([this, state](const Provider::Ptr& provider)
1885 {
1886- if (provider->requires(location::Provider::Requirements::satellites))
1887+ if (util::flags::has(provider->requirements(), Provider::Requirements::satellites))
1888 {
1889 switch (state)
1890 {
1891 case SatelliteBasedPositioningState::on:
1892 // We only enable a provider if the overall engine is enabled.
1893 if (configuration.engine_state == Engine::Status::on)
1894- provider->state_controller()->enable();
1895+ provider->enable();
1896 break;
1897 case SatelliteBasedPositioningState::off:
1898- provider->state_controller()->disable();
1899+ provider->disable();
1900 break;
1901 }
1902 }
1903@@ -77,13 +84,14 @@
1904 {
1905 case Engine::Status::on:
1906 // We only enable providers that require satellites if the respective engine option is set to on.
1907- if (provider->requires(location::Provider::Requirements::satellites) && configuration.satellite_based_positioning_state == SatelliteBasedPositioningState::off)
1908+ if (util::flags::has(provider->requirements(), Provider::Requirements::satellites) &&
1909+ configuration.satellite_based_positioning_state == SatelliteBasedPositioningState::off)
1910 return;
1911
1912- provider->state_controller()->enable();
1913+ provider->enable();
1914 break;
1915 case Engine::Status::off:
1916- provider->state_controller()->disable();
1917+ provider->disable();
1918 break;
1919 default:
1920 break;
1921@@ -111,6 +119,12 @@
1922 configuration.wifi_and_cell_id_reporting_state.changed().connect([this](WifiAndCellIdReportingState state)
1923 {
1924 Engine::settings->set_enum_for_key<WifiAndCellIdReportingState>(Configuration::Keys::wifi_and_cell_id_reporting_state, state);
1925+ Engine::bus->dispatch(std::make_shared<events::WifiAndCellIdReportingStateChanged>(state));
1926+ });
1927+
1928+ updates.last_known_location.changed().connect([this](const Optional<Update<Position>>& update)
1929+ {
1930+ Engine::bus->dispatch(std::make_shared<events::ReferencePositionUpdated>(*update));
1931 });
1932 }
1933
1934@@ -126,9 +140,7 @@
1935
1936 for_each_provider([](const Provider::Ptr& provider)
1937 {
1938- provider->state_controller()->stop_position_updates();
1939- provider->state_controller()->stop_heading_updates();
1940- provider->state_controller()->stop_velocity_updates();
1941+ provider->disable();
1942 });
1943 }
1944
1945@@ -142,80 +154,36 @@
1946 if (!impl)
1947 throw std::runtime_error("Cannot add null provider");
1948
1949- auto provider = std::make_shared<StateTrackingProvider>(impl);
1950+ auto provider = std::make_shared<providers::StateTrackingProvider>(impl);
1951
1952 // We synchronize to the engine state.
1953- if (provider->requires(Provider::Requirements::satellites) && configuration.satellite_based_positioning_state == SatelliteBasedPositioningState::off)
1954- provider->state_controller()->disable();
1955+ if (util::flags::has(provider->requirements(), Provider::Requirements::satellites) && configuration.satellite_based_positioning_state == SatelliteBasedPositioningState::off)
1956+ provider->disable();
1957
1958 if (configuration.engine_state == Engine::Status::off)
1959- provider->state_controller()->disable();
1960-
1961- // We wire up changes in the engine's configuration to the respective slots
1962- // of the provider.
1963- auto cp = updates.last_known_location.changed().connect([provider](const location::Optional<location::Update<location::Position>>& pos)
1964- {
1965- if (pos)
1966- {
1967- provider->on_reference_location_updated(pos.get());
1968- }
1969- });
1970-
1971- auto cv = updates.last_known_velocity.changed().connect([provider](const location::Optional<location::Update<location::Velocity>>& velocity)
1972- {
1973- if (velocity)
1974- {
1975- provider->on_reference_velocity_updated(velocity.get());
1976- }
1977- });
1978-
1979- auto ch = updates.last_known_heading.changed().connect([provider](const location::Optional<location::Update<location::Heading>>& heading)
1980- {
1981- if (heading)
1982- {
1983- provider->on_reference_heading_updated(heading.get());
1984- }
1985- });
1986-
1987- auto cr = configuration.wifi_and_cell_id_reporting_state.changed().connect([provider](location::WifiAndCellIdReportingState state)
1988- {
1989- provider->on_wifi_and_cell_reporting_state_changed(state);
1990- });
1991-
1992- // And do the reverse: Satellite visibility updates are funneled via the engine's configuration.
1993- auto cs = provider->updates().svs.connect([this](const location::Update<std::set<location::SpaceVehicle>>& src)
1994- {
1995- updates.visible_space_vehicles.update([src](std::map<location::SpaceVehicle::Key, location::SpaceVehicle>& dest)
1996- {
1997- for(auto& sv : src.value)
1998- {
1999- dest[sv.key] = sv;
2000- }
2001-
2002- return true;
2003- });
2004- });
2005+ provider->disable();
2006
2007 // We are a bit dumb and just take any position update as new reference.
2008 // We should come up with a better heuristic here.
2009- auto cpr = provider->updates().position.connect([this](const location::Update<location::Position>& src)
2010+ auto cpr = provider->position_updates().connect([this](const location::Update<location::Position>& src)
2011 {
2012 updates.last_known_location = update_policy->verify_update(src);
2013 });
2014
2015- auto cps = provider->state().changed().connect([this](const StateTrackingProvider::State&)
2016+ auto cps = provider->state().changed().connect([this](const providers::StateTrackingProvider::State&)
2017 {
2018 bool is_any_active = false;
2019
2020 std::lock_guard<std::recursive_mutex> lg(guard);
2021 for (const auto& pair : providers)
2022- is_any_active = pair.first->state() == StateTrackingProvider::State::active;
2023+ is_any_active = pair.first->state() == providers::StateTrackingProvider::State::active;
2024
2025 configuration.engine_state = is_any_active ? Engine::Status::active : Engine::Status::on;
2026 });
2027
2028 std::lock_guard<std::recursive_mutex> lg(guard);
2029- providers.emplace(provider, std::move(ProviderConnections{cp, ch, cv, cr, cs, cpr, cps}));
2030+ bus->subscribe(provider);
2031+ providers.emplace(provider, std::move(ProviderConnections{cpr, cps}));
2032 }
2033
2034 void location::Engine::for_each_provider(const std::function<void(const Provider::Ptr&)>& enumerator) const noexcept
2035
2036=== modified file 'src/location/engine.h'
2037--- src/location/engine.h 2016-06-27 06:44:50 +0000
2038+++ src/location/engine.h 2016-08-12 12:03:50 +0000
2039@@ -18,15 +18,17 @@
2040 #ifndef LOCATION_ENGINE_H_
2041 #define LOCATION_ENGINE_H_
2042
2043+#include <location/bus.h>
2044 #include <location/provider.h>
2045 #include <location/provider_enumerator.h>
2046 #include <location/provider_selection.h>
2047 #include <location/provider_selection_policy.h>
2048 #include <location/satellite_based_positioning_state.h>
2049 #include <location/space_vehicle.h>
2050-#include <location/state_tracking_provider.h>
2051 #include <location/wifi_and_cell_reporting_state.h>
2052
2053+#include <location/providers/state_tracking_provider.h>
2054+
2055 #include <location/settings.h>
2056
2057 #include <core/property.h>
2058@@ -134,6 +136,7 @@
2059 };
2060
2061 Engine(const ProviderSelectionPolicy::Ptr& provider_selection_policy,
2062+ const Bus::Ptr& bus,
2063 const Settings::Ptr& settings);
2064
2065 Engine(const Engine&) = delete;
2066@@ -168,18 +171,14 @@
2067 private:
2068 struct ProviderConnections
2069 {
2070- core::ScopedConnection reference_location_updates;
2071- core::ScopedConnection reference_velocity_updates;
2072- core::ScopedConnection reference_heading_updates;
2073- core::ScopedConnection wifi_and_cell_id_reporting_state_updates;
2074- core::ScopedConnection space_vehicle_visibility_updates;
2075 core::ScopedConnection provider_position_updates;
2076 core::ScopedConnection provider_state_updates;
2077 };
2078
2079 mutable std::recursive_mutex guard;
2080- std::map<StateTrackingProvider::Ptr, ProviderConnections> providers;
2081+ std::map<providers::StateTrackingProvider::Ptr, ProviderConnections> providers;
2082 ProviderSelectionPolicy::Ptr provider_selection_policy;
2083+ Bus::Ptr bus;
2084 Settings::Ptr settings;
2085 UpdatePolicy::Ptr update_policy;
2086 };
2087
2088=== added file 'src/location/event.cpp'
2089--- src/location/event.cpp 1970-01-01 00:00:00 +0000
2090+++ src/location/event.cpp 2016-08-12 12:03:50 +0000
2091@@ -0,0 +1,26 @@
2092+/*
2093+ * Copyright © 2016 Canonical Ltd.
2094+ *
2095+ * This program is free software: you can redistribute it and/or modify it
2096+ * under the terms of the GNU Lesser General Public License version 3,
2097+ * as published by the Free Software Foundation.
2098+ *
2099+ * This program is distributed in the hope that it will be useful,
2100+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2101+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2102+ * GNU Lesser General Public License for more details.
2103+ *
2104+ * You should have received a copy of the GNU Lesser General Public License
2105+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2106+ *
2107+ * Authored by: Thomas Voß <thomas.voss@canonical.com>
2108+ */
2109+
2110+#include <location/event.h>
2111+
2112+#include <location/events/registry.h>
2113+
2114+location::Event::Type location::Event::next_user_defined_type(const std::string& name)
2115+{
2116+ return events::Registry::instance().insert(name);
2117+}
2118
2119=== added directory 'src/location/events'
2120=== added file 'src/location/events/all.h'
2121--- src/location/events/all.h 1970-01-01 00:00:00 +0000
2122+++ src/location/events/all.h 2016-08-12 12:03:50 +0000
2123@@ -0,0 +1,46 @@
2124+/*
2125+ * Copyright © 2016 Canonical Ltd.
2126+ *
2127+ * This program is free software: you can redistribute it and/or modify it
2128+ * under the terms of the GNU Lesser General Public License version 3,
2129+ * as published by the Free Software Foundation.
2130+ *
2131+ * This program is distributed in the hope that it will be useful,
2132+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2133+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2134+ * GNU Lesser General Public License for more details.
2135+ *
2136+ * You should have received a copy of the GNU Lesser General Public License
2137+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2138+ *
2139+ * Authored by: Thomas Voß <thomas.voss@canonical.com>
2140+ */
2141+#ifndef LOCATION_EVENTS_ALL_H_
2142+#define LOCATION_EVENTS_ALL_H_
2143+
2144+#include <location/events/reference_position_updated.h>
2145+#include <location/events/wifi_and_cell_id_reporting_state_changed.h>
2146+
2147+#include <boost/variant.hpp>
2148+
2149+namespace location
2150+{
2151+namespace events
2152+{
2153+/// @brief Undefined tags the unknown event and allows us to
2154+/// escape the "no default ctor" issue.
2155+struct Undefined{};
2156+
2157+/// @brief All captures all known events and allows us to serialize/transport
2158+/// them easily without the need to extend location::Event with specific serialization
2159+/// functionality.
2160+typedef boost::variant
2161+<
2162+ Undefined,
2163+ ReferencePositionUpdated,
2164+ WifiAndCellIdReportingStateChanged
2165+> All;
2166+}
2167+}
2168+
2169+#endif // LOCATION_EVENTS_ALL_H_
2170
2171=== added file 'src/location/events/reference_position_updated.cpp'
2172--- src/location/events/reference_position_updated.cpp 1970-01-01 00:00:00 +0000
2173+++ src/location/events/reference_position_updated.cpp 2016-08-12 12:03:50 +0000
2174@@ -0,0 +1,55 @@
2175+/*
2176+ * Copyright © 2016 Canonical Ltd.
2177+ *
2178+ * This program is free software: you can redistribute it and/or modify it
2179+ * under the terms of the GNU Lesser General Public License version 3,
2180+ * as published by the Free Software Foundation.
2181+ *
2182+ * This program is distributed in the hope that it will be useful,
2183+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2184+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2185+ * GNU Lesser General Public License for more details.
2186+ *
2187+ * You should have received a copy of the GNU Lesser General Public License
2188+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2189+ *
2190+ * Authored by: Thomas Voß <thomas.voss@canonical.com>
2191+ */
2192+
2193+#include <location/events/reference_position_updated.h>
2194+
2195+namespace
2196+{
2197+const location::Event::Type id = location::Event::register_type<location::events::ReferencePositionUpdated>("location::events::ReferencePositionUpdated");
2198+}
2199+
2200+location::events::ReferencePositionUpdated::ReferencePositionUpdated(const Update<Position>& update)
2201+ : update_{update}
2202+{
2203+}
2204+
2205+location::events::ReferencePositionUpdated::ReferencePositionUpdated(const ReferencePositionUpdated& rhs)
2206+ : Event{}, update_{rhs.update_}
2207+{
2208+}
2209+
2210+location::events::ReferencePositionUpdated& location::events::ReferencePositionUpdated::operator=(const ReferencePositionUpdated& rhs)
2211+{
2212+ update_ = rhs.update_;
2213+ return *this;
2214+}
2215+
2216+const location::Update<location::Position>& location::events::ReferencePositionUpdated::update() const
2217+{
2218+ return update_;
2219+}
2220+
2221+location::Event::Type location::events::ReferencePositionUpdated::type() const
2222+{
2223+ return id;
2224+}
2225+
2226+location::Event::Type location::TypeOf<location::events::ReferencePositionUpdated>::query()
2227+{
2228+ return id;
2229+}
2230
2231=== added file 'src/location/events/registry.cpp'
2232--- src/location/events/registry.cpp 1970-01-01 00:00:00 +0000
2233+++ src/location/events/registry.cpp 2016-08-12 12:03:50 +0000
2234@@ -0,0 +1,65 @@
2235+/*
2236+ * Copyright © 2016 Canonical Ltd.
2237+ *
2238+ * This program is free software: you can redistribute it and/or modify it
2239+ * under the terms of the GNU Lesser General Public License version 3,
2240+ * as published by the Free Software Foundation.
2241+ *
2242+ * This program is distributed in the hope that it will be useful,
2243+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2244+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2245+ * GNU Lesser General Public License for more details.
2246+ *
2247+ * You should have received a copy of the GNU Lesser General Public License
2248+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2249+ *
2250+ * Authored by: Thomas Voß <thomas.voss@canonical.com>
2251+ */
2252+
2253+#include <location/events/registry.h>
2254+
2255+namespace
2256+{
2257+location::Event::Type increment(location::Event::Type type, std::size_t value)
2258+{
2259+ return static_cast<location::Event::Type>(static_cast<std::size_t>(type) + value);
2260+}
2261+}
2262+
2263+location::events::Registry& location::events::Registry::instance()
2264+{
2265+ static Registry registry;
2266+ return registry;
2267+}
2268+
2269+std::string location::events::Registry::find(location::Event::Type type) const
2270+{
2271+ std::lock_guard<std::mutex> lg{guard};
2272+ return type_name_lut.at(type);
2273+}
2274+
2275+location::Event::Type location::events::Registry::find(const std::string& name) const
2276+{
2277+ std::lock_guard<std::mutex> lg{guard};
2278+ return name_type_lut.at(name);
2279+}
2280+
2281+location::Event::Type location::events::Registry::insert(const std::string& name)
2282+{
2283+ std::lock_guard<std::mutex> lg{guard};
2284+
2285+ auto it = name_type_lut.find(name);
2286+ if (it == name_type_lut.end())
2287+ {
2288+ std::tie(it, std::ignore) = name_type_lut.insert(
2289+ std::make_pair(
2290+ name,
2291+ increment(location::Event::Type::first_user_defined_type, counter++)));
2292+
2293+ type_name_lut[it->second] = name;
2294+
2295+ return it->second;
2296+ }
2297+
2298+ throw std::runtime_error{"Event " + name + " is already known to the registry."};
2299+}
2300
2301=== added file 'src/location/events/registry.h'
2302--- src/location/events/registry.h 1970-01-01 00:00:00 +0000
2303+++ src/location/events/registry.h 2016-08-12 12:03:50 +0000
2304@@ -0,0 +1,65 @@
2305+/*
2306+ * Copyright © 2016 Canonical Ltd.
2307+ *
2308+ * This program is free software: you can redistribute it and/or modify it
2309+ * under the terms of the GNU Lesser General Public License version 3,
2310+ * as published by the Free Software Foundation.
2311+ *
2312+ * This program is distributed in the hope that it will be useful,
2313+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2314+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2315+ * GNU Lesser General Public License for more details.
2316+ *
2317+ * You should have received a copy of the GNU Lesser General Public License
2318+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2319+ *
2320+ * Authored by: Thomas Voß <thomas.voss@canonical.com>
2321+ */
2322+#ifndef LOCATION_EVENTS_REGISTRY_H_
2323+#define LOCATION_EVENTS_REGISTRY_H_
2324+
2325+#include <location/event.h>
2326+
2327+#include <map>
2328+#include <mutex>
2329+#include <string>
2330+
2331+namespace location
2332+{
2333+namespace events
2334+{
2335+class Registry
2336+{
2337+public:
2338+ // instance returns the singleton instance of Registry.
2339+ static Registry& instance();
2340+
2341+ // find returns the name assigned to type or throws std::out_of_range.
2342+ std::string find(location::Event::Type type) const;
2343+
2344+ // find returns the type assigned to name or throws std::out_of_range.
2345+ location::Event::Type find(const std::string& name) const;
2346+
2347+ // insert makes name known and assigns it a unique type in the scope of
2348+ // the process.
2349+ location::Event::Type insert(const std::string& name);
2350+
2351+private:
2352+ // Boilerplate to prevent the outside from creating/deleting/copying/moving
2353+ // Registry instances.
2354+ Registry() = default;
2355+ Registry(const Registry&) = delete;
2356+ Registry(Registry&&) = delete;
2357+ ~Registry() = default;
2358+ Registry& operator=(const Registry&) = delete;
2359+ Registry& operator=(Registry&&) = delete;
2360+
2361+ mutable std::mutex guard;
2362+ std::size_t counter{0};
2363+ std::map<location::Event::Type, std::string> type_name_lut;
2364+ std::map<std::string, location::Event::Type> name_type_lut;
2365+};
2366+}
2367+}
2368+
2369+#endif // LOCATION_EVENTS_REGISTRY_H_
2370
2371=== added file 'src/location/events/wifi_and_cell_id_reporting_state_changed.cpp'
2372--- src/location/events/wifi_and_cell_id_reporting_state_changed.cpp 1970-01-01 00:00:00 +0000
2373+++ src/location/events/wifi_and_cell_id_reporting_state_changed.cpp 2016-08-12 12:03:50 +0000
2374@@ -0,0 +1,55 @@
2375+/*
2376+ * Copyright © 2016 Canonical Ltd.
2377+ *
2378+ * This program is free software: you can redistribute it and/or modify it
2379+ * under the terms of the GNU Lesser General Public License version 3,
2380+ * as published by the Free Software Foundation.
2381+ *
2382+ * This program is distributed in the hope that it will be useful,
2383+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2384+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2385+ * GNU Lesser General Public License for more details.
2386+ *
2387+ * You should have received a copy of the GNU Lesser General Public License
2388+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2389+ *
2390+ * Authored by: Thomas Voß <thomas.voss@canonical.com>
2391+ */
2392+
2393+#include <location/events/wifi_and_cell_id_reporting_state_changed.h>
2394+
2395+namespace
2396+{
2397+const location::Event::Type id = location::Event::register_type<location::events::WifiAndCellIdReportingStateChanged>("location::events::WifiAndCellIdReportingStateChanged");
2398+}
2399+
2400+location::events::WifiAndCellIdReportingStateChanged::WifiAndCellIdReportingStateChanged(WifiAndCellIdReportingState new_state)
2401+ : new_state_{new_state}
2402+{
2403+}
2404+
2405+location::events::WifiAndCellIdReportingStateChanged::WifiAndCellIdReportingStateChanged(const WifiAndCellIdReportingStateChanged& rhs)
2406+ : Event{}, new_state_{rhs.new_state_}
2407+{
2408+}
2409+
2410+location::events::WifiAndCellIdReportingStateChanged& location::events::WifiAndCellIdReportingStateChanged::operator=(const WifiAndCellIdReportingStateChanged& rhs)
2411+{
2412+ new_state_ = rhs.new_state_;
2413+ return *this;
2414+}
2415+
2416+location::WifiAndCellIdReportingState location::events::WifiAndCellIdReportingStateChanged::new_state() const
2417+{
2418+ return new_state_;
2419+}
2420+
2421+location::Event::Type location::events::WifiAndCellIdReportingStateChanged::type() const
2422+{
2423+ return id;
2424+}
2425+
2426+location::Event::Type location::TypeOf<location::events::WifiAndCellIdReportingStateChanged>::query()
2427+{
2428+ return id;
2429+}
2430
2431=== modified file 'src/location/fusion_provider_selection_policy.cpp'
2432--- src/location/fusion_provider_selection_policy.cpp 2016-06-26 21:17:03 +0000
2433+++ src/location/fusion_provider_selection_policy.cpp 2016-08-12 12:03:50 +0000
2434@@ -1,6 +1,9 @@
2435-#include <location/fusion_provider.h>
2436+#include <location/providers/fusion/provider.h>
2437+#include <location/providers/fusion/newer_or_more_accurate_update_selector.h>
2438+
2439 #include <location/fusion_provider_selection_policy.h>
2440-#include <location/newer_or_more_accurate_update_selector.h>
2441+
2442+namespace fusion = location::providers::fusion;
2443
2444 location::ProviderSelection location::FusionProviderSelectionPolicy::determine_provider_selection_for_criteria(
2445 const location::Criteria&,
2446@@ -13,7 +16,7 @@
2447 bag.insert(provider);
2448 });
2449
2450- auto fusion_providers = std::make_shared<location::FusionProvider>(bag, std::make_shared<location::NewerOrMoreAccurateUpdateSelector>());
2451+ auto fusion_providers = fusion::Provider::create(bag, std::make_shared<fusion::NewerOrMoreAccurateUpdateSelector>());
2452
2453 return location::ProviderSelection
2454 {
2455
2456=== modified file 'src/location/non_selecting_provider_selection_policy.cpp'
2457--- src/location/non_selecting_provider_selection_policy.cpp 2016-06-26 21:17:03 +0000
2458+++ src/location/non_selecting_provider_selection_policy.cpp 2016-08-12 12:03:50 +0000
2459@@ -17,8 +17,7 @@
2460 */
2461
2462 #include <location/non_selecting_provider_selection_policy.h>
2463-#include <location/fusion_provider.h>
2464-#include <location/newer_update_selector.h>
2465+#include <location/providers/proxy.h>
2466
2467 #include <set>
2468
2469@@ -33,13 +32,13 @@
2470 bag.insert(provider);
2471 });
2472
2473- auto bag_of_providers = std::make_shared<FusionProvider>(bag, std::make_shared<NewerUpdateSelector>());
2474+ auto proxy = std::make_shared<providers::Proxy>(bag);
2475
2476 // Our bag of providers is responsible for delivering position/heading/velocity updates.
2477 return location::ProviderSelection
2478 {
2479- bag_of_providers, // position
2480- bag_of_providers, // heading
2481- bag_of_providers // velocity
2482+ proxy, // position
2483+ proxy, // heading
2484+ proxy // velocity
2485 };
2486 }
2487
2488=== modified file 'src/location/provider.cpp'
2489--- src/location/provider.cpp 2016-06-26 21:17:03 +0000
2490+++ src/location/provider.cpp 2016-08-12 12:03:50 +0000
2491@@ -17,197 +17,6 @@
2492 */
2493 #include <location/provider.h>
2494
2495-#include <atomic>
2496-#include <bitset>
2497-#include <memory>
2498-
2499-namespace
2500-{
2501-static const int our_magic_disabling_value = -1;
2502-}
2503-
2504-void location::Provider::Controller::enable()
2505-{
2506- position_updates_counter = 0;
2507- heading_updates_counter = 0;
2508- velocity_updates_counter = 0;
2509-}
2510-
2511-void location::Provider::Controller::disable()
2512-{
2513- if (position_updates_counter > 0)
2514- instance.stop_position_updates();
2515- if (heading_updates_counter > 0)
2516- instance.stop_heading_updates();
2517- if (velocity_updates_counter > 0)
2518- instance.stop_velocity_updates();
2519-
2520- position_updates_counter = our_magic_disabling_value;
2521- heading_updates_counter = our_magic_disabling_value;
2522- velocity_updates_counter = our_magic_disabling_value;
2523-}
2524-
2525-void location::Provider::Controller::start_position_updates()
2526-{
2527- if (position_updates_counter < 0)
2528- return;
2529-
2530- if (++position_updates_counter == 1)
2531- {
2532- instance.start_position_updates();
2533- }
2534-}
2535-
2536-void location::Provider::Controller::stop_position_updates()
2537-{
2538- if (position_updates_counter < 0)
2539- return;
2540-
2541- if (--position_updates_counter == 0)
2542- {
2543- instance.stop_position_updates();
2544- }
2545-}
2546-
2547-bool location::Provider::Controller::are_position_updates_running() const
2548-{
2549- return position_updates_counter > 0;
2550-}
2551-
2552-void location::Provider::Controller::start_heading_updates()
2553-{
2554- if (heading_updates_counter < 0)
2555- return;
2556-
2557- if (++heading_updates_counter == 1)
2558- {
2559- instance.start_heading_updates();
2560- }
2561-}
2562-
2563-void location::Provider::Controller::stop_heading_updates()
2564-{
2565- if (heading_updates_counter < 0)
2566- return;
2567-
2568- if (--heading_updates_counter == 0)
2569- {
2570- instance.stop_heading_updates();
2571- }
2572-}
2573-
2574-bool location::Provider::Controller::are_heading_updates_running() const
2575-{
2576- return heading_updates_counter > 0;
2577-}
2578-
2579-void location::Provider::Controller::start_velocity_updates()
2580-{
2581- if (velocity_updates_counter < 0)
2582- return;
2583-
2584- if (++velocity_updates_counter == 1)
2585- {
2586- instance.start_velocity_updates();
2587- }
2588-}
2589-
2590-void location::Provider::Controller::stop_velocity_updates()
2591-{
2592- if (velocity_updates_counter < 0)
2593- return;
2594-
2595- if (--velocity_updates_counter == 0)
2596- {
2597- instance.stop_velocity_updates();
2598- }
2599-}
2600-
2601-bool location::Provider::Controller::are_velocity_updates_running() const
2602-{
2603- return velocity_updates_counter > 0;
2604-}
2605-
2606-location::Provider::Controller::Controller(location::Provider& instance)
2607- : instance(instance),
2608- position_updates_counter(0),
2609- heading_updates_counter(0),
2610- velocity_updates_counter(0)
2611-{
2612-}
2613-
2614-const location::Provider::Controller::Ptr& location::Provider::state_controller() const
2615-{
2616- return d.controller;
2617-}
2618-
2619-bool location::Provider::supports(const location::Provider::Features& f) const
2620-{
2621- return (d.features & f) != Features::none;
2622-}
2623-
2624-bool location::Provider::requires(const location::Provider::Requirements& r) const
2625-{
2626- return (d.requirements & r) != Requirements::none;
2627-}
2628-
2629-bool location::Provider::matches_criteria(const location::Criteria&)
2630-{
2631- return false;
2632-}
2633-
2634-const location::Provider::Updates& location::Provider::updates() const
2635-{
2636- return d.updates;
2637-}
2638-
2639-location::Provider::Provider(
2640- const location::Provider::Features& features,
2641- const location::Provider::Requirements& requirements)
2642-{
2643- d.features = features;
2644- d.requirements = requirements;
2645- d.controller = std::shared_ptr<Provider::Controller>(new Provider::Controller(*this));
2646-}
2647-
2648-location::Provider::Updates& location::Provider::mutable_updates()
2649-{
2650- return d.updates;
2651-}
2652-
2653-void location::Provider::on_wifi_and_cell_reporting_state_changed(location::WifiAndCellIdReportingState)
2654-{
2655-}
2656-
2657-void location::Provider::on_reference_location_updated(const location::Update<location::Position>&)
2658-{
2659-}
2660-
2661-void location::Provider::on_reference_velocity_updated(const location::Update<location::Velocity>&)
2662-{
2663-}
2664-
2665-void location::Provider::on_reference_heading_updated(const location::Update<location::Heading>&)
2666-{
2667-}
2668-
2669-void location::Provider::start_position_updates() {}
2670-void location::Provider::stop_position_updates() {}
2671-void location::Provider::start_heading_updates() {}
2672-void location::Provider::stop_heading_updates() {}
2673-void location::Provider::start_velocity_updates() {}
2674-void location::Provider::stop_velocity_updates() {}
2675-
2676-location::Provider::Features location::operator|(location::Provider::Features lhs, location::Provider::Features rhs)
2677-{
2678- return static_cast<location::Provider::Features>(static_cast<unsigned int>(lhs) | static_cast<unsigned int>(rhs));
2679-}
2680-
2681-location::Provider::Features location::operator&(location::Provider::Features lhs, location::Provider::Features rhs)
2682-{
2683- return static_cast<location::Provider::Features>(static_cast<unsigned int>(lhs) & static_cast<unsigned int>(rhs));
2684-}
2685-
2686 location::Provider::Requirements location::operator|(location::Provider::Requirements lhs, location::Provider::Requirements rhs)
2687 {
2688 return static_cast<location::Provider::Requirements>(static_cast<unsigned int>(lhs) | static_cast<unsigned int>(rhs));
2689
2690=== modified file 'src/location/provider_selection.h'
2691--- src/location/provider_selection.h 2016-06-28 11:53:34 +0000
2692+++ src/location/provider_selection.h 2016-08-12 12:03:50 +0000
2693@@ -26,20 +26,6 @@
2694 {
2695 struct ProviderSelection
2696 {
2697- inline Provider::Features to_feature_flags() const
2698- {
2699- Provider::Features flags = Provider::Features::none;
2700-
2701- if (position_updates_provider)
2702- flags = flags | Provider::Features::position;
2703- if (heading_updates_provider)
2704- flags = flags | Provider::Features::heading;
2705- if(velocity_updates_provider)
2706- flags = flags | Provider::Features::velocity;
2707-
2708- return flags;
2709- }
2710-
2711 std::shared_ptr<Provider> position_updates_provider;
2712 std::shared_ptr<Provider> heading_updates_provider;
2713 std::shared_ptr<Provider> velocity_updates_provider;
2714
2715=== modified file 'src/location/providers/CMakeLists.txt'
2716--- src/location/providers/CMakeLists.txt 2014-08-22 11:16:27 +0000
2717+++ src/location/providers/CMakeLists.txt 2016-08-12 12:03:50 +0000
2718@@ -1,8 +1,7 @@
2719 add_subdirectory(dummy)
2720+add_subdirectory(fusion)
2721 add_subdirectory(remote)
2722-add_subdirectory(geoclue)
2723 add_subdirectory(gps)
2724-add_subdirectory(skyhook)
2725
2726 set(
2727 ENABLED_PROVIDER_TARGETS
2728
2729=== modified file 'src/location/providers/config.cpp'
2730--- src/location/providers/config.cpp 2016-08-12 12:03:49 +0000
2731+++ src/location/providers/config.cpp 2016-08-12 12:03:50 +0000
2732@@ -39,22 +39,6 @@
2733 location::providers::dummy::Provider::create_instance
2734 };
2735
2736-#include <location/providers/remote/provider.h>
2737-static FactoryInjector remote_injector
2738-{
2739- "remote::Provider",
2740- location::providers::remote::Provider::Stub::create_instance
2741-};
2742-
2743-#if defined(LOCATION_PROVIDERS_GEOCLUE)
2744-#include <location/providers/geoclue/provider.h>
2745-static FactoryInjector geoclue_injector
2746-{
2747- "geoclue::Provider",
2748- location::providers::geoclue::Provider::create_instance
2749-};
2750-#endif // LOCATION_PROVIDERS_GEOCLUE
2751-
2752 #if defined(LOCATION_PROVIDERS_GPS)
2753 #include <location/providers/gps/provider.h>
2754 static FactoryInjector gps_injector
2755@@ -63,12 +47,3 @@
2756 location::providers::gps::Provider::create_instance
2757 };
2758 #endif // LOCATION_PROVIDERS_GPS
2759-
2760-#if defined(LOCATION_PROVIDERS_SKYHOOK)
2761-#include <location/providers/skyhook/provider.h>
2762-static FactoryInjector skyhook_injector
2763-{
2764- "skyhook::Provider",
2765- location::providers::skyhook::Provider::create_instance
2766-};
2767-#endif // LOCATION_PROVIDERS_SKYHOOK
2768
2769=== modified file 'src/location/providers/dummy/provider.cpp'
2770--- src/location/providers/dummy/provider.cpp 2016-08-12 12:03:49 +0000
2771+++ src/location/providers/dummy/provider.cpp 2016-08-12 12:03:50 +0000
2772@@ -24,27 +24,6 @@
2773
2774 namespace dummy = location::providers::dummy;
2775
2776-struct dummy::Provider::Private
2777-{
2778- enum class State
2779- {
2780- started,
2781- stopping,
2782- stopped
2783- };
2784-
2785- Private(const dummy::Configuration& configuration)
2786- : configuration(configuration),
2787- state(State::stopped)
2788- {
2789- }
2790-
2791- dummy::Configuration configuration;
2792- std::atomic<State> state;
2793- bool stop_requested;
2794- std::thread worker{};
2795-};
2796-
2797 std::string dummy::Provider::class_name()
2798 {
2799 return "dummy::Provider";
2800@@ -93,87 +72,104 @@
2801 return location::Provider::Ptr{new dummy::Provider{provider_config}};
2802 }
2803
2804-dummy::Provider::Provider(const dummy::Configuration& config)
2805- : location::Provider(
2806- location::Provider::Features::position | location::Provider::Features::velocity | location::Provider::Features::heading,
2807- location::Provider::Requirements::none),
2808- d(new Private{config})
2809+dummy::Provider::Provider(const dummy::Configuration&)
2810 {
2811 }
2812
2813 dummy::Provider::~Provider() noexcept
2814 {
2815- stop_position_updates();
2816-
2817- if (d->worker.joinable())
2818- d->worker.join();
2819-}
2820-
2821-bool dummy::Provider::matches_criteria(const location::Criteria&)
2822+ deactivate();
2823+
2824+ if (worker.joinable())
2825+ worker.join();
2826+}
2827+
2828+void dummy::Provider::on_new_event(const Event&)
2829+{
2830+}
2831+
2832+location::Provider::Requirements dummy::Provider::requirements() const
2833+{
2834+ return Requirements::none;
2835+}
2836+
2837+bool dummy::Provider::satisfies(const location::Criteria&)
2838 {
2839 return true;
2840 }
2841
2842-void dummy::Provider::start_position_updates()
2843-{
2844- if (d->state.load() != Private::State::stopped)
2845- return;
2846-
2847- d->stop_requested = false;
2848-
2849- d->worker = std::move(std::thread([this]()
2850+void dummy::Provider::enable()
2851+{
2852+}
2853+
2854+void dummy::Provider::disable()
2855+{
2856+}
2857+
2858+void dummy::Provider::activate()
2859+{
2860+ stop_requested = false;
2861+
2862+ worker = std::move(std::thread([this]()
2863 {
2864- d->state.store(Private::State::started);
2865 VLOG(1) << __PRETTY_FUNCTION__ << ": started";
2866
2867 location::Update<location::Position> position_update
2868 {
2869- d->configuration.reference_position,
2870+ configuration.reference_position,
2871 location::Clock::now()
2872 };
2873
2874 location::Update<location::Heading> heading_update
2875 {
2876- d->configuration.reference_heading,
2877+ configuration.reference_heading,
2878 location::Clock::now()
2879 };
2880
2881 location::Update<location::Velocity> velocity_update
2882 {
2883- d->configuration.reference_velocity,
2884+ configuration.reference_velocity,
2885 location::Clock::now()
2886 };
2887
2888- while (!d->stop_requested)
2889+ while (!stop_requested)
2890 {
2891- VLOG(10) << position_update;
2892-
2893 position_update.when = location::Clock::now();
2894 heading_update.when = location::Clock::now();
2895 velocity_update.when = location::Clock::now();
2896
2897- mutable_updates().position(position_update);
2898- mutable_updates().heading(heading_update);
2899- mutable_updates().velocity(velocity_update);
2900+ updates.position(position_update);
2901+ updates.heading(heading_update);
2902+ updates.velocity(velocity_update);
2903
2904- std::this_thread::sleep_for(d->configuration.update_period);
2905+ std::this_thread::sleep_for(configuration.update_period);
2906 }
2907-
2908- d->state.store(Private::State::stopped);
2909 }));
2910 }
2911
2912-void dummy::Provider::stop_position_updates()
2913-{
2914- if (d->state.load() != Private::State::started)
2915- return;
2916-
2917- d->state.store(Private::State::stopping);
2918- VLOG(1) << __PRETTY_FUNCTION__ << ": stopping";
2919-
2920- d->stop_requested = true;
2921-
2922- if (d->worker.joinable())
2923- d->worker.join();
2924-}
2925-
2926+void dummy::Provider::deactivate()
2927+{
2928+ VLOG(1) << __PRETTY_FUNCTION__ << ": stopping";
2929+
2930+ stop_requested = true;
2931+
2932+ if (worker.joinable())
2933+ worker.join();
2934+
2935+ VLOG(1) << __PRETTY_FUNCTION__ << ": stopping";
2936+}
2937+
2938+const core::Signal<location::Update<location::Position>>& dummy::Provider::position_updates() const
2939+{
2940+ return updates.position;
2941+}
2942+
2943+const core::Signal<location::Update<location::Heading>>& dummy::Provider::heading_updates() const
2944+{
2945+ return updates.heading;
2946+}
2947+
2948+const core::Signal<location::Update<location::Velocity>>& dummy::Provider::velocity_updates() const
2949+{
2950+ return updates.velocity;
2951+}
2952
2953=== modified file 'src/location/providers/dummy/provider.h'
2954--- src/location/providers/dummy/provider.h 2016-06-27 06:44:50 +0000
2955+++ src/location/providers/dummy/provider.h 2016-08-12 12:03:50 +0000
2956@@ -21,6 +21,8 @@
2957 #include <location/provider.h>
2958 #include <location/provider_factory.h>
2959
2960+#include <thread>
2961+
2962 namespace location
2963 {
2964 namespace providers
2965@@ -68,7 +70,7 @@
2966 };
2967
2968 // Updates are delivered every update_period milliseconds.
2969- std::chrono::milliseconds update_period{500};
2970+ std::chrono::milliseconds update_period{10};
2971
2972 // The reference position that is delivered in every upate cycle.
2973 Position reference_position
2974@@ -115,17 +117,34 @@
2975 // Cleans up all resources and stops the updates.
2976 ~Provider() noexcept;
2977
2978- // Always returns true.
2979- bool matches_criteria(const Criteria&);
2980-
2981- // Starts up the updater thread and delivers position updates
2982- void start_position_updates();
2983- // Stops the updater thread.
2984- void stop_position_updates();
2985+ void on_new_event(const Event& event) override;
2986+
2987+ void enable() override;
2988+ void disable() override;
2989+ void activate() override;
2990+ void deactivate() override;
2991+
2992+ Requirements requirements() const override;
2993+ bool satisfies(const Criteria& criteria) override;
2994+ const core::Signal<Update<Position>>& position_updates() const override;
2995+ const core::Signal<Update<Heading>>& heading_updates() const override;
2996+ const core::Signal<Update<Velocity>>& velocity_updates() const override;
2997+ void on_wifi_and_cell_reporting_state_changed(WifiAndCellIdReportingState state);
2998+ void on_reference_location_updated(const Update<Position>& position);
2999+ void on_reference_velocity_updated(const Update<Velocity>& velocity);
3000+ void on_reference_heading_updated(const Update<Heading>& heading);
3001
3002 private:
3003- struct Private;
3004- std::unique_ptr<Private> d;
3005+ dummy::Configuration configuration;
3006+ std::atomic<bool> stop_requested{false};
3007+ std::thread worker{};
3008+
3009+ struct
3010+ {
3011+ core::Signal<Update<Position>> position;
3012+ core::Signal<Update<Heading>> heading;
3013+ core::Signal<Update<Velocity>> velocity;
3014+ } updates;
3015 };
3016 }
3017 }
3018
3019=== added directory 'src/location/providers/fusion'
3020=== added file 'src/location/providers/fusion/CMakeLists.txt'
3021--- src/location/providers/fusion/CMakeLists.txt 1970-01-01 00:00:00 +0000
3022+++ src/location/providers/fusion/CMakeLists.txt 2016-08-12 12:03:50 +0000
3023@@ -0,0 +1,4 @@
3024+add_library(
3025+ fusion
3026+ provider.h provider.cpp
3027+)
3028
3029=== renamed file 'src/location/newer_or_more_accurate_update_selector.h' => 'src/location/providers/fusion/newer_or_more_accurate_update_selector.h'
3030--- src/location/newer_or_more_accurate_update_selector.h 2016-06-28 11:53:34 +0000
3031+++ src/location/providers/fusion/newer_or_more_accurate_update_selector.h 2016-08-12 12:03:50 +0000
3032@@ -15,13 +15,17 @@
3033 *
3034 * Authored by: Scott Sweeny <scott.sweeny@canonical.com
3035 */
3036-#ifndef LOCATION_NEWER_OR_MORE_ACCURATE_UPDATE_SELECTOR_H
3037-#define LOCATION_NEWER_OR_MORE_ACCURATE_UPDATE_SELECTOR_H
3038+#ifndef LOCATION_PROVIDERS_FUSION_NEWER_OR_MORE_ACCURATE_UPDATE_SELECTOR_H
3039+#define LOCATION_PROVIDERS_FUSION_NEWER_OR_MORE_ACCURATE_UPDATE_SELECTOR_H
3040
3041-#include <location/update_selector.h>
3042+#include <location/providers/fusion/update_selector.h>
3043
3044 namespace location
3045 {
3046+namespace providers
3047+{
3048+namespace fusion
3049+{
3050 class NewerOrMoreAccurateUpdateSelector : public UpdateSelector
3051 {
3052 public:
3053@@ -34,7 +38,7 @@
3054 static const std::chrono::seconds cutoff(11);
3055
3056 // If the new position is from the same source as the old one then just use it
3057- if (newer.source == older.source) {
3058+ if (newer.source.lock() == older.source.lock()) {
3059 return newer;
3060 }
3061
3062@@ -55,6 +59,8 @@
3063 }
3064 };
3065 }
3066+}
3067+}
3068
3069-#endif // LOCATION_NEWER_OR_MORE_ACCURATE_UPDATE_SELECTOR_H
3070+#endif // LOCATION_PROVIDERS_FUSION_NEWER_OR_MORE_ACCURATE_UPDATE_SELECTOR_H
3071
3072
3073=== renamed file 'src/location/newer_update_selector.h' => 'src/location/providers/fusion/newer_update_selector.h'
3074--- src/location/newer_update_selector.h 2016-06-28 11:53:34 +0000
3075+++ src/location/providers/fusion/newer_update_selector.h 2016-08-12 12:03:50 +0000
3076@@ -27,7 +27,7 @@
3077 public:
3078 typedef std::shared_ptr<NewerUpdateSelector> Ptr;
3079
3080- virtual WithSource<Update<Position>> select(const WithSource<Update<Position>>& older,
3081+ virtual WithSource<Update<Position>> select(const WithSource<Update<Position>>&,
3082 const WithSource<Update<Position>>& newer) override
3083 {
3084 return newer;
3085
3086=== renamed file 'src/location/fusion_provider.cpp' => 'src/location/providers/fusion/provider.cpp'
3087--- src/location/fusion_provider.cpp 2016-06-26 21:17:03 +0000
3088+++ src/location/providers/fusion/provider.cpp 2016-08-12 12:03:50 +0000
3089@@ -15,125 +15,117 @@
3090 *
3091 * Authored by: Scott Sweeny <scott.sweeny@canonical.com
3092 */
3093- #include <location/fusion_provider.h>
3094- #include <location/logging.h>
3095- #include <location/update.h>
3096-
3097-location::Provider::Features all_features()
3098-{
3099- return location::Provider::Features::position |
3100- location::Provider::Features::heading |
3101- location::Provider::Features::velocity;
3102-}
3103-
3104-location::Provider::Requirements all_requirements()
3105-{
3106- return location::Provider::Requirements::cell_network |
3107- location::Provider::Requirements::data_network |
3108- location::Provider::Requirements::monetary_spending |
3109- location::Provider::Requirements::satellites;
3110-}
3111-
3112-location::FusionProvider::FusionProvider(const std::set<location::Provider::Ptr>& providers, const UpdateSelector::Ptr& update_selector)
3113- : Provider{all_features(), all_requirements()},
3114- providers{providers}
3115-{
3116+
3117+#include <location/providers/fusion/provider.h>
3118+
3119+#include <location/logging.h>
3120+#include <location/update.h>
3121+
3122+namespace fusion = location::providers::fusion;
3123+
3124+fusion::Provider::Provider(const std::set<location::Provider::Ptr>& providers, const UpdateSelector::Ptr& update_selector)
3125+ : providers{providers}
3126+{
3127+}
3128+
3129+void fusion::Provider::on_new_event(const Event& event)
3130+{
3131+ for (auto provider : providers) provider->on_new_event(event);
3132+}
3133+
3134+void fusion::Provider::enable()
3135+{
3136+ for (auto provider : providers) provider->enable();
3137+}
3138+
3139+void fusion::Provider::disable()
3140+{
3141+ for (auto provider : providers) provider->disable();
3142+}
3143+
3144+void fusion::Provider::activate()
3145+{
3146+ for (auto provider : providers) provider->activate();
3147+}
3148+
3149+void fusion::Provider::deactivate()
3150+{
3151+ for (auto provider : providers) provider->deactivate();
3152+}
3153+
3154+location::Provider::Requirements fusion::Provider::requirements() const
3155+{
3156+ location::Provider::Requirements reqs{location::Provider::Requirements::none};
3157+ for (auto provider : providers) reqs = reqs | provider->requirements();
3158+ return reqs;
3159+}
3160+
3161+bool fusion::Provider::satisfies(const Criteria& criteria)
3162+{
3163+ bool result{true};
3164+ for (auto provider : providers) result &= provider->satisfies(criteria);
3165+ return result;
3166+}
3167+
3168+const core::Signal<location::Update<location::Position>>& fusion::Provider::position_updates() const
3169+{
3170+ return updates.position;
3171+}
3172+
3173+const core::Signal<location::Update<location::Heading>>& fusion::Provider::heading_updates() const
3174+{
3175+ return updates.heading;
3176+}
3177+
3178+const core::Signal<location::Update<location::Velocity>>& fusion::Provider::velocity_updates() const
3179+{
3180+ return updates.velocity;
3181+}
3182+
3183+fusion::Provider::Ptr fusion::Provider::finalize(const UpdateSelector::Ptr& update_selector)
3184+{
3185+ auto sp = shared_from_this(); std::weak_ptr<fusion::Provider> wp{sp};
3186
3187 for (auto provider : providers)
3188 {
3189- connections.push_back(provider->updates().position.connect(
3190- [this, provider, update_selector](const location::Update<location::Position>& u)
3191+ provider->position_updates().connect(
3192+ [wp, provider, update_selector](const location::Update<location::Position>& u)
3193 {
3194- // if this is the first update, use it
3195- if (!last_position) {
3196- mutable_updates().position((*(last_position = WithSource<Update<Position>>{provider, u})).value);
3197-
3198- // otherwise use the selector
3199- } else {
3200- try {
3201- mutable_updates().position((*(last_position = update_selector->select(*last_position, WithSource<Update<Position>>{provider, u}))).value);
3202- } catch (const std::exception& e) {
3203- LOG(WARNING) << "Error while updating position";
3204+ if (auto sp = wp.lock())
3205+ {
3206+ // if this is the first update, use it
3207+ if (!sp->last_position) {
3208+ sp->updates.position((*(sp->last_position = WithSource<Update<Position>>{provider, u})).value);
3209+
3210+ // otherwise use the selector
3211+ } else {
3212+ try {
3213+ sp->updates.position((*(sp->last_position = update_selector->select(*sp->last_position, WithSource<Update<Position>>{provider, u}))).value);
3214+ } catch (const std::exception& e) {
3215+ LOG(WARNING) << "Error while updating position";
3216+ }
3217 }
3218 }
3219- }));
3220- connections.push_back(provider->updates().heading.connect(
3221- [this](const location::Update<location::Heading>& u)
3222- {
3223- mutable_updates().heading(u);
3224- }));
3225- connections.push_back(provider->updates().velocity.connect(
3226- [this](const location::Update<location::Velocity>& u)
3227- {
3228- mutable_updates().velocity(u);
3229- }));
3230+ });
3231+ provider->heading_updates().connect(
3232+ [wp](const location::Update<location::Heading>& u)
3233+ {
3234+ if (auto sp = wp.lock())
3235+ sp->updates.heading(u);
3236+ });
3237+ provider->velocity_updates().connect(
3238+ [wp](const location::Update<location::Velocity>& u)
3239+ {
3240+ if (auto sp = wp.lock())
3241+ sp->updates.velocity(u);
3242+ });
3243 }
3244
3245-}
3246-
3247-// We always match :)
3248-bool location::FusionProvider::matches_criteria(const location::Criteria&)
3249-{
3250- return true;
3251-}
3252-
3253-// We forward all events to the other providers.
3254-void location::FusionProvider::on_wifi_and_cell_reporting_state_changed(location::WifiAndCellIdReportingState state)
3255-{
3256- for (auto provider : providers)
3257- provider->on_wifi_and_cell_reporting_state_changed(state);
3258-}
3259-
3260-void location::FusionProvider::on_reference_location_updated(const location::Update<location::Position>& position)
3261-{
3262- for (auto provider : providers)
3263- provider->on_reference_location_updated(position);
3264-}
3265-
3266-void location::FusionProvider::on_reference_velocity_updated(const location::Update<location::Velocity>& velocity)
3267-{
3268- for (auto provider : providers)
3269- provider->on_reference_velocity_updated(velocity);
3270-}
3271-
3272-void location::FusionProvider::on_reference_heading_updated(const location::Update<location::Heading>& heading)
3273-{
3274- for (auto provider : providers)
3275- provider->on_reference_heading_updated(heading);
3276-}
3277-
3278-void location::FusionProvider::start_position_updates()
3279-{
3280- for (auto provider : providers)
3281- provider->state_controller()->start_position_updates();
3282-}
3283-
3284-void location::FusionProvider::stop_position_updates()
3285-{
3286- for (auto provider : providers)
3287- provider->state_controller()->stop_position_updates();
3288-}
3289-
3290-void location::FusionProvider::start_heading_updates()
3291-{
3292- for (auto provider : providers)
3293- provider->state_controller()->start_heading_updates();
3294-}
3295-
3296-void location::FusionProvider::stop_heading_updates()
3297-{
3298- for (auto provider : providers)
3299- provider->state_controller()->stop_heading_updates();
3300-}
3301-
3302-void location::FusionProvider::start_velocity_updates()
3303-{
3304- for (auto provider : providers)
3305- provider->state_controller()->start_velocity_updates();
3306-}
3307-
3308-void location::FusionProvider::stop_velocity_updates()
3309-{
3310- for (auto provider : providers)
3311- provider->state_controller()->stop_velocity_updates();
3312+ return sp;
3313+}
3314+
3315+fusion::Provider::Ptr fusion::Provider::create(const std::set<location::Provider::Ptr>& providers, const UpdateSelector::Ptr& update_selector)
3316+{
3317+ auto sp = fusion::Provider::Ptr{new fusion::Provider{providers, update_selector}};
3318+ return sp->finalize(update_selector);
3319 }
3320
3321=== renamed file 'src/location/fusion_provider.h' => 'src/location/providers/fusion/provider.h'
3322--- src/location/fusion_provider.h 2016-06-28 11:53:34 +0000
3323+++ src/location/providers/fusion/provider.h 2016-08-12 12:03:50 +0000
3324@@ -15,39 +15,57 @@
3325 *
3326 * Authored by: Scott Sweeny <scott.sweeny@canonical.com
3327 */
3328-#ifndef LOCATION_FUSION_PROVIDER_H
3329-#define LOCATION_FUSION_PROVIDER_H
3330+#ifndef LOCATION_PROVIDERS_FUSION_PROVIDER_H
3331+#define LOCATION_PROVIDERS_FUSION_PROVIDER_H
3332
3333 #include <location/provider.h>
3334-#include <location/provider_selection_policy.h>
3335-#include <location/update_selector.h>
3336+#include <location/providers/fusion/update_selector.h>
3337
3338 namespace location
3339 {
3340-class FusionProvider : public Provider
3341+namespace providers
3342+{
3343+namespace fusion
3344+{
3345+class Provider : public std::enable_shared_from_this<Provider>, public location::Provider
3346 {
3347 public:
3348- typedef std::shared_ptr<FusionProvider> Ptr;
3349-
3350- FusionProvider(const std::set<Provider::Ptr>& providers, const UpdateSelector::Ptr& update_selector);
3351-
3352- bool matches_criteria(const Criteria &criteria) override;
3353- void on_wifi_and_cell_reporting_state_changed(location::WifiAndCellIdReportingState state) override;
3354- void on_reference_location_updated(const Update<Position>& position) override;
3355- void on_reference_velocity_updated(const Update<Velocity>& velocity) override;
3356- void on_reference_heading_updated(const Update<Heading>& heading) override;
3357- void start_position_updates() override;
3358- void stop_position_updates() override;
3359- void start_heading_updates() override;
3360- void stop_heading_updates() override;
3361- void start_velocity_updates() override;
3362- void stop_velocity_updates() override;
3363+ typedef std::shared_ptr<Provider> Ptr;
3364+
3365+ static Ptr create(const std::set<location::Provider::Ptr>& providers, const UpdateSelector::Ptr& update_selector);
3366+
3367+ // From Provider
3368+ void on_new_event(const Event& event) override;
3369+
3370+ void enable() override;
3371+ void disable() override;
3372+ void activate() override;
3373+ void deactivate() override;
3374+
3375+ Requirements requirements() const override;
3376+ bool satisfies(const Criteria& criteria) override;
3377+ const core::Signal<Update<Position>>& position_updates() const override;
3378+ const core::Signal<Update<Heading>>& heading_updates() const override;
3379+ const core::Signal<Update<Velocity>>& velocity_updates() const override;
3380
3381 private:
3382+ Provider(const std::set<location::Provider::Ptr>& providers, const UpdateSelector::Ptr& update_selector);
3383+
3384+ std::shared_ptr<Provider> finalize(const UpdateSelector::Ptr& update_selector);
3385+
3386 Optional<WithSource<Update<Position>>> last_position;
3387- std::set<Provider::Ptr> providers;
3388+ std::set<location::Provider::Ptr> providers;
3389 std::vector<core::ScopedConnection> connections;
3390+
3391+ struct
3392+ {
3393+ core::Signal<Update<Position>> position;
3394+ core::Signal<Update<Heading>> heading;
3395+ core::Signal<Update<Velocity>> velocity;
3396+ } updates;
3397 };
3398 }
3399+}
3400+}
3401
3402-#endif // LOCATION_FUSION_PROVIDER_H
3403+#endif // LOCATION_PROVIDERS_FUSION_PROVIDER_H
3404
3405=== renamed file 'src/location/update_selector.h' => 'src/location/providers/fusion/update_selector.h'
3406--- src/location/update_selector.h 2016-06-28 11:53:34 +0000
3407+++ src/location/providers/fusion/update_selector.h 2016-08-12 12:03:50 +0000
3408@@ -25,7 +25,7 @@
3409 {
3410
3411 template<typename T>
3412-struct WithSource { std::shared_ptr<Provider> source; T value; };
3413+struct WithSource { std::weak_ptr<Provider> source; T value; };
3414
3415 class UpdateSelector
3416 {
3417
3418=== removed directory 'src/location/providers/geoclue'
3419=== removed file 'src/location/providers/geoclue/CMakeLists.txt'
3420--- src/location/providers/geoclue/CMakeLists.txt 2016-06-27 06:44:50 +0000
3421+++ src/location/providers/geoclue/CMakeLists.txt 1970-01-01 00:00:00 +0000
3422@@ -1,24 +0,0 @@
3423-option(
3424- LOCATION_ENABLE_GEOCLUE_PROVIDER
3425- "Enable location provider connecting to existing geoclue providers"
3426- ON
3427-)
3428-
3429-if (LOCATION_ENABLE_GEOCLUE_PROVIDER)
3430-
3431- message(STATUS "Enabling support for Geoclue location providers")
3432-
3433- add_library(geoclue provider.cpp)
3434-
3435- set(
3436- ENABLED_PROVIDER_TARGETS
3437- ${ENABLED_PROVIDER_TARGETS} geoclue
3438- PARENT_SCOPE
3439- )
3440-
3441- set(
3442- ENABLED_PROVIDER_TARGETS_DEFINITIONS
3443- -DLOCATION_PROVIDERS_GEOCLUE ${ENABLED_PROVIDER_TARGETS_DEFINITIONS}
3444- PARENT_SCOPE
3445- )
3446-endif (LOCATION_ENABLE_GEOCLUE_PROVIDER)
3447
3448=== removed file 'src/location/providers/geoclue/geoclue.h'
3449--- src/location/providers/geoclue/geoclue.h 2016-06-26 21:17:03 +0000
3450+++ src/location/providers/geoclue/geoclue.h 1970-01-01 00:00:00 +0000
3451@@ -1,257 +0,0 @@
3452-/*
3453- * Copyright © 2012-2013 Canonical Ltd.
3454- *
3455- * This program is free software: you can redistribute it and/or modify it
3456- * under the terms of the GNU Lesser General Public License version 3,
3457- * as published by the Free Software Foundation.
3458- *
3459- * This program is distributed in the hope that it will be useful,
3460- * but WITHOUT ANY WARRANTY; without even the implied warranty of
3461- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3462- * GNU Lesser General Public License for more details.
3463- *
3464- * You should have received a copy of the GNU Lesser General Public License
3465- * along with this program. If not, see <http://www.gnu.org/licenses/>.
3466- *
3467- * Authored by: Thomas Voß <thomas.voss@canonical.com>
3468- */
3469-#ifndef LOCATION_PROVIDERS_GEOCLUE_GEOCLUE_H_
3470-#define LOCATION_PROVIDERS_GEOCLUE_GEOCLUE_H_
3471-
3472-#include <core/dbus/service.h>
3473-#include <core/dbus/traits/service.h>
3474-#include <core/dbus/types/struct.h>
3475-#include <core/dbus/types/stl/tuple.h>
3476-
3477-#include <string>
3478-
3479-namespace dbus = core::dbus;
3480-
3481-namespace org
3482-{
3483-namespace freedesktop
3484-{
3485-struct Geoclue
3486-{
3487- enum class Status : int
3488- {
3489- error,
3490- unavailable,
3491- acquiring,
3492- available
3493- };
3494-
3495- friend std::ostream& operator<<(std::ostream& out, const Status& status)
3496- {
3497- static std::map<Status, std::string> lut =
3498- {
3499- {Status::error, "error"},
3500- {Status::unavailable, "unavailable"},
3501- {Status::acquiring, "acquiring"},
3502- {Status::available, "available"}
3503- };
3504-
3505- return out << lut[status];
3506- }
3507-
3508- struct GetProviderInfo
3509- {
3510- inline static std::string name()
3511- {
3512- return "GetProviderInfo";
3513- }
3514- typedef Geoclue Interface;
3515- typedef std::tuple<std::string, std::string> ResultType;
3516- inline static const std::chrono::milliseconds default_timeout() { return std::chrono::seconds{1}; }
3517- };
3518-
3519- struct GetStatus
3520- {
3521- inline static std::string name()
3522- {
3523- return "GetStatus";
3524- }
3525- typedef Geoclue Interface;
3526- typedef int32_t ResultType;
3527- inline static const std::chrono::milliseconds default_timeout() { return std::chrono::seconds{1}; }
3528- };
3529-
3530- struct AddReference
3531- {
3532- inline static std::string name()
3533- {
3534- return "AddReference";
3535- }
3536- typedef Geoclue Interface;
3537- typedef void ResultType;
3538- inline static const std::chrono::milliseconds default_timeout() { return std::chrono::seconds{1}; }
3539- };
3540-
3541- struct RemoveReference
3542- {
3543- inline static std::string name()
3544- {
3545- return "RemoveReference";
3546- }
3547- typedef Geoclue Interface;
3548- typedef void ResultType;
3549- inline static const std::chrono::milliseconds default_timeout() { return std::chrono::seconds{1}; }
3550- };
3551-
3552- struct Address
3553- {
3554- struct GetAddress
3555- {
3556- inline static std::string name()
3557- {
3558- return "GetAddress";
3559- }
3560- typedef Address Interface;
3561- typedef std::tuple<int32_t, std::map<std::string, std::string>, dbus::types::Struct<std::tuple<int32_t, double, double>>> ResultType;
3562- inline static const std::chrono::milliseconds default_timeout() { return std::chrono::seconds{1}; }
3563- };
3564-
3565- struct Signals
3566- {
3567- struct AddressChanged
3568- {
3569- inline static std::string name()
3570- {
3571- return "PositionChanged";
3572- };
3573- typedef Address Interface;
3574- typedef std::tuple<int32_t, std::map<std::string, std::string>, dbus::types::Struct<std::tuple<int32_t, double, double>>> ArgumentType;
3575- };
3576- };
3577- };
3578-
3579- struct Position
3580- {
3581- struct Field
3582- {
3583- Field() = delete;
3584-
3585- static const int none = 0;
3586- static const int latitude = 1;
3587- static const int longitude = 2;
3588- static const int altitude = 3;
3589- };
3590-
3591- typedef std::bitset<4> FieldFlags;
3592-
3593- struct GetPosition
3594- {
3595- inline static std::string name()
3596- {
3597- return "GetPosition";
3598- }
3599- typedef Position Interface;
3600- typedef std::tuple<int32_t, int32_t, double, double, double, dbus::types::Struct<std::tuple<int32_t, double, double>>> ResultType;
3601- inline static const std::chrono::milliseconds default_timeout() { return std::chrono::seconds{1}; }
3602- };
3603-
3604- struct Signals
3605- {
3606- struct PositionChanged
3607- {
3608- inline static std::string name()
3609- {
3610- return "PositionChanged";
3611- };
3612- typedef Position Interface;
3613- typedef std::tuple<int32_t, int32_t, double, double, double, dbus::types::Struct<std::tuple<int32_t, double, double>>> ArgumentType;
3614- };
3615- };
3616- };
3617-
3618- struct Velocity
3619- {
3620- struct Field
3621- {
3622- Field() = delete;
3623-
3624- static const int none = 0;
3625- static const int speed = 1;
3626- static const int direction = 2;
3627- static const int climb = 3;
3628- };
3629-
3630- typedef std::bitset<4> FieldFlags;
3631-
3632- struct GetVelocity
3633- {
3634- inline static std::string name()
3635- {
3636- return "GetVelocity";
3637- }
3638- typedef Velocity Interface;
3639- typedef std::tuple<int32_t, int32_t, double, double, double> ResultType;
3640- inline static const std::chrono::milliseconds default_timeout() { return std::chrono::seconds{1}; }
3641- };
3642- struct Signals
3643- {
3644- struct VelocityChanged
3645- {
3646- inline static std::string name()
3647- {
3648- return "VelocityChanged";
3649- };
3650- typedef Velocity Interface;
3651- typedef std::tuple<int32_t, int32_t, double, double, double> ArgumentType;
3652- };
3653- };
3654- };
3655-};
3656-}
3657-}
3658-
3659-namespace core
3660-{
3661-namespace dbus
3662-{
3663-namespace traits
3664-{
3665-template<>
3666-struct Service<org::freedesktop::Geoclue>
3667-{
3668- inline static const std::string& interface_name()
3669- {
3670- static const std::string s{"org.freedesktop.Geoclue"};
3671- return s;
3672- }
3673-};
3674-
3675-template<>
3676-struct Service<org::freedesktop::Geoclue::Address>
3677-{
3678- inline static const std::string& interface_name()
3679- {
3680- static const std::string s{"org.freedesktop.Geoclue.Address"};
3681- return s;
3682- }
3683-};
3684-
3685-template<>
3686-struct Service<org::freedesktop::Geoclue::Position>
3687-{
3688- inline static const std::string& interface_name()
3689- {
3690- static const std::string s{"org.freedesktop.Geoclue.Position"};
3691- return s;
3692- }
3693-};
3694-
3695-template<>
3696-struct Service<org::freedesktop::Geoclue::Velocity>
3697-{
3698- inline static const std::string& interface_name()
3699- {
3700- static const std::string s{"org.freedesktop.Geoclue.Velocity"};
3701- return s;
3702- }
3703-};
3704-}
3705-}
3706-}
3707-
3708-#endif // LOCATION_PROVIDERS_GEOCLUE_GEOCLUE_H_
3709
3710=== removed file 'src/location/providers/geoclue/provider.cpp'
3711--- src/location/providers/geoclue/provider.cpp 2016-06-26 21:17:03 +0000
3712+++ src/location/providers/geoclue/provider.cpp 1970-01-01 00:00:00 +0000
3713@@ -1,165 +0,0 @@
3714-/*
3715- * Copyright © 2012-2015 Canonical Ltd.
3716- *
3717- * This program is free software: you can redistribute it and/or modify it
3718- * under the terms of the GNU Lesser General Public License version 3,
3719- * as published by the Free Software Foundation.
3720- *
3721- * This program is distributed in the hope that it will be useful,
3722- * but WITHOUT ANY WARRANTY; without even the implied warranty of
3723- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3724- * GNU Lesser General Public License for more details.
3725- *
3726- * You should have received a copy of the GNU Lesser General Public License
3727- * along with this program. If not, see <http://www.gnu.org/licenses/>.
3728- *
3729- * Authored by: Thomas Voß <thomas.voss@canonical.com>
3730- * Manuel de la Pena <manuel.delapena@canonial.com>
3731- */
3732-
3733-#include "provider.h"
3734-
3735-namespace dbus = core::dbus;
3736-
3737-namespace
3738-{
3739-dbus::Bus::Ptr the_session_bus()
3740-{
3741- static dbus::Bus::Ptr session_bus = std::make_shared<dbus::Bus>(dbus::WellKnownBus::session);
3742- return session_bus;
3743-}
3744-}
3745-
3746-void location::providers::geoclue::Provider::start()
3747-{
3748- if (!worker.joinable())
3749- worker = std::move(std::thread{std::bind(&dbus::Bus::run, bus)});
3750-}
3751-
3752-void location::providers::geoclue::Provider::stop()
3753-{
3754- bus->stop();
3755- if (worker.joinable())
3756- worker.join();
3757-}
3758-
3759-void location::providers::geoclue::Provider::on_position_changed(const fd::Geoclue::Position::Signals::PositionChanged::ArgumentType& arg)
3760-{
3761- fd::Geoclue::Position::FieldFlags flags{static_cast<unsigned long>(std::get<0>(arg))};
3762- location::Position pos
3763- {
3764- flags.test(fd::Geoclue::Position::Field::latitude) ?
3765- location::wgs84::Latitude{std::get<2>(arg)* location::units::Degrees} : location::wgs84::Latitude{},
3766- flags.test(fd::Geoclue::Position::Field::longitude) ?
3767- location::wgs84::Longitude{std::get<3>(arg)* location::units::Degrees} : location::wgs84::Longitude{}
3768- };
3769-
3770- if (flags.test(fd::Geoclue::Position::Field::altitude))
3771- pos.altitude = location::wgs84::Altitude{std::get<4>(arg)* location::units::Meters};
3772-
3773- location::Update<location::Position> update(pos);
3774- mutable_updates().position(update);
3775-}
3776-
3777-void location::providers::geoclue::Provider::on_velocity_changed(const fd::Geoclue::Velocity::Signals::VelocityChanged::ArgumentType& arg)
3778-{
3779- fd::Geoclue::Velocity::FieldFlags flags{static_cast<unsigned long>(std::get<0>(arg))};
3780- if (flags.none())
3781- return;
3782- if (flags.test(fd::Geoclue::Velocity::Field::speed))
3783- {
3784- location::Update<location::Velocity> update
3785- {
3786- std::get<2>(arg) * location::units::MetersPerSecond,
3787- location::Clock::now()
3788- };
3789- mutable_updates().velocity(update);
3790- }
3791-
3792- if (flags.test(fd::Geoclue::Velocity::Field::direction))
3793- {
3794- location::Update<location::Heading> update
3795- {
3796- std::get<3>(arg) * location::units::Degrees,
3797- location::Clock::now()
3798- };
3799-
3800- mutable_updates().heading(update);
3801- }
3802-}
3803-
3804-location::Provider::Ptr location::providers::geoclue::Provider::create_instance(const location::ProviderFactory::Configuration& config)
3805-{
3806- location::providers::geoclue::Provider::Configuration pConfig;
3807- pConfig.name = config.count(Configuration::key_name()) > 0 ?
3808- config.get<std::string>(Configuration::key_name()) : throw std::runtime_error("Missing bus-name");
3809- pConfig.path = config.count(Configuration::key_path()) > 0 ?
3810- config.get<std::string>(Configuration::key_path()) : throw std::runtime_error("Missing bus-path");
3811- return location::Provider::Ptr{new location::providers::geoclue::Provider{pConfig}};
3812-}
3813-
3814-location::providers::geoclue::Provider::Provider(const location::providers::geoclue::Provider::Configuration& config)
3815- : location::Provider(config.features, config.requirements),
3816- bus(the_session_bus()),
3817- service(dbus::Service::use_service(bus, config.name)),
3818- object(service->object_for_path(config.path)),
3819- signal_position_changed(object->get_signal<fd::Geoclue::Position::Signals::PositionChanged>()),
3820- signal_velocity_changed(object->get_signal<fd::Geoclue::Velocity::Signals::VelocityChanged>())
3821-{
3822- position_updates_connection = signal_position_changed->connect(
3823- std::bind(&location::providers::geoclue::Provider::on_position_changed, this, std::placeholders::_1));
3824- velocity_updates_connection = signal_velocity_changed->connect(
3825- std::bind(&location::providers::geoclue::Provider::on_velocity_changed, this, std::placeholders::_1));
3826-
3827- auto info = object->invoke_method_synchronously<
3828- fd::Geoclue::GetProviderInfo,
3829- fd::Geoclue::GetProviderInfo::ResultType>();
3830- auto status = object->invoke_method_synchronously<
3831- fd::Geoclue::GetStatus,
3832- fd::Geoclue::GetStatus::ResultType>();
3833-
3834- std::cout << "GeoclueProvider: ["
3835- << std::get<0>(info.value()) << ", "
3836- << std::get<1>(info.value()) << ","
3837- << static_cast<fd::Geoclue::Status>(status.value()) << "]" <<std::endl;
3838-}
3839-
3840-location::providers::geoclue::Provider::~Provider() noexcept
3841-{
3842- stop();
3843-}
3844-
3845-bool location::providers::geoclue::Provider::matches_criteria(const location::Criteria&)
3846-{
3847- return true;
3848-}
3849-
3850-void location::providers::geoclue::Provider::start_position_updates()
3851-{
3852- start();
3853-}
3854-
3855-void location::providers::geoclue::Provider::stop_position_updates()
3856-{
3857- stop();
3858-}
3859-
3860-void location::providers::geoclue::Provider::start_velocity_updates()
3861-{
3862- start();
3863-}
3864-
3865-void location::providers::geoclue::Provider::stop_velocity_updates()
3866-{
3867- stop();
3868-}
3869-
3870-void location::providers::geoclue::Provider::start_heading_updates()
3871-{
3872- start();
3873-}
3874-
3875-void location::providers::geoclue::Provider::stop_heading_updates()
3876-{
3877- stop();
3878-}
3879
3880=== removed file 'src/location/providers/geoclue/provider.h'
3881--- src/location/providers/geoclue/provider.h 2016-06-26 21:17:03 +0000
3882+++ src/location/providers/geoclue/provider.h 1970-01-01 00:00:00 +0000
3883@@ -1,106 +0,0 @@
3884-/*
3885- * Copyright © 2012-2013 Canonical Ltd.
3886- *
3887- * This program is free software: you can redistribute it and/or modify it
3888- * under the terms of the GNU Lesser General Public License version 3,
3889- * as published by the Free Software Foundation.
3890- *
3891- * This program is distributed in the hope that it will be useful,
3892- * but WITHOUT ANY WARRANTY; without even the implied warranty of
3893- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3894- * GNU Lesser General Public License for more details.
3895- *
3896- * You should have received a copy of the GNU Lesser General Public License
3897- * along with this program. If not, see <http://www.gnu.org/licenses/>.
3898- *
3899- * Authored by: Thomas Voß <thomas.voss@canonical.com>
3900- * Manuel de la Pena <manuel.delapena@canonical.com>
3901- */
3902-#ifndef LOCATION_PROVIDERS_GEOCLUE_PROVIDER_H_
3903-#define LOCATION_PROVIDERS_GEOCLUE_PROVIDER_H_
3904-
3905-#include <core/dbus/object.h>
3906-#include <core/dbus/signal.h>
3907-
3908-#include "core/dbus/object.h"
3909-#include "core/dbus/signal.h"
3910-
3911-#include <location/provider.h>
3912-#include <location/provider_factory.h>
3913-
3914-#include <thread>
3915-
3916-#include "geoclue.h"
3917-
3918-namespace fd = org::freedesktop;
3919-
3920-namespace location
3921-{
3922-namespace providers
3923-{
3924-namespace geoclue
3925-{
3926-class Provider : public location::Provider
3927-{
3928-
3929- typedef dbus::Signal<
3930- fd::Geoclue::Position::Signals::PositionChanged,
3931- fd::Geoclue::Position::Signals::PositionChanged::ArgumentType
3932- > PositionChanged;
3933-
3934- typedef dbus::Signal<
3935- fd::Geoclue::Velocity::Signals::VelocityChanged,
3936- fd::Geoclue::Velocity::Signals::VelocityChanged::ArgumentType
3937- > VelocityChanged;
3938-
3939- public:
3940- static Provider::Ptr create_instance(const ProviderFactory::Configuration&);
3941-
3942- struct Configuration
3943- {
3944- static std::string key_name() { return "name"; }
3945- static std::string key_path() { return "path"; }
3946- std::string name;
3947- std::string path;
3948-
3949- Provider::Features features = Provider::Features::none;
3950- Provider::Requirements requirements = Provider::Requirements::none;
3951- };
3952-
3953- Provider(const Configuration& config);
3954- ~Provider() noexcept;
3955-
3956- virtual bool matches_criteria(const Criteria&);
3957-
3958- virtual void start_position_updates() override;
3959- virtual void stop_position_updates() override;
3960-
3961- virtual void start_velocity_updates() override;
3962- virtual void stop_velocity_updates() override;
3963-
3964- virtual void start_heading_updates() override;
3965- virtual void stop_heading_updates() override;
3966-
3967- private:
3968- void start();
3969- void stop();
3970-
3971- void on_position_changed(const fd::Geoclue::Position::Signals::PositionChanged::ArgumentType& arg);
3972- void on_velocity_changed(const fd::Geoclue::Velocity::Signals::VelocityChanged::ArgumentType& arg);
3973-
3974- private:
3975- dbus::Bus::Ptr bus;
3976- dbus::Service::Ptr service;
3977- dbus::Object::Ptr object;
3978- PositionChanged::Ptr signal_position_changed;
3979- VelocityChanged::Ptr signal_velocity_changed;
3980- PositionChanged::SubscriptionToken position_updates_connection;
3981- VelocityChanged::SubscriptionToken velocity_updates_connection;
3982-
3983- std::thread worker;
3984-};
3985-}
3986-}
3987-}
3988-
3989-#endif // LOCATION_PROVIDERS_GEOCLUE_PROVIDER_H_
3990
3991=== modified file 'src/location/providers/gps/provider.cpp'
3992--- src/location/providers/gps/provider.cpp 2016-06-27 10:56:44 +0000
3993+++ src/location/providers/gps/provider.cpp 2016-08-12 12:03:50 +0000
3994@@ -37,30 +37,27 @@
3995 }
3996
3997 location::providers::gps::Provider::Provider(const std::shared_ptr<HardwareAbstractionLayer>& hal)
3998- : location::Provider(
3999- location::Provider::Features::position | location::Provider::Features::velocity | location::Provider::Features::heading,
4000- location::Provider::Requirements::satellites),
4001- hal(hal)
4002+ : hal(hal)
4003 {
4004
4005 hal->position_updates().connect([this](const location::Position& pos)
4006 {
4007- mutable_updates().position(Update<Position>(pos));
4008+ updates.position(Update<Position>(pos));
4009 });
4010
4011 hal->heading_updates().connect([this](const location::Heading& heading)
4012 {
4013- mutable_updates().heading(Update<Heading>(heading));
4014+ updates.heading(Update<Heading>(heading));
4015 });
4016
4017 hal->velocity_updates().connect([this](const location::Velocity& velocity)
4018 {
4019- mutable_updates().velocity(Update<Velocity>(velocity));
4020+ updates.velocity(Update<Velocity>(velocity));
4021 });
4022
4023 hal->space_vehicle_updates().connect([this](const std::set<location::SpaceVehicle>& svs)
4024 {
4025- mutable_updates().svs(Update<std::set<location::SpaceVehicle>>(svs));
4026+ updates.svs(Update<std::set<location::SpaceVehicle>>(svs));
4027 });
4028 }
4029
4030@@ -68,39 +65,59 @@
4031 {
4032 }
4033
4034-bool location::providers::gps::Provider::matches_criteria(const location::Criteria&)
4035+void location::providers::gps::Provider::on_new_event(const Event&)
4036+{
4037+}
4038+
4039+location::Provider::Requirements location::providers::gps::Provider::requirements() const
4040+{
4041+ return Requirements::satellites;
4042+}
4043+
4044+bool location::providers::gps::Provider::satisfies(const location::Criteria&)
4045 {
4046 return true;
4047 }
4048
4049-void location::providers::gps::Provider::start_position_updates()
4050+void location::providers::gps::Provider::enable()
4051+{
4052+}
4053+
4054+void location::providers::gps::Provider::disable()
4055+{
4056+}
4057+
4058+void location::providers::gps::Provider::activate()
4059 {
4060 hal->start_positioning();
4061 }
4062
4063-void location::providers::gps::Provider::stop_position_updates()
4064+void location::providers::gps::Provider::deactivate()
4065 {
4066 hal->stop_positioning();
4067 }
4068
4069-void location::providers::gps::Provider::start_velocity_updates()
4070-{
4071-}
4072-
4073-void location::providers::gps::Provider::stop_velocity_updates()
4074-{
4075-}
4076-
4077-void location::providers::gps::Provider::start_heading_updates()
4078-{
4079-}
4080-
4081-void location::providers::gps::Provider::stop_heading_updates()
4082-{
4083+const core::Signal<location::Update<location::Position>>& location::providers::gps::Provider::position_updates() const
4084+{
4085+ return updates.position;
4086+}
4087+
4088+const core::Signal<location::Update<location::Heading>>& location::providers::gps::Provider::heading_updates() const
4089+{
4090+ return updates.heading;
4091+}
4092+
4093+const core::Signal<location::Update<location::Velocity>>& location::providers::gps::Provider::velocity_updates() const
4094+{
4095+ return updates.velocity;
4096+}
4097+
4098+const core::Signal<location::Update<std::set<location::SpaceVehicle>>>& location::providers::gps::Provider::svs_updates() const
4099+{
4100+ return updates.svs;
4101 }
4102
4103 void location::providers::gps::Provider::on_reference_location_updated(const location::Update<location::Position>& position)
4104 {
4105 hal->inject_reference_position(position.value);
4106 }
4107-
4108
4109=== modified file 'src/location/providers/gps/provider.h'
4110--- src/location/providers/gps/provider.h 2016-06-26 21:17:03 +0000
4111+++ src/location/providers/gps/provider.h 2016-08-12 12:03:50 +0000
4112@@ -43,21 +43,31 @@
4113 Provider& operator=(const Provider&) = delete;
4114 ~Provider() noexcept;
4115
4116- bool matches_criteria(const Criteria&);
4117-
4118- void start_position_updates();
4119- void stop_position_updates();
4120-
4121- void start_velocity_updates();
4122- void stop_velocity_updates();
4123-
4124- void start_heading_updates();
4125- void stop_heading_updates();
4126-
4127+ void on_new_event(const Event& event) override;
4128+
4129+ void enable() override;
4130+ void disable() override;
4131+ void activate() override;
4132+ void deactivate() override;
4133+
4134+ Requirements requirements() const override;
4135+ bool satisfies(const Criteria& criteria) override;
4136+ const core::Signal<Update<Position>>& position_updates() const override;
4137+ const core::Signal<Update<Heading>>& heading_updates() const override;
4138+ const core::Signal<Update<Velocity>>& velocity_updates() const override;
4139+
4140+ const core::Signal<Update<std::set<SpaceVehicle>>>& svs_updates() const;
4141 void on_reference_location_updated(const Update<Position>& position);
4142
4143 private:
4144 std::shared_ptr<HardwareAbstractionLayer> hal;
4145+ struct
4146+ {
4147+ core::Signal<Update<Position>> position;
4148+ core::Signal<Update<Heading>> heading;
4149+ core::Signal<Update<Velocity>> velocity;
4150+ core::Signal<Update<std::set<SpaceVehicle>>> svs;
4151+ } updates;
4152 };
4153 }
4154 }
4155
4156=== added file 'src/location/providers/proxy.cpp'
4157--- src/location/providers/proxy.cpp 1970-01-01 00:00:00 +0000
4158+++ src/location/providers/proxy.cpp 2016-08-12 12:03:50 +0000
4159@@ -0,0 +1,95 @@
4160+/*
4161+ * Copyright © 2016 Canonical Ltd.
4162+ *
4163+ * This program is free software: you can redistribute it and/or modify it
4164+ * under the terms of the GNU Lesser General Public License version 3,
4165+ * as published by the Free Software Foundation.
4166+ *
4167+ * This program is distributed in the hope that it will be useful,
4168+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4169+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4170+ * GNU Lesser General Public License for more details.
4171+ *
4172+ * You should have received a copy of the GNU Lesser General Public License
4173+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4174+ *
4175+ * Authored by: Scott Sweeny <scott.sweeny@canonical.com
4176+ */
4177+
4178+#include <location/providers/proxy.h>
4179+
4180+location::providers::Proxy::Proxy(const std::set<Provider::Ptr>& providers)
4181+ : providers{providers}
4182+{
4183+ for (auto provider : providers)
4184+ {
4185+ connections.emplace_back(provider->position_updates().connect([this](const location::Update<location::Position>& u)
4186+ {
4187+ updates.position(u);
4188+ }));
4189+
4190+ connections.emplace_back(provider->heading_updates().connect([this](const location::Update<location::Heading>& u)
4191+ {
4192+ updates.heading(u);
4193+ }));
4194+
4195+ connections.emplace_back(provider->velocity_updates().connect([this](const location::Update<location::Velocity>& u)
4196+ {
4197+ updates.velocity(u);
4198+ }));
4199+ }
4200+}
4201+
4202+void location::providers::Proxy::on_new_event(const Event& event)
4203+{
4204+ for (auto provider: providers) provider->on_new_event(event);
4205+}
4206+
4207+void location::providers::Proxy::enable()
4208+{
4209+ for (auto provider : providers) provider->enable();
4210+}
4211+
4212+void location::providers::Proxy::disable()
4213+{
4214+ for (auto provider : providers) provider->disable();
4215+}
4216+
4217+void location::providers::Proxy::activate()
4218+{
4219+ for (auto provider : providers) provider->activate();
4220+}
4221+
4222+void location::providers::Proxy::deactivate()
4223+{
4224+ for (auto provider : providers) provider->deactivate();
4225+}
4226+
4227+location::Provider::Requirements location::providers::Proxy::requirements() const
4228+{
4229+ location::Provider::Requirements reqs{location::Provider::Requirements::none};
4230+ for (auto provider : providers) reqs = reqs | provider->requirements();
4231+ return reqs;
4232+}
4233+
4234+bool location::providers::Proxy::satisfies(const Criteria& criteria)
4235+{
4236+ bool result{true};
4237+ for (auto provider : providers) result &= provider->satisfies(criteria);
4238+ return result;
4239+}
4240+
4241+const core::Signal<location::Update<location::Position>>& location::providers::Proxy::position_updates() const
4242+{
4243+ return updates.position;
4244+}
4245+
4246+const core::Signal<location::Update<location::Heading>>& location::providers::Proxy::heading_updates() const
4247+{
4248+ return updates.heading;
4249+}
4250+
4251+const core::Signal<location::Update<location::Velocity>>& location::providers::Proxy::velocity_updates() const
4252+{
4253+ return updates.velocity;
4254+}
4255
4256=== added file 'src/location/providers/proxy.h'
4257--- src/location/providers/proxy.h 1970-01-01 00:00:00 +0000
4258+++ src/location/providers/proxy.h 2016-08-12 12:03:50 +0000
4259@@ -0,0 +1,59 @@
4260+/*
4261+ * Copyright © 2016 Canonical Ltd.
4262+ *
4263+ * This program is free software: you can redistribute it and/or modify it
4264+ * under the terms of the GNU Lesser General Public License version 3,
4265+ * as published by the Free Software Foundation.
4266+ *
4267+ * This program is distributed in the hope that it will be useful,
4268+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4269+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4270+ * GNU Lesser General Public License for more details.
4271+ *
4272+ * You should have received a copy of the GNU Lesser General Public License
4273+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4274+ *
4275+ * Authored by: Scott Sweeny <scott.sweeny@canonical.com
4276+ */
4277+#ifndef LOCATION_PROVIDERS_PROXY_H
4278+#define LOCATION_PROVIDERS_PROXY_H
4279+
4280+#include <location/provider.h>
4281+
4282+#include <set>
4283+
4284+namespace location
4285+{
4286+namespace providers
4287+{
4288+class Proxy : public Provider
4289+{
4290+public:
4291+ explicit Proxy(const std::set<Provider::Ptr>& providers);
4292+
4293+ // From Provider
4294+ void on_new_event(const Event&) override;
4295+ void enable() override;
4296+ void disable() override;
4297+ void activate() override;
4298+ void deactivate() override;
4299+
4300+ Requirements requirements() const override;
4301+ bool satisfies(const Criteria& criteria) override;
4302+ const core::Signal<Update<Position>>& position_updates() const override;
4303+ const core::Signal<Update<Heading>>& heading_updates() const override;
4304+ const core::Signal<Update<Velocity>>& velocity_updates() const override;
4305+
4306+private:
4307+ std::set<Provider::Ptr> providers;
4308+ std::vector<core::ScopedConnection> connections;
4309+ struct
4310+ {
4311+ core::Signal<Update<Position>> position;
4312+ core::Signal<Update<Heading>> heading;
4313+ core::Signal<Update<Velocity>> velocity;
4314+ } updates;
4315+};
4316+}
4317+}
4318+#endif // LOCATION_PROVIDERS_PROXY_H
4319
4320=== modified file 'src/location/providers/remote/interface.h'
4321--- src/location/providers/remote/interface.h 2016-06-28 11:53:34 +0000
4322+++ src/location/providers/remote/interface.h 2016-08-12 12:03:50 +0000
4323@@ -47,111 +47,39 @@
4324 return s;
4325 }
4326
4327- // Checks if a provider satisfies a set of accuracy criteria.
4328- DBUS_CPP_METHOD_DEF(MatchesCriteria, remote::Interface)
4329- // Checks if the provider has got a specific requirement.
4330- DBUS_CPP_METHOD_DEF(Requires, remote::Interface)
4331- // Checks if the provider supports a specific feature.
4332- DBUS_CPP_METHOD_DEF(Supports, remote::Interface)
4333- // Called by the engine whenever the wifi and cell ID reporting state changes.
4334- DBUS_CPP_METHOD_DEF(OnWifiAndCellIdReportingStateChanged, remote::Interface)
4335- // Called by the engine whenever the reference location changed.
4336- DBUS_CPP_METHOD_DEF(OnReferenceLocationChanged, remote::Interface)
4337- // Called by the engine whenever the reference heading changed.
4338- DBUS_CPP_METHOD_DEF(OnReferenceHeadingChanged, remote::Interface)
4339- // Called by the engine whenever the reference velocity changed.
4340- DBUS_CPP_METHOD_DEF(OnReferenceVelocityChanged, remote::Interface)
4341-
4342- DBUS_CPP_METHOD_DEF(StartPositionUpdates, remote::Interface)
4343- DBUS_CPP_METHOD_DEF(StopPositionUpdates, remote::Interface)
4344- DBUS_CPP_METHOD_DEF(StartHeadingUpdates, remote::Interface)
4345- DBUS_CPP_METHOD_DEF(StopHeadingUpdates, remote::Interface)
4346- DBUS_CPP_METHOD_DEF(StartVelocityUpdates, remote::Interface)
4347- DBUS_CPP_METHOD_DEF(StopVelocityUpdates, remote::Interface)
4348-
4349- struct Signals
4350- {
4351- DBUS_CPP_SIGNAL_DEF(PositionChanged, remote::Interface, location::Position)
4352- DBUS_CPP_SIGNAL_DEF(HeadingChanged, remote::Interface, location::Heading)
4353- DBUS_CPP_SIGNAL_DEF(VelocityChanged, remote::Interface, location::Velocity)
4354- };
4355-
4356- struct Properties
4357- {
4358- DBUS_CPP_READABLE_PROPERTY_DEF(HasPosition, remote::Interface, bool)
4359- DBUS_CPP_READABLE_PROPERTY_DEF(HasVelocity, remote::Interface, bool)
4360- DBUS_CPP_READABLE_PROPERTY_DEF(HasHeading, remote::Interface, bool)
4361- DBUS_CPP_READABLE_PROPERTY_DEF(RequiresSatellites, remote::Interface, bool)
4362- DBUS_CPP_READABLE_PROPERTY_DEF(RequiresCellNetwork, remote::Interface, bool)
4363- DBUS_CPP_READABLE_PROPERTY_DEF(RequiresDataNetwork, remote::Interface, bool)
4364- DBUS_CPP_READABLE_PROPERTY_DEF(RequiresMonetarySpending, remote::Interface, bool)
4365- DBUS_CPP_READABLE_PROPERTY_DEF(ArePositionUpdatesRunning, remote::Interface, bool)
4366- DBUS_CPP_READABLE_PROPERTY_DEF(AreHeadingUpdatesRunning, remote::Interface, bool)
4367- DBUS_CPP_READABLE_PROPERTY_DEF(AreVelocityUpdatesRunning, remote::Interface, bool)
4368- };
4369+ struct Observer
4370+ {
4371+ static const std::string& name()
4372+ {
4373+ static const std::string s{"com.ubuntu.remote.Service.Provider.Observer"};
4374+ return s;
4375+ }
4376+
4377+ DBUS_CPP_METHOD_DEF(UpdatePosition, remote::Interface::Observer)
4378+ DBUS_CPP_METHOD_DEF(UpdateHeading, remote::Interface::Observer)
4379+ DBUS_CPP_METHOD_DEF(UpdateVelocity, remote::Interface::Observer)
4380+ };
4381+
4382+ DBUS_CPP_METHOD_DEF(OnNewEvent, remote::Interface)
4383+ DBUS_CPP_METHOD_DEF(AddObserver, remote::Interface)
4384+ DBUS_CPP_METHOD_DEF(Satisfies, remote::Interface)
4385+ DBUS_CPP_METHOD_DEF(Requirements, remote::Interface)
4386+ DBUS_CPP_METHOD_DEF(Enable, remote::Interface)
4387+ DBUS_CPP_METHOD_DEF(Disable, remote::Interface)
4388+ DBUS_CPP_METHOD_DEF(Activate, remote::Interface)
4389+ DBUS_CPP_METHOD_DEF(Deactivate, remote::Interface)
4390
4391 struct Skeleton
4392 {
4393 // Creates a new skeleton instance and installs the interface
4394 // remote::Interface on it.
4395 Skeleton(const core::dbus::Object::Ptr& object)
4396- : object{object},
4397- properties
4398- {
4399- object->get_property<Properties::HasPosition>(),
4400- object->get_property<Properties::HasVelocity>(),
4401- object->get_property<Properties::HasHeading>(),
4402- object->get_property<Properties::RequiresSatellites>(),
4403- object->get_property<Properties::RequiresCellNetwork>(),
4404- object->get_property<Properties::RequiresDataNetwork>(),
4405- object->get_property<Properties::RequiresMonetarySpending>(),
4406- object->get_property<Properties::ArePositionUpdatesRunning>(),
4407- object->get_property<Properties::AreHeadingUpdatesRunning>(),
4408- object->get_property<Properties::AreVelocityUpdatesRunning>()
4409- },
4410- signals
4411- {
4412- object->get_signal<Signals::PositionChanged>(),
4413- object->get_signal<Signals::HeadingChanged>(),
4414- object->get_signal<Signals::VelocityChanged>()
4415- }
4416+ : object{object}
4417 {
4418 }
4419
4420 // The object that the interface is installed on.
4421 core::dbus::Object::Ptr object;
4422- // All known properties.
4423- struct
4424- {
4425- std::shared_ptr<core::dbus::Property<Properties::HasPosition>> has_position;
4426- std::shared_ptr<core::dbus::Property<Properties::HasVelocity>> has_velocity;
4427- std::shared_ptr<core::dbus::Property<Properties::HasHeading>> has_heading;
4428- std::shared_ptr<core::dbus::Property<Properties::RequiresSatellites>> requires_satellites;
4429- std::shared_ptr<core::dbus::Property<Properties::RequiresCellNetwork>> requires_cell_network;
4430- std::shared_ptr<core::dbus::Property<Properties::RequiresDataNetwork>> requires_data_network;
4431- std::shared_ptr<core::dbus::Property<Properties::RequiresMonetarySpending>> requires_monetary_spending;
4432- std::shared_ptr<core::dbus::Property<Properties::ArePositionUpdatesRunning>> are_position_updates_running;
4433- std::shared_ptr<core::dbus::Property<Properties::AreHeadingUpdatesRunning>> are_heading_updates_running;
4434- std::shared_ptr<core::dbus::Property<Properties::AreVelocityUpdatesRunning>> are_velocity_updates_running;
4435- } properties;
4436- // All known signals.
4437- struct
4438- {
4439- std::shared_ptr<core::dbus::Signal<
4440- Signals::PositionChanged,
4441- Signals::PositionChanged::ArgumentType
4442- >> position_changed;
4443-
4444- std::shared_ptr<core::dbus::Signal<
4445- Signals::HeadingChanged,
4446- Signals::HeadingChanged::ArgumentType
4447- >> heading_changed;
4448-
4449- std::shared_ptr<core::dbus::Signal<
4450- Signals::VelocityChanged,
4451- Signals::VelocityChanged::ArgumentType
4452- >> velocity_changed;
4453- } signals;
4454 };
4455
4456 struct Stub
4457@@ -159,63 +87,12 @@
4458 // Creates a new skeleton instance and installs the interface
4459 // remote::Interface on it.
4460 Stub(const core::dbus::Object::Ptr& object)
4461- : object{object},
4462- properties
4463- {
4464- object->get_property<Properties::HasPosition>(),
4465- object->get_property<Properties::HasVelocity>(),
4466- object->get_property<Properties::HasHeading>(),
4467- object->get_property<Properties::RequiresSatellites>(),
4468- object->get_property<Properties::RequiresCellNetwork>(),
4469- object->get_property<Properties::RequiresDataNetwork>(),
4470- object->get_property<Properties::RequiresMonetarySpending>(),
4471- object->get_property<Properties::ArePositionUpdatesRunning>(),
4472- object->get_property<Properties::AreHeadingUpdatesRunning>(),
4473- object->get_property<Properties::AreVelocityUpdatesRunning>()
4474- },
4475- signals
4476- {
4477- object->get_signal<Signals::PositionChanged>(),
4478- object->get_signal<Signals::HeadingChanged>(),
4479- object->get_signal<Signals::VelocityChanged>()
4480- }
4481+ : object{object}
4482 {
4483 }
4484
4485 // The object that the interface is installed on.
4486- core::dbus::Object::Ptr object;
4487- // All known properties.
4488- struct
4489- {
4490- std::shared_ptr<core::dbus::Property<Properties::HasPosition>> has_position;
4491- std::shared_ptr<core::dbus::Property<Properties::HasVelocity>> has_velocity;
4492- std::shared_ptr<core::dbus::Property<Properties::HasHeading>> has_heading;
4493- std::shared_ptr<core::dbus::Property<Properties::RequiresSatellites>> requires_satellites;
4494- std::shared_ptr<core::dbus::Property<Properties::RequiresCellNetwork>> requires_cell_network;
4495- std::shared_ptr<core::dbus::Property<Properties::RequiresDataNetwork>> requires_data_network;
4496- std::shared_ptr<core::dbus::Property<Properties::RequiresMonetarySpending>> requires_monetary_spending;
4497- std::shared_ptr<core::dbus::Property<Properties::ArePositionUpdatesRunning>> are_position_updates_running;
4498- std::shared_ptr<core::dbus::Property<Properties::AreHeadingUpdatesRunning>> are_heading_updates_running;
4499- std::shared_ptr<core::dbus::Property<Properties::AreVelocityUpdatesRunning>> are_velocity_updates_running;
4500- } properties;
4501- // All known signals.
4502- struct
4503- {
4504- std::shared_ptr<core::dbus::Signal<
4505- Signals::PositionChanged,
4506- Signals::PositionChanged::ArgumentType
4507- >> position_changed;
4508-
4509- std::shared_ptr<core::dbus::Signal<
4510- Signals::HeadingChanged,
4511- Signals::HeadingChanged::ArgumentType
4512- >> heading_changed;
4513-
4514- std::shared_ptr<core::dbus::Signal<
4515- Signals::VelocityChanged,
4516- Signals::VelocityChanged::ArgumentType
4517- >> velocity_changed;
4518- } signals;
4519+ core::dbus::Object::Ptr object;
4520 };
4521
4522 };
4523
4524=== modified file 'src/location/providers/remote/provider.cpp'
4525--- src/location/providers/remote/provider.cpp 2016-06-26 21:17:03 +0000
4526+++ src/location/providers/remote/provider.cpp 2016-08-12 12:03:50 +0000
4527@@ -17,9 +17,12 @@
4528 */
4529
4530 #include <location/providers/remote/provider.h>
4531-
4532 #include <location/providers/remote/interface.h>
4533
4534+#include <location/dbus/codec.h>
4535+#include <location/events/registry.h>
4536+#include <location/events/reference_position_updated.h>
4537+#include <location/events/wifi_and_cell_id_reporting_state_changed.h>
4538 #include <location/logging.h>
4539
4540 #include <core/dbus/object.h>
4541@@ -40,113 +43,6 @@
4542
4543 namespace
4544 {
4545-struct Runtime
4546-{
4547- static Runtime& instance()
4548- {
4549- static Runtime runtime;
4550- return runtime;
4551- }
4552-
4553- Runtime()
4554- : running{true},
4555- worker1{std::bind(&Runtime::run, this, std::ref(io.service))},
4556- worker2{std::bind(&Runtime::run, this, std::ref(task.service))}
4557- {
4558- }
4559-
4560- ~Runtime()
4561- {
4562- stop();
4563- }
4564-
4565- void run(boost::asio::io_service& service)
4566- {
4567- while (running)
4568- {
4569- try
4570- {
4571- service.run();
4572- break; // provider has exited correctly
4573- }
4574- catch (const std::exception& e)
4575- {
4576- LOG(WARNING) << e.what();
4577- }
4578- catch (...)
4579- {
4580- LOG(WARNING) << "Caught exception from event loop, restarting.";
4581- }
4582- }
4583- }
4584-
4585- void stop()
4586- {
4587- running = false;
4588-
4589- task.service.stop();
4590-
4591- if (worker2.joinable())
4592- worker2.join();
4593-
4594- io.service.stop();
4595-
4596- if (worker1.joinable())
4597- worker1.join();
4598- }
4599-
4600- bool running;
4601- struct
4602- {
4603- boost::asio::io_service service;
4604- boost::asio::io_service::work keep_alive
4605- {
4606- service
4607- };
4608- } io;
4609- struct
4610- {
4611- boost::asio::io_service service;
4612- boost::asio::io_service::work keep_alive
4613- {
4614- service
4615- };
4616- } task;
4617- std::thread worker1;
4618- std::thread worker2;
4619-};
4620-
4621-core::dbus::Bus::Ptr bus_from_name(const std::string& bus_name)
4622-{
4623- core::dbus::Bus::Ptr bus;
4624-
4625- if (bus_name == "system")
4626- bus = std::make_shared<core::dbus::Bus>(core::dbus::WellKnownBus::system);
4627- else if (bus_name == "session")
4628- bus = std::make_shared<core::dbus::Bus>(core::dbus::WellKnownBus::session);
4629- else if (bus_name == "system_with_address_from_env")
4630- bus = std::make_shared<core::dbus::Bus>(core::posix::this_process::env::get_or_throw("DBUS_SYSTEM_BUS_ADDRESS"));
4631- else if (bus_name == "session_with_address_from_env")
4632- bus = std::make_shared<core::dbus::Bus>(core::posix::this_process::env::get_or_throw("DBUS_SESSION_BUS_ADDRESS"));
4633-
4634- if (not bus) throw std::runtime_error
4635- {
4636- "Could not create bus for name: " + bus_name
4637- };
4638-
4639- bus->install_executor(core::dbus::asio::make_executor(bus, Runtime::instance().io.service));
4640-
4641- return bus;
4642-}
4643-
4644-void throw_if_error(const dbus::Result<void>& result)
4645-{
4646- if (result.is_error()) throw std::runtime_error
4647- {
4648- result.error().print()
4649- };
4650-}
4651-
4652 template<typename T>
4653 T throw_if_error_or_return(const dbus::Result<T>& result)
4654 {
4655@@ -156,13 +52,127 @@
4656 };
4657 return result.value();
4658 }
4659+
4660+core::dbus::types::ObjectPath generate_path_for_observer()
4661+{
4662+ static constexpr const char* pattern{"/com/ubuntu/location/provider/observer/%1%"};
4663+ static std::size_t counter{0};
4664+
4665+ return core::dbus::types::ObjectPath{(boost::format{pattern} % ++counter).str()};
4666+}
4667+}
4668+
4669+remote::Provider::Observer::Stub::Stub(const core::dbus::Object::Ptr& object)
4670+ : object{object}
4671+{
4672+
4673+}
4674+
4675+void remote::Provider::Observer::Stub::on_new_position(const Update<Position>& update)
4676+{
4677+ try
4678+ {
4679+ object->invoke_method_asynchronously_with_callback<remote::Interface::Observer::UpdatePosition, void>([](const core::dbus::Result<void>&)
4680+ {
4681+
4682+ }, update);
4683+ }
4684+ catch(const std::exception& e)
4685+ {
4686+ LOG(WARNING) << e.what();
4687+ }
4688+ catch(...)
4689+ {
4690+ }
4691+}
4692+
4693+void remote::Provider::Observer::Stub::on_new_heading(const Update<Heading>& update)
4694+{
4695+ try
4696+ {
4697+ object->invoke_method_asynchronously_with_callback<remote::Interface::Observer::UpdateHeading, void>([](const core::dbus::Result<void>&)
4698+ {
4699+
4700+ }, update);
4701+ }
4702+ catch(const std::exception& e)
4703+ {
4704+ LOG(WARNING) << e.what();
4705+ }
4706+ catch(...)
4707+ {
4708+ }
4709+}
4710+
4711+void remote::Provider::Observer::Stub::on_new_velocity(const Update<Velocity>& update)
4712+{
4713+ try
4714+ {
4715+ object->invoke_method_asynchronously_with_callback<remote::Interface::Observer::UpdateVelocity, void>([](const core::dbus::Result<void>&)
4716+ {
4717+
4718+ }, update);
4719+ }
4720+ catch(const std::exception& e)
4721+ {
4722+ LOG(WARNING) << e.what();
4723+ }
4724+ catch(...)
4725+ {
4726+ }
4727+}
4728+
4729+remote::Provider::Observer::Skeleton::Skeleton(const core::dbus::Bus::Ptr& bus, const core::dbus::Object::Ptr& object, const std::shared_ptr<Observer>& impl)
4730+ : bus{bus}, object{object}, impl{impl}
4731+{
4732+ object->install_method_handler<remote::Interface::Observer::UpdatePosition>([this](const core::dbus::Message::Ptr& msg)
4733+ {
4734+ VLOG(50) << "remote::Interface::Observer::UpdatePosition";
4735+ location::Update<location::Position> update; msg->reader() >> update;
4736+ on_new_position(update);
4737+ Skeleton::bus->send(dbus::Message::make_method_return(msg));
4738+ });
4739+
4740+ object->install_method_handler<remote::Interface::Observer::UpdateHeading>([this](const core::dbus::Message::Ptr& msg)
4741+ {
4742+ VLOG(50) << "remote::Interface::Observer::UpdateHeading";
4743+ location::Update<location::Heading> update; msg->reader() >> update;
4744+ on_new_heading(update);
4745+ Skeleton::bus->send(dbus::Message::make_method_return(msg));
4746+ });
4747+
4748+ object->install_method_handler<remote::Interface::Observer::UpdateVelocity>([this](const core::dbus::Message::Ptr& msg)
4749+ {
4750+ VLOG(50) << "remote::Interface::Observer::UpdateVelocity";
4751+ location::Update<location::Velocity> update; msg->reader() >> update;
4752+ on_new_velocity(update);
4753+ Skeleton::bus->send(dbus::Message::make_method_return(msg));
4754+ });
4755+}
4756+
4757+void remote::Provider::Observer::Skeleton::on_new_position(const Update<Position>& update)
4758+{
4759+ impl->on_new_position(update);
4760+}
4761+
4762+void remote::Provider::Observer::Skeleton::on_new_heading(const Update<Heading>& update)
4763+{
4764+ impl->on_new_heading(update);
4765+}
4766+
4767+void remote::Provider::Observer::Skeleton::on_new_velocity(const Update<Velocity>& update)
4768+{
4769+ impl->on_new_velocity(update);
4770 }
4771
4772 struct remote::Provider::Stub::Private
4773 {
4774- Private(const remote::stub::Configuration& config)
4775- : object(config.object),
4776- stub(object)
4777+ Private(const remote::stub::Configuration& config, location::Provider::Requirements requirements)
4778+ : bus{config.bus},
4779+ service{config.service},
4780+ object{config.object},
4781+ requirements{requirements},
4782+ stub{object}
4783 {
4784 }
4785
4786@@ -170,125 +180,47 @@
4787 {
4788 }
4789
4790+ dbus::Bus::Ptr bus;
4791+ dbus::Service::Ptr service;
4792 dbus::Object::Ptr object;
4793+ location::Provider::Requirements requirements;
4794 remote::Interface::Stub stub;
4795+ std::set<std::shared_ptr<remote::Provider::Observer>> observers;
4796+ struct
4797+ {
4798+ core::Signal<location::Update<location::Position>> position;
4799+ core::Signal<location::Update<location::Heading>> heading;
4800+ core::Signal<location::Update<location::Velocity>> velocity;
4801+ } updates;
4802 };
4803
4804-std::string remote::Provider::Stub::class_name()
4805-{
4806- return "remote::Provider";
4807-}
4808-
4809-cul::Provider::Ptr remote::Provider::Stub::create_instance(const cul::ProviderFactory::Configuration& config)
4810-{
4811- auto bus_name = config.count(Stub::key_bus) > 0 ? config.get<std::string>(Stub::key_bus) :
4812- "system";
4813- auto name = config.count(Stub::key_name) > 0 ? config.get<std::string>(Stub::key_name) :
4814- throw std::runtime_error("Missing bus-name");
4815- auto path = config.count(Stub::key_path) > 0 ? config.get<std::string>(Stub::key_path) :
4816- throw std::runtime_error("Missing bus-path");
4817-
4818- auto bus = bus_from_name(bus_name);
4819- auto service = dbus::Service::use_service(bus, name);
4820- auto object = service->object_for_path(path);
4821-
4822- // Check if the service has come up
4823- if (!bus->has_owner_for_name(name)) {
4824- // If it hasn't wait for it to come up
4825- bool valid = false;
4826- std::mutex guard;
4827- std::condition_variable cv;
4828- dbus::DBus daemon(bus);
4829- dbus::ServiceWatcher::Ptr service_watcher(
4830- daemon.make_service_watcher(name, dbus::DBus::WatchMode::registration));
4831-
4832- service_watcher->service_registered().connect([&valid, &guard, &cv]()
4833- {
4834- std::unique_lock<std::mutex> ul(guard);
4835- valid = true;
4836- cv.notify_all();
4837- });
4838-
4839- std::unique_lock<std::mutex> ul(guard);
4840- if (not cv.wait_for(ul, std::chrono::seconds{30}, [&valid]() { return valid; }))
4841- throw std::runtime_error("Remote service failed to start");
4842- }
4843-
4844- return create_instance_with_config(remote::stub::Configuration{object});
4845-}
4846-
4847-cul::Provider::Ptr remote::Provider::Stub::create_instance_with_config(const remote::stub::Configuration& config)
4848-{
4849- std::shared_ptr<remote::Provider::Stub> result{new remote::Provider::Stub{config}};
4850-
4851- // This call throws if we fail to reach the remote end. With that, we make sure that
4852- // we do not return a potentially invalid instance that throws later on.
4853- result->ping();
4854-
4855- result->setup_event_connections();
4856- return result;
4857-}
4858-
4859-remote::Provider::Stub::Stub(const remote::stub::Configuration& config)
4860- : location::Provider(/* TODO(tvoss) Features should be all initially*/),
4861- d(new Private(config))
4862-{
4863-}
4864-
4865-void remote::Provider::Stub::setup_event_connections()
4866-{
4867- std::weak_ptr<remote::Provider::Stub> wp{shared_from_this()};
4868-
4869- d->stub.signals.position_changed->connect(
4870- [wp](const remote::Interface::Signals::PositionChanged::ArgumentType& arg)
4871- {
4872- VLOG(50) << "remote::Provider::Stub::PositionChanged: " << arg;
4873- Runtime::instance().task.service.post([wp, arg]()
4874- {
4875- auto sp = wp.lock();
4876-
4877- if (not sp)
4878- return;
4879-
4880- sp->mutable_updates().position(arg);
4881- });
4882- });
4883-
4884- d->stub.signals.heading_changed->connect(
4885- [wp](const remote::Interface::Signals::HeadingChanged::ArgumentType& arg)
4886- {
4887- VLOG(50) << "remote::Provider::Stub::HeadingChanged: " << arg;
4888- Runtime::instance().task.service.post([wp, arg]()
4889- {
4890- auto sp = wp.lock();
4891-
4892- if (not sp)
4893- return;
4894-
4895- sp->mutable_updates().heading(arg);
4896- });
4897- });
4898-
4899- d->stub.signals.velocity_changed->connect(
4900- [wp](const remote::Interface::Signals::VelocityChanged::ArgumentType& arg)
4901- {
4902- VLOG(50) << "remote::Provider::Stub::VelocityChanged: " << arg;
4903- Runtime::instance().task.service.post([wp, arg]()
4904- {
4905- auto sp = wp.lock();
4906-
4907- if (not sp)
4908- return;
4909-
4910- sp->mutable_updates().velocity(arg);
4911- });
4912- });
4913-}
4914-
4915-void remote::Provider::Stub::ping()
4916-{
4917- // Requires reaches out to the remote side and throws in case of issues.
4918- requires(Provider::Requirements::satellites);
4919+void remote::Provider::Stub::create_instance_with_config(const remote::stub::Configuration& config, const std::function<void(const Provider::Ptr&)>& cb)
4920+{
4921+ config.object->invoke_method_asynchronously_with_callback<remote::Interface::Requirements, Provider::Requirements>([config, cb](const core::dbus::Result<Provider::Requirements>& result)
4922+ {
4923+ VLOG(50) << "Finished querying results from remote provider: " << std::boolalpha << result.is_error();
4924+ if (not result.is_error())
4925+ {
4926+ std::shared_ptr<remote::Provider::Stub> provider{new remote::Provider::Stub{config, result.value()}};
4927+ cb(provider->finalize());
4928+ }
4929+ else
4930+ {
4931+ LOG(WARNING) << result.error().print();
4932+ }
4933+ });
4934+}
4935+
4936+remote::Provider::Stub::Stub(const remote::stub::Configuration& config, Provider::Requirements requirements)
4937+ : d(new Private(config, requirements))
4938+{
4939+}
4940+
4941+std::shared_ptr<remote::Provider::Stub> remote::Provider::Stub::finalize()
4942+{
4943+ auto thiz = shared_from_this();
4944+ add_observer(thiz);
4945+ return thiz;
4946 }
4947
4948 remote::Provider::Stub::~Stub() noexcept
4949@@ -296,188 +228,114 @@
4950 VLOG(10) << __PRETTY_FUNCTION__;
4951 }
4952
4953-bool remote::Provider::Stub::matches_criteria(const cul::Criteria& criteria)
4954-{
4955- VLOG(10) << __PRETTY_FUNCTION__ << std::endl;
4956- return throw_if_error_or_return(d->stub.object->transact_method<remote::Interface::MatchesCriteria, bool>(criteria));
4957-}
4958-
4959-bool remote::Provider::Stub::supports(const cul::Provider::Features& f) const
4960-{
4961- VLOG(10) << __PRETTY_FUNCTION__;
4962- return throw_if_error_or_return(d->stub.object->transact_method<remote::Interface::Supports, bool>(f));
4963-}
4964-
4965-bool remote::Provider::Stub::requires(const cul::Provider::Requirements& r) const
4966-{
4967- VLOG(10) << __PRETTY_FUNCTION__;
4968- return throw_if_error_or_return(d->stub.object->transact_method<remote::Interface::Requires, bool>(r));
4969-}
4970-
4971-void remote::Provider::Stub::on_wifi_and_cell_reporting_state_changed(cul::WifiAndCellIdReportingState state)
4972-{
4973- VLOG(10) << __PRETTY_FUNCTION__;
4974- throw_if_error(d->stub.object->transact_method<remote::Interface::OnWifiAndCellIdReportingStateChanged, void>(state));
4975-}
4976-
4977-void remote::Provider::Stub::on_reference_location_updated(const cul::Update<cul::Position>& position)
4978-{
4979- std::weak_ptr<Private> wp{d};
4980- Runtime::instance().task.service.post([wp, position]()
4981- {
4982- auto sp = wp.lock();
4983-
4984- if (not sp)
4985- return;
4986-
4987- try
4988- {
4989- throw_if_error(sp->stub.object->transact_method<remote::Interface::OnReferenceLocationChanged, void>(position));
4990- } catch(const std::exception& e)
4991- {
4992- // We drop the error and just log it for post-mortem inspection.
4993- LOG(WARNING) << "Transaction<remote::Interface::OnReferenceLocationChanged>: " << e.what();
4994- }
4995- });
4996-}
4997-
4998-void remote::Provider::Stub::on_reference_velocity_updated(const cul::Update<cul::Velocity>& velocity)
4999-{
5000- std::weak_ptr<Private> wp{d};
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches

to all changes: