Merge lp:~ssweeny/location-service/delayed-providers.15.04 into lp:location-service/15.04

Proposed by Scott Sweeny
Status: Approved
Approved by: Thomas Voß
Approved revision: 201
Proposed branch: lp:~ssweeny/location-service/delayed-providers.15.04
Merge into: lp:location-service/15.04
Diff against target: 567 lines (+411/-9)
4 files modified
include/location_service/com/ubuntu/location/provider.h (+43/-1)
src/location_service/com/ubuntu/location/provider.cpp (+66/-8)
tests/controller_test.cpp (+213/-0)
tests/mock_delayed_provider.h (+89/-0)
To merge this branch: bzr merge lp:~ssweeny/location-service/delayed-providers.15.04
Reviewer Review Type Date Requested Status
Thomas Voß (community) Approve
Review via email: mp+275384@code.launchpad.net

Commit message

Add the concept of a delayed providers. This will allow providers that are slow to start the chance to be started and later be connected accordingly.

Description of the change

Add the concept of a delayed providers. This will allow providers that are slow to start the chance to be started and later be connected accordingly.

To post a comment you must log in.
Revision history for this message
Thomas Voß (thomas-voss) wrote :

Please note that this change requires a rebuild of lp:espoo as the location::Provider interface is altered.

review: Needs Information
Revision history for this message
Thomas Voß (thomas-voss) wrote :

A few niggles inline.

review: Needs Fixing
199. By Scott Sweeny

Address review comments

200. By Scott Sweeny

Add logging output (move here from espoo-delayed-providers MP)

201. By Scott Sweeny

Add a log message that I missed

Revision history for this message
Thomas Voß (thomas-voss) wrote :

LGTM.

review: Approve
Revision history for this message
Alberto Mardegan (mardy) wrote :

I'm coming from a programming style that keeps virtual methods to a minimum, and I do understand if that might not be of your liking, so feel free to discard this comment. :-)

Wouldn't it be possible to implement the same without breaking the ABI?

At least, I see no reason why these methods need to be virtual:

    virtual core::Signal<bool>& boot_state_changed();
    virtual const core::Signal<bool>& boot_state_changed() const;

given that you are providing a default implementation that I don't see any reason to override. As for the getter:

    virtual BootState boot_state() const;

this could be made non virtual by adding a protected method like

    void set_boot_state(BootState state);

that subclasses can call to set the boot state. This method would also take care of emitting the boot_state_changed() signal.

The only method for which a virtual declaration makes a lot of sense is request_boot(), but OTOH I wonder if we could remove it altogether: we could just specify that boot should start when the provider's constructor is invoked, or (if we really need a two-phase initialization) when the

    virtual const Controller::Ptr& state_controller() const;

method is first invoked (it's a virtual method, so the subclass can use it to start the initialization). I can see that purists might not like to have this method be overloaded with the booting role too, but it's something that can make sense, if clearly explained in a doc comment.

It all depends on whether preserving ABI is a goal or not.

Unmerged revisions

201. By Scott Sweeny

Add a log message that I missed

200. By Scott Sweeny

Add logging output (move here from espoo-delayed-providers MP)

199. By Scott Sweeny

Address review comments

198. By Manuel de la Peña

Added support for delayed providers.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'include/location_service/com/ubuntu/location/provider.h'
--- include/location_service/com/ubuntu/location/provider.h 2015-01-21 20:13:28 +0000
+++ include/location_service/com/ubuntu/location/provider.h 2015-10-27 20:49:11 +0000
@@ -150,6 +150,8 @@
150 friend class Provider;150 friend class Provider;
151 explicit Controller(Provider& instance);151 explicit Controller(Provider& instance);
152152
153 virtual void on_provider_booted();
154
153 private:155 private:
154 Provider& instance;156 Provider& instance;
155 std::atomic<int> position_updates_counter;157 std::atomic<int> position_updates_counter;
@@ -172,6 +174,20 @@
172 core::Signal<Update<std::set<SpaceVehicle>>> svs;174 core::Signal<Update<std::set<SpaceVehicle>>> svs;
173 };175 };
174176
177 /**
178 * @brief Wraps al those sigals that are related to the boot of the provider.
179 */
180 struct Signals
181 {
182 core::Signal<bool> booted;
183 };
184
185 enum class BootState {
186 NOT_BOOTED,
187 BOOTING,
188 BOOTED
189 };
190
175 virtual ~Provider() = default;191 virtual ~Provider() = default;
176192
177 Provider(const Provider&) = delete;193 Provider(const Provider&) = delete;
@@ -189,6 +205,18 @@
189 virtual const Controller::Ptr& state_controller() const;205 virtual const Controller::Ptr& state_controller() const;
190206
191 /**207 /**
208 * @brief Returns the booted signal to track the booting state of the provider.
209 * @return The signal that will be triggered once the provider has booted.
210 */
211 virtual core::Signal<bool>& boot_state_changed();
212
213 /**
214 * @brief Returns the booted signal to track the booting state of the provider.
215 * @return The signal that will be triggered once the provider has booted.
216 */
217 virtual const core::Signal<bool>& boot_state_changed() const;
218
219 /**
192 * @brief Checks if the provider supports a specific feature.220 * @brief Checks if the provider supports a specific feature.
193 * @param f Feature to test for221 * @param f Feature to test for
194 * @return true iff the provider supports the feature.222 * @return true iff the provider supports the feature.
@@ -210,6 +238,18 @@
210 virtual bool matches_criteria(const Criteria& criteria);238 virtual bool matches_criteria(const Criteria& criteria);
211239
212 /**240 /**
241 * @brief States the booting state of the provider.
242 * @return The boot state of the provider.
243 */
244 virtual BootState boot_state() const;
245
246 /**
247 * @brief Indicates to the provider that it should start the boot process in order to be able to
248 * be used by the engine.
249 */
250 virtual void request_boot();
251
252 /**
213 * @brief Called by the engine whenever the wifi and cell ID reporting state changes.253 * @brief Called by the engine whenever the wifi and cell ID reporting state changes.
214 * @param state The new state.254 * @param state The new state.
215 */255 */
@@ -270,12 +310,14 @@
270 */310 */
271 virtual void stop_velocity_updates();311 virtual void stop_velocity_updates();
272312
273private:313protected:
314 // protected to allow better white box testing
274 struct315 struct
275 {316 {
276 Features features = Features::none;317 Features features = Features::none;
277 Requirements requirements = Requirements::none;318 Requirements requirements = Requirements::none;
278 Updates updates;319 Updates updates;
320 Signals signals;
279 Controller::Ptr controller = Controller::Ptr{};321 Controller::Ptr controller = Controller::Ptr{};
280 } d;322 } d;
281};323};
282324
=== modified file 'src/location_service/com/ubuntu/location/provider.cpp'
--- src/location_service/com/ubuntu/location/provider.cpp 2015-01-23 19:07:09 +0000
+++ src/location_service/com/ubuntu/location/provider.cpp 2015-10-27 20:49:11 +0000
@@ -16,9 +16,11 @@
16 * Authored by: Thomas Voß <thomas.voss@canonical.com>16 * Authored by: Thomas Voß <thomas.voss@canonical.com>
17 */17 */
18#include <com/ubuntu/location/provider.h>18#include <com/ubuntu/location/provider.h>
19#include <com/ubuntu/location/logging.h>
1920
20#include <atomic>21#include <atomic>
21#include <bitset>22#include <bitset>
23#include <functional>
22#include <memory>24#include <memory>
2325
24namespace cul = com::ubuntu::location;26namespace cul = com::ubuntu::location;
@@ -51,12 +53,15 @@
5153
52void cul::Provider::Controller::start_position_updates()54void cul::Provider::Controller::start_position_updates()
53{55{
54 if (position_updates_counter < 0)56 if (position_updates_counter < 0) {
55 return;57 return;
58 }
5659
57 if (++position_updates_counter == 1)60 if (++position_updates_counter == 1)
58 {61 {
59 instance.start_position_updates();62 if (instance.boot_state() == BootState::BOOTED) {
63 instance.start_position_updates();
64 }
60 }65 }
61}66}
6267
@@ -67,7 +72,8 @@
6772
68 if (--position_updates_counter == 0)73 if (--position_updates_counter == 0)
69 {74 {
70 instance.stop_position_updates();75 if (instance.boot_state() == BootState::BOOTED)
76 instance.stop_position_updates();
71 }77 }
72}78}
7379
@@ -83,7 +89,8 @@
8389
84 if (++heading_updates_counter == 1)90 if (++heading_updates_counter == 1)
85 {91 {
86 instance.start_heading_updates();92 if (instance.boot_state() == BootState::BOOTED)
93 instance.start_heading_updates();
87 }94 }
88}95}
8996
@@ -94,7 +101,8 @@
94101
95 if (--heading_updates_counter == 0)102 if (--heading_updates_counter == 0)
96 {103 {
97 instance.stop_heading_updates();104 if (instance.boot_state() == BootState::BOOTED)
105 instance.stop_heading_updates();
98 }106 }
99}107}
100108
@@ -110,7 +118,8 @@
110118
111 if (++velocity_updates_counter == 1)119 if (++velocity_updates_counter == 1)
112 {120 {
113 instance.start_velocity_updates();121 if (instance.boot_state() == BootState::BOOTED)
122 instance.start_velocity_updates();
114 }123 }
115}124}
116125
@@ -121,7 +130,8 @@
121130
122 if (--velocity_updates_counter == 0)131 if (--velocity_updates_counter == 0)
123 {132 {
124 instance.stop_velocity_updates();133 if (instance.boot_state() == BootState::BOOTED)
134 instance.stop_velocity_updates();
125 }135 }
126}136}
127137
@@ -130,12 +140,43 @@
130 return velocity_updates_counter > 0;140 return velocity_updates_counter > 0;
131}141}
132142
143void cul::Provider::Controller::on_provider_booted()
144{
145 if (instance.boot_state() != BootState::BOOTED)
146 return;
147
148 LOG(INFO) << "Provider was booted";
149
150 // we need to propagate the state of the provider using the internal counters as references
151 if (position_updates_counter > 0) {
152 LOG(INFO) << "Starting position updates";
153 instance.start_position_updates();
154 }
155 if (heading_updates_counter > 0) {
156 LOG(INFO) << "Starting heading updates";
157 instance.start_heading_updates();
158 }
159 if (velocity_updates_counter > 0) {
160 LOG(INFO) << "Starting velocity updates";
161 instance.start_velocity_updates();
162 }
163}
164
133cul::Provider::Controller::Controller(cul::Provider& instance)165cul::Provider::Controller::Controller(cul::Provider& instance)
134 : instance(instance),166 : instance(instance),
135 position_updates_counter(0),167 position_updates_counter(0),
136 heading_updates_counter(0),168 heading_updates_counter(0),
137 velocity_updates_counter(0)169 velocity_updates_counter(0)
138{ 170{
171 using namespace std::placeholders;
172
173 if (instance.boot_state() != BootState::BOOTED) {
174 // if the instance has not booted and is delayed we need to keep track of its booting state
175 instance.boot_state_changed().connect(std::bind(&Controller::on_provider_booted, this));
176 if (instance.boot_state() != BootState::BOOTING) {
177 instance.request_boot();
178 }
179 }
139}180}
140181
141const cul::Provider::Controller::Ptr& cul::Provider::state_controller() const182const cul::Provider::Controller::Ptr& cul::Provider::state_controller() const
@@ -158,11 +199,28 @@
158 return false;199 return false;
159}200}
160201
202cul::Provider::BootState cul::Provider::boot_state() const
203{
204 return cul::Provider::BootState::BOOTED;
205}
206
207void cul::Provider::request_boot() { }
208
161const cul::Provider::Updates& cul::Provider::updates() const209const cul::Provider::Updates& cul::Provider::updates() const
162{210{
163 return d.updates;211 return d.updates;
164}212}
165213
214core::Signal<bool>& cul::Provider::boot_state_changed()
215{
216 return d.signals.booted;
217}
218
219const core::Signal<bool>& cul::Provider::boot_state_changed() const
220{
221 return d.signals.booted;
222}
223
166cul::Provider::Provider(224cul::Provider::Provider(
167 const cul::Provider::Features& features,225 const cul::Provider::Features& features,
168 const cul::Provider::Requirements& requirements)226 const cul::Provider::Requirements& requirements)
169227
=== modified file 'tests/controller_test.cpp'
--- tests/controller_test.cpp 2014-09-10 19:34:09 +0000
+++ tests/controller_test.cpp 2015-10-27 20:49:11 +0000
@@ -18,6 +18,7 @@
18#include <com/ubuntu/location/provider.h>18#include <com/ubuntu/location/provider.h>
1919
20#include "mock_provider.h"20#include "mock_provider.h"
21#include "mock_delayed_provider.h"
2122
22#include <gmock/gmock.h>23#include <gmock/gmock.h>
23#include <gtest/gtest.h>24#include <gtest/gtest.h>
@@ -130,3 +131,215 @@
130 EXPECT_FALSE(controller->are_velocity_updates_running());131 EXPECT_FALSE(controller->are_velocity_updates_running());
131 EXPECT_FALSE(controller->are_heading_updates_running());132 EXPECT_FALSE(controller->are_heading_updates_running());
132}133}
134
135TEST(Controller, controller_resumes_state_after_boot) {
136 using namespace ::testing;
137 using ::testing::Mock;
138
139 MockDelayedProvider provider;
140
141 // ignore what ever was performed on construction
142 Mock::VerifyAndClear(&provider);
143
144}
145
146TEST(Controller, controller_does_not_call_start_position_if_not_booted) {
147 using namespace ::testing;
148 using ::testing::Mock;
149
150 MockDelayedProvider provider;
151
152 // ignore what ever was performed on construction
153 Mock::VerifyAndClear(&provider);
154 // use a mock controller
155 auto controller = provider.state_controller();
156
157 EXPECT_CALL(provider, boot_state()).Times(Exactly(1))
158 .WillOnce(Return(cul::Provider::BootState::NOT_BOOTED));
159 EXPECT_CALL(provider, start_position_updates()).Times(Exactly(0));
160
161 controller->start_position_updates();
162 controller->start_position_updates();
163}
164
165TEST(Controller, controller_does_not_call_start_position_if_booting) {
166 using namespace ::testing;
167 using ::testing::Mock;
168
169 MockDelayedProvider provider;
170
171 // ignore what ever was performed on construction
172 Mock::VerifyAndClear(&provider);
173 // use a mock controller
174 auto controller = provider.state_controller();
175
176 EXPECT_CALL(provider, boot_state()).Times(Exactly(1))
177 .WillOnce(Return(cul::Provider::BootState::BOOTING));
178 EXPECT_CALL(provider, start_position_updates()).Times(Exactly(0));
179
180 controller->start_position_updates();
181}
182
183TEST(Controller, controller_does_not_call_start_heading_if_not_booted) {
184 using namespace ::testing;
185 using ::testing::Mock;
186
187 MockDelayedProvider provider;
188 EXPECT_CALL(provider, has_delayed_boot()).WillRepeatedly(Return(true));
189
190 // ignore what ever was performed on construction
191 Mock::VerifyAndClear(&provider);
192 // use a mock controller
193 auto controller = provider.state_controller();
194
195 EXPECT_CALL(provider, boot_state()).Times(Exactly(1))
196 .WillOnce(Return(cul::Provider::BootState::NOT_BOOTED));
197 EXPECT_CALL(provider, start_heading_updates()).Times(Exactly(0));
198
199 controller->start_heading_updates();
200}
201
202TEST(Controller, controller_does_not_call_start_heading_if_booting) {
203 using namespace ::testing;
204 using ::testing::Mock;
205
206 MockDelayedProvider provider;
207 EXPECT_CALL(provider, has_delayed_boot()).WillRepeatedly(Return(true));
208
209 // ignore what ever was performed on construction
210 Mock::VerifyAndClear(&provider);
211 // use a mock controller
212 auto controller = provider.state_controller();
213
214 EXPECT_CALL(provider, boot_state()).Times(Exactly(1))
215 .WillOnce(Return(cul::Provider::BootState::BOOTING));
216 EXPECT_CALL(provider, start_heading_updates()).Times(Exactly(0));
217
218 controller->start_heading_updates();
219}
220
221TEST(Controller, controller_does_not_call_start_velocity_if_not_booted) {
222 using namespace ::testing;
223 using ::testing::Mock;
224
225 MockDelayedProvider provider;
226 EXPECT_CALL(provider, has_delayed_boot()).WillRepeatedly(Return(true));
227
228 // ignore what ever was performed on construction
229 Mock::VerifyAndClear(&provider);
230 // use a mock controller
231 auto controller = provider.state_controller();
232
233 EXPECT_CALL(provider, boot_state()).Times(Exactly(1))
234 .WillOnce(Return(cul::Provider::BootState::NOT_BOOTED));
235 EXPECT_CALL(provider, start_heading_updates()).Times(Exactly(0));
236
237 controller->start_velocity_updates();
238}
239
240TEST(Controller, controller_does_not_call_start_velocity_if_booting) {
241 using namespace ::testing;
242 using ::testing::Mock;
243
244 MockDelayedProvider provider;
245 EXPECT_CALL(provider, has_delayed_boot()).WillRepeatedly(Return(true));
246
247 // ignore what ever was performed on construction
248 Mock::VerifyAndClear(&provider);
249 // use a mock controller
250 auto controller = provider.state_controller();
251
252 EXPECT_CALL(provider, boot_state()).Times(Exactly(1))
253 .WillOnce(Return(cul::Provider::BootState::BOOTING));
254 EXPECT_CALL(provider, start_heading_updates()).Times(Exactly(0));
255
256 controller->start_velocity_updates();
257}
258
259TEST(Controller, controller_does_not_call_stop_position_if_not_booted) {
260 using namespace ::testing;
261 using ::testing::Mock;
262
263 MockDelayedProvider provider;
264 EXPECT_CALL(provider, has_delayed_boot()).WillRepeatedly(Return(true));
265
266 // ignore what ever was performed on construction
267 Mock::VerifyAndClear(&provider);
268 // use a mock controller
269 auto controller = provider.state_controller();
270
271 EXPECT_CALL(provider, boot_state()).Times(Exactly(2))
272 .WillOnce(Return(cul::Provider::BootState::BOOTED))
273 .WillOnce(Return(cul::Provider::BootState::NOT_BOOTED));
274 EXPECT_CALL(provider, start_position_updates()).Times(Exactly(1));
275 EXPECT_CALL(provider, stop_position_updates()).Times(Exactly(0));
276
277 controller->start_position_updates();
278 controller->stop_position_updates();
279}
280
281TEST(Controller, controller_does_not_call_stop_position_if_booting) {
282 using namespace ::testing;
283 using ::testing::Mock;
284
285 MockDelayedProvider provider;
286 EXPECT_CALL(provider, has_delayed_boot()).WillRepeatedly(Return(true));
287
288 // ignore what ever was performed on construction
289 Mock::VerifyAndClear(&provider);
290 // use a mock controller
291 auto controller = provider.state_controller();
292
293 EXPECT_CALL(provider, boot_state()).Times(Exactly(2))
294 .WillOnce(Return(cul::Provider::BootState::BOOTED))
295 .WillOnce(Return(cul::Provider::BootState::BOOTING));
296 EXPECT_CALL(provider, start_position_updates()).Times(Exactly(1));
297 EXPECT_CALL(provider, stop_position_updates()).Times(Exactly(0));
298
299 controller->start_position_updates();
300 controller->stop_position_updates();
301}
302
303TEST(Controller, controller_does_not_call_stop_heading_if_not_booted) {
304 using namespace ::testing;
305 using ::testing::Mock;
306
307 MockDelayedProvider provider;
308 EXPECT_CALL(provider, has_delayed_boot()).WillRepeatedly(Return(true));
309
310 // ignore what ever was performed on construction
311 Mock::VerifyAndClear(&provider);
312 // use a mock controller
313 auto controller = provider.state_controller();
314
315 EXPECT_CALL(provider, boot_state()).Times(Exactly(2))
316 .WillOnce(Return(cul::Provider::BootState::BOOTED))
317 .WillOnce(Return(cul::Provider::BootState::BOOTING));
318 EXPECT_CALL(provider, start_heading_updates()).Times(Exactly(1));
319 EXPECT_CALL(provider, stop_heading_updates()).Times(Exactly(0));
320
321 controller->start_heading_updates();
322 controller->stop_heading_updates();
323}
324
325TEST(Controller, controller_does_not_call_stop_velocity_if_not_booted) {
326 using namespace ::testing;
327 using ::testing::Mock;
328
329 MockDelayedProvider provider;
330 EXPECT_CALL(provider, has_delayed_boot()).WillRepeatedly(Return(true));
331
332 // ignore what ever was performed on construction
333 Mock::VerifyAndClear(&provider);
334 // use a mock controller
335 auto controller = provider.state_controller();
336
337 EXPECT_CALL(provider, boot_state()).Times(Exactly(2))
338 .WillOnce(Return(cul::Provider::BootState::BOOTED))
339 .WillOnce(Return(cul::Provider::BootState::BOOTING));
340 EXPECT_CALL(provider, start_velocity_updates()).Times(Exactly(1));
341 EXPECT_CALL(provider, stop_velocity_updates()).Times(Exactly(0));
342
343 controller->start_velocity_updates();
344 controller->stop_velocity_updates();
345}
133346
=== added file 'tests/mock_delayed_provider.h'
--- tests/mock_delayed_provider.h 1970-01-01 00:00:00 +0000
+++ tests/mock_delayed_provider.h 2015-10-27 20:49:11 +0000
@@ -0,0 +1,89 @@
1/*
2 * Copyright © 2014 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: M
17 */
18#ifndef MOCK_DELAYED_PROVIDER_H_
19#define MOCK_DELAYED_PROVIDER_H_
20
21#include <com/ubuntu/location/provider.h>
22#include <com/ubuntu/location/logging.h>
23
24#include <gmock/gmock.h>
25
26struct PublicController : public com::ubuntu::location::Provider::Controller
27{
28
29 explicit PublicController(com::ubuntu::location::Provider& instance)
30 : com::ubuntu::location::Provider::Controller(instance) {}
31};
32
33struct MockDelayedProvider : public com::ubuntu::location::Provider
34{
35 MockDelayedProvider() : com::ubuntu::location::Provider()
36 {
37 }
38
39 MOCK_METHOD1(matches_criteria, bool(const com::ubuntu::location::Criteria&));
40
41 MOCK_CONST_METHOD1(supports, bool(const com::ubuntu::location::Provider::Features&));
42 MOCK_CONST_METHOD1(requires, bool(const com::ubuntu::location::Provider::Requirements&));
43
44 // Called by the engine whenever the wifi and cell ID reporting state changes.
45 MOCK_METHOD1(on_wifi_and_cell_reporting_state_changed, void(com::ubuntu::location::WifiAndCellIdReportingState state));
46
47 // Called by the engine whenever the reference location changed.
48 MOCK_METHOD1(on_reference_location_updated, void(const com::ubuntu::location::Update<com::ubuntu::location::Position>& position));
49
50 // Called by the engine whenever the reference velocity changed.
51 MOCK_METHOD1(on_reference_velocity_updated, void(const com::ubuntu::location::Update<com::ubuntu::location::Velocity>& velocity));
52
53 // Called by the engine whenever the reference heading changed.
54 MOCK_METHOD1(on_reference_heading_updated, void(const com::ubuntu::location::Update<com::ubuntu::location::Heading>& heading));
55
56 MOCK_METHOD0(start_position_updates, void());
57 MOCK_METHOD0(stop_position_updates, void());
58
59 MOCK_METHOD0(start_heading_updates, void());
60 MOCK_METHOD0(stop_heading_updates, void());
61
62 MOCK_METHOD0(start_velocity_updates, void());
63 MOCK_METHOD0(stop_velocity_updates, void());
64
65 MOCK_CONST_METHOD0(has_delayed_boot, bool());
66 MOCK_CONST_METHOD0(boot_state, BootState());
67 MOCK_CONST_METHOD0(boot, void());
68
69
70 // Inject a position update from the outside.
71 void inject_update(const com::ubuntu::location::Update<com::ubuntu::location::Position>& update)
72 {
73 mutable_updates().position(update);
74 }
75
76 // Inject a velocity update from the outside.
77 void inject_update(const com::ubuntu::location::Update<com::ubuntu::location::Velocity>& update)
78 {
79 mutable_updates().velocity(update);
80 }
81
82 // Inject a heading update from the outside.
83 void inject_update(const com::ubuntu::location::Update<com::ubuntu::location::Heading>& update)
84 {
85 mutable_updates().heading(update);
86 }
87};
88
89#endif // MOCK_PROVIDER_H_

Subscribers

People subscribed via source and target branches