Merge lp:~thomas-voss/location-service/fix-settings-not-being-applied into lp:location-service/trunk
- fix-settings-not-being-applied
- Merge into trunk
Proposed by
Thomas Voß
Status: | Superseded |
---|---|
Proposed branch: | lp:~thomas-voss/location-service/fix-settings-not-being-applied |
Merge into: | lp:location-service/trunk |
Diff against target: |
2114 lines (+1468/-140) (has conflicts) 34 files modified
CMakeLists.txt (+14/-0) _clang-format (+56/-0) astyle-config (+43/-0) debian/changelog (+71/-0) doc/Doxyfile.in (+2/-2) doc/daemon_and_cli.md (+55/-0) doc/debugging.md (+92/-0) doc/hacking.md (+146/-0) doc/intro.md (+67/-0) doc/manual_testing.md (+174/-0) doc/tips_n_tricks.md (+21/-0) src/location_service/com/ubuntu/location/CMakeLists.txt (+1/-0) src/location_service/com/ubuntu/location/connectivity/cached_wireless_network.cpp (+12/-6) src/location_service/com/ubuntu/location/connectivity/cached_wireless_network.h (+12/-0) src/location_service/com/ubuntu/location/connectivity/ofono_nm_connectivity_manager.cpp (+1/-1) src/location_service/com/ubuntu/location/engine.cpp (+23/-14) src/location_service/com/ubuntu/location/engine.h (+3/-3) src/location_service/com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.cpp (+3/-5) src/location_service/com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.h (+1/-1) src/location_service/com/ubuntu/location/service/daemon.cpp (+14/-66) src/location_service/com/ubuntu/location/service/implementation.cpp (+25/-4) src/location_service/com/ubuntu/location/service/provider_daemon.cpp (+17/-16) src/location_service/com/ubuntu/location/service/runtime.cpp (+109/-0) src/location_service/com/ubuntu/location/service/runtime.h (+90/-0) src/location_service/com/ubuntu/location/service/session/skeleton.cpp (+21/-3) src/location_service/com/ubuntu/location/time_based_update_policy.cpp (+4/-3) tests/CMakeLists.txt (+1/-0) tests/acceptance_tests.cpp (+114/-12) tests/engine_test.cpp (+3/-3) tests/gps_provider_test.cpp (+83/-0) tests/position_test.cpp (+1/-1) tests/runtime_test.cpp (+118/-0) tools/CMakeLists.txt (+1/-0) tools/symbol_diff.in (+70/-0) Text conflict in debian/changelog |
To merge this branch: | bzr merge lp:~thomas-voss/location-service/fix-settings-not-being-applied |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ubuntu Phablet Team | Pending | ||
Review via email: mp+280040@code.launchpad.net |
This proposal has been superseded by a proposal from 2015-12-09.
Commit message
Fix settings not being applied correctly.
Description of the change
Fix settings not being applied correctly.
To post a comment you must log in.
Unmerged revisions
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'CMakeLists.txt' |
2 | --- CMakeLists.txt 2014-09-18 23:06:08 +0000 |
3 | +++ CMakeLists.txt 2015-12-09 15:21:10 +0000 |
4 | @@ -54,6 +54,20 @@ |
5 | SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=unused-local-typedefs") |
6 | endif (DISABLE_ERROR_ON_LOCAL_TYPEDEFS_WARNINGS) |
7 | |
8 | +# |
9 | +# Code style fixer. We rely on clang-format to adjust the formatting of source code. |
10 | +# |
11 | +find_program(CLANG_FORMAT_COMMAND NAMES clang-format-3.6 clang-format-3.5) |
12 | +if (NOT CLANG_FORMAT_COMMAND) |
13 | + message(WARNING "Cannot find clang-format >= clang-format-3.5: formatcode target will not be available") |
14 | +endif() |
15 | + |
16 | +if (CLANG_FORMAT_COMMAND) |
17 | + file(GLOB_RECURSE UBUNTU_LOCATION_SERVICE_INTERFACE_HEADER_FILES ${CMAKE_SOURCE_DIR}/include/*.h) |
18 | + file(GLOB_RECURSE UBUNTU_LOCATION_SERVICE_IMPLEMENTATION_FILES ${CMAKE_SOURCE_DIR}/src/*.h ${CMAKE_SOURCE_DIR}/src/*.cpp) |
19 | + add_custom_target(formatcode ${CLANG_FORMAT_COMMAND} -i ${UBUNTU_LOCATION_SERVICE_INTERFACE_HEADER_FILES} ${UBUNTU_LOCATION_SERVICE_IMPLEMENTATION_FILES} SOURCES _clang-format) |
20 | +endif() |
21 | + |
22 | include_directories( |
23 | ${Boost_INCLUDE_DIRS} |
24 | ${DBUS_INCLUDE_DIRS} |
25 | |
26 | === added file '_clang-format' |
27 | --- _clang-format 1970-01-01 00:00:00 +0000 |
28 | +++ _clang-format 2015-12-09 15:21:10 +0000 |
29 | @@ -0,0 +1,56 @@ |
30 | +--- |
31 | +Language: Cpp |
32 | +AccessModifierOffset: -4 |
33 | +ConstructorInitializerIndentWidth: 4 |
34 | +AlignEscapedNewlinesLeft: false |
35 | +AlignTrailingComments: true |
36 | +AllowAllParametersOfDeclarationOnNextLine: true |
37 | +AllowShortBlocksOnASingleLine: false |
38 | +AllowShortIfStatementsOnASingleLine: false |
39 | +AllowShortLoopsOnASingleLine: false |
40 | +AllowShortFunctionsOnASingleLine: All |
41 | +AlwaysBreakTemplateDeclarations: false |
42 | +AlwaysBreakBeforeMultilineStrings: false |
43 | +BreakBeforeBinaryOperators: false |
44 | +BreakBeforeTernaryOperators: true |
45 | +BreakConstructorInitializersBeforeComma: false |
46 | +BinPackParameters: true |
47 | +ColumnLimit: 0 |
48 | +ConstructorInitializerAllOnOneLineOrOnePerLine: false |
49 | +DerivePointerAlignment: false |
50 | +ExperimentalAutoDetectBinPacking: false |
51 | +IndentCaseLabels: false |
52 | +IndentWrappedFunctionNames: false |
53 | +IndentFunctionDeclarationAfterType: false |
54 | +MaxEmptyLinesToKeep: 1 |
55 | +KeepEmptyLinesAtTheStartOfBlocks: true |
56 | +NamespaceIndentation: None |
57 | +ObjCSpaceAfterProperty: false |
58 | +ObjCSpaceBeforeProtocolList: true |
59 | +PenaltyBreakBeforeFirstCallParameter: 19 |
60 | +PenaltyBreakComment: 300 |
61 | +PenaltyBreakString: 1000 |
62 | +PenaltyBreakFirstLessLess: 120 |
63 | +PenaltyExcessCharacter: 1000000 |
64 | +PenaltyReturnTypeOnItsOwnLine: 60 |
65 | +PointerAlignment: Left |
66 | +SpacesBeforeTrailingComments: 1 |
67 | +Cpp11BracedListStyle: true |
68 | +Standard: Cpp11 |
69 | +IndentWidth: 4 |
70 | +TabWidth: 8 |
71 | +UseTab: Never |
72 | +BreakBeforeBraces: Allman |
73 | +SpacesInParentheses: false |
74 | +SpacesInAngles: false |
75 | +SpaceInEmptyParentheses: false |
76 | +SpacesInCStyleCastParentheses: false |
77 | +SpacesInContainerLiterals: true |
78 | +SpaceBeforeAssignmentOperators: true |
79 | +ContinuationIndentWidth: 4 |
80 | +CommentPragmas: '^ IWYU pragma:' |
81 | +ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] |
82 | +SpaceBeforeParens: ControlStatements |
83 | +DisableFormat: false |
84 | +... |
85 | + |
86 | |
87 | === added file 'astyle-config' |
88 | --- astyle-config 1970-01-01 00:00:00 +0000 |
89 | +++ astyle-config 2015-12-09 15:21:10 +0000 |
90 | @@ -0,0 +1,43 @@ |
91 | +# Options for formatting code with astyle. |
92 | +# |
93 | +# This helps to make code match the style guide. |
94 | +# |
95 | +# Use like this: |
96 | +# |
97 | +# astyle --options=astyle-config mfile.h myfile.cpp |
98 | +# |
99 | +# Occasionally, astyle does something silly (particularly with lambdas), so it's |
100 | +# still necessary to scan the changes for things that are wrong. |
101 | +# But, for most files, it does a good job. |
102 | +# |
103 | +# Please consider using this before checking code in for review. Code reviews shouldn't |
104 | +# have to deal with layout issues, they are just a distraction. It's better to be able |
105 | +# to focus on semantics in a code review, with style issues out of the way. |
106 | + |
107 | +--formatted |
108 | +--style=allman |
109 | +--min-conditional-indent=2 |
110 | +--indent-switches |
111 | +--max-instatement-indent=120 |
112 | +--pad-header |
113 | +--align-pointer=type |
114 | +--align-reference=type |
115 | +--convert-tabs |
116 | +--close-templates |
117 | +--max-code-length=120 |
118 | + |
119 | +# --pad-oper |
120 | +# |
121 | +# Commented out for now. It changes |
122 | +# |
123 | +# for (int i=0; i<10; ++i) |
124 | +# to |
125 | +# for (int i = 0; i < 10; ++i) |
126 | +# |
127 | +# Unfortunately, it also messes with rvalue references: |
128 | +# |
129 | +# ResourcePtr& operator=(ResourcePtr&& r); |
130 | +# |
131 | +# becomes: |
132 | +# |
133 | +# ResourcePtr& operator=(ResourcePtr && r); |
134 | |
135 | === modified file 'debian/changelog' |
136 | --- debian/changelog 2015-07-27 18:07:37 +0000 |
137 | +++ debian/changelog 2015-12-09 15:21:10 +0000 |
138 | @@ -1,3 +1,4 @@ |
139 | +<<<<<<< TREE |
140 | location-service (2.1+15.10.20150727-0ubuntu1) wily; urgency=medium |
141 | |
142 | [ CI Train Bot ] |
143 | @@ -36,6 +37,76 @@ |
144 | |
145 | -- CI Train Bot <ci-train-bot@canonical.com> Thu, 28 May 2015 11:40:58 +0000 |
146 | |
147 | +======= |
148 | +location-service (2.1+15.04.20151202.1-0ubuntu1) vivid; urgency=medium |
149 | + |
150 | + * Ensure that event connections are cleaned up on destruction. (LP: |
151 | + #1480877) |
152 | + |
153 | + -- Thomas Voß <ci-train-bot@canonical.com> Wed, 02 Dec 2015 12:12:21 +0000 |
154 | + |
155 | +location-service (2.1+15.04.20151127-0ubuntu1) vivid; urgency=medium |
156 | + |
157 | + [ Alberto Mardegan ] |
158 | + * Send last known position on session start |
159 | + |
160 | + [ CI Train Bot ] |
161 | + * New rebuild forced. |
162 | + |
163 | + [ Thomas Voß ] |
164 | + * Factor out service::Runtime from daemon.cpp into its own .h/.cpp |
165 | + pair of files. Add test cases around correct operation of |
166 | + service::Runtime. added: |
167 | + src/location_service/com/ubuntu/location/service/runtime.cpp |
168 | + src/location_service/com/ubuntu/location/service/runtime.h |
169 | + tests/runtime_test.cpp |
170 | + |
171 | + [ thomas-voss ] |
172 | + * Factor out service::Runtime from daemon.cpp into its own .h/.cpp |
173 | + pair of files. Add test cases around correct operation of |
174 | + service::Runtime. added: |
175 | + src/location_service/com/ubuntu/location/service/runtime.cpp |
176 | + src/location_service/com/ubuntu/location/service/runtime.h |
177 | + tests/runtime_test.cpp |
178 | + |
179 | + -- Thomas Voß <ci-train-bot@canonical.com> Fri, 27 Nov 2015 13:00:33 +0000 |
180 | + |
181 | +location-service (2.1+15.04.20151113-0ubuntu1) vivid; urgency=medium |
182 | + |
183 | + * Adjust default timeout for downloading GPS XTRA data. |
184 | + |
185 | + -- Thomas Voß <ci-train-bot@canonical.com> Fri, 13 Nov 2015 10:33:56 +0000 |
186 | + |
187 | +location-service (2.1+15.04.20151109.2-0ubuntu1) vivid; urgency=medium |
188 | + |
189 | + [ Alberto Mardegan ] |
190 | + * Make sure that injected time is given in milliseconds |
191 | + |
192 | + [ Thomas Voß ] |
193 | + * Cherry-pick rev. 196 and 199 from lp:location-service. The changes |
194 | + got accidentally removed by merging the outstanding documentation |
195 | + branch. |
196 | + * Handle responses of clients to updates asynchronously. Rely on |
197 | + dummy::ConnectivityManager as harvesting is disabled anyway. (LP: |
198 | + #1462664, #1387643) |
199 | + |
200 | + -- David Barth <david.barth@canonical.com> Mon, 09 Nov 2015 20:48:48 +0000 |
201 | + |
202 | +location-service (2.1+15.04.20151022-0ubuntu1) vivid; urgency=medium |
203 | + |
204 | + [ Thomas Voß ] |
205 | + * Add documentation for debugging, hacking and debugging the location |
206 | + service. Pull manual testing instructions over from the wiki. Add |
207 | + tools for formatting the source. |
208 | + |
209 | + [ thomas-voss ] |
210 | + * Add documentation for debugging, hacking and debugging the location |
211 | + service. Pull manual testing instructions over from the wiki. Add |
212 | + tools for formatting the source. |
213 | + |
214 | + -- Thomas Voß <ci-train-bot@canonical.com> Thu, 22 Oct 2015 07:16:50 +0000 |
215 | + |
216 | +>>>>>>> MERGE-SOURCE |
217 | location-service (2.1+15.04.20150427.1-0ubuntu1) vivid; urgency=medium |
218 | |
219 | [ CI Train Bot ] |
220 | |
221 | === modified file 'doc/Doxyfile.in' |
222 | --- doc/Doxyfile.in 2014-05-19 09:55:25 +0000 |
223 | +++ doc/Doxyfile.in 2015-12-09 15:21:10 +0000 |
224 | @@ -748,7 +748,7 @@ |
225 | # directories that contain image that are included in the documentation (see |
226 | # the \image command). |
227 | |
228 | -IMAGE_PATH = |
229 | +IMAGE_PATH = @CMAKE_CURRENT_SOURCE_DIR@/images |
230 | |
231 | # The INPUT_FILTER tag can be used to specify a program that doxygen should |
232 | # invoke to filter for each input file. Doxygen will invoke the filter program |
233 | @@ -1463,7 +1463,7 @@ |
234 | # generate an XML file that captures the structure of |
235 | # the code including all documentation. |
236 | |
237 | -GENERATE_XML = NO |
238 | +GENERATE_XML = YES |
239 | |
240 | # The XML_OUTPUT tag is used to specify where the XML pages will be put. |
241 | # If a relative path is entered the value of OUTPUT_DIRECTORY will be |
242 | |
243 | === added file 'doc/daemon_and_cli.md' |
244 | --- doc/daemon_and_cli.md 1970-01-01 00:00:00 +0000 |
245 | +++ doc/daemon_and_cli.md 2015-12-09 15:21:10 +0000 |
246 | @@ -0,0 +1,55 @@ |
247 | +# Service Daemon and CLI |
248 | + |
249 | +The location service offers a daemon executable and a corresponding |
250 | +command-line interface for interacting with it. The daemon does not |
251 | +necessarily require root privileges, but might so depending on your |
252 | +configuration. |
253 | + |
254 | +Run the following command to receive an overview of the arguments to |
255 | +the daemon: |
256 | + |
257 | + ubuntu-location-serviced --help |
258 | + |
259 | +An example invocation of the daemon, configuring a GPS provider that |
260 | +relies on the Android HAL to talk to the chipset, exposing the service |
261 | +on the system DBus instance: |
262 | + |
263 | + ubuntu-location-serviced --bus system --provider gps::Provider |
264 | + |
265 | +The cli allows for querying properties of a running service instance, e.g.: |
266 | + |
267 | + ubuntu-location-serviced-cli --bus system --get --property is_online |
268 | + |
269 | +## Configuring an Out-Of-Process Provider |
270 | + |
271 | +If you want to run a provider out of process, the daemon executable |
272 | +allows you to do so by instantiating a so-called remote provider. The |
273 | +following invocation of the service tries to connect to the provider |
274 | +instance described by the given unique DBus name and path. |
275 | + |
276 | + ubuntu-location-serviced \ |
277 | + --bus system \ |
278 | + --provider remote::Provider \ |
279 | + --remote::Provider::bus=system \ |
280 | + --remote::Provider::name=com.ubuntu.location.provider.Gps \ |
281 | + --remote::Provider::path=/ |
282 | + |
283 | +Please note that the service allows for decorating provider names to |
284 | +uniquely identify per provider configuration options and to allow for |
285 | +loading more than one provider of a certain kind. The following |
286 | +configuration configures two remote providers, one relying on GPS |
287 | +(decorated with @gps) and another one relying on network-based |
288 | +positioning (decorated with @network): |
289 | + |
290 | + ubuntu-location-serviced \ |
291 | + --bus system \ |
292 | + --provider remote::Provider@gps \ |
293 | + --remote::Provider@gps::bus=system \ |
294 | + --remote::Provider@gps::name=com.ubuntu.location.provider.Gps \ |
295 | + --remote::Provider@gps::path=/ \ |
296 | + --provider remote::Provider@network \ |
297 | + --remote::Provider@network::bus=system \ |
298 | + --remote::Provider@network::name=com.ubuntu.location.provider.Network \ |
299 | + --remote::Provider@network::path=/ |
300 | + |
301 | + |
302 | |
303 | === added file 'doc/debugging.md' |
304 | --- doc/debugging.md 1970-01-01 00:00:00 +0000 |
305 | +++ doc/debugging.md 2015-12-09 15:21:10 +0000 |
306 | @@ -0,0 +1,92 @@ |
307 | +# Debugging |
308 | + |
309 | +Location not working? Here's how to debug. |
310 | + |
311 | +## Layers |
312 | + |
313 | +Test in OSMTouch (QML app using Qt API) before testing in webapps or |
314 | +webbrowser app. Different results? File a bug where it doesn't |
315 | +work. Same result of no location? Next step. |
316 | + |
317 | +## Check that stack works with dummy provider |
318 | + |
319 | +Edit /etc/init/ubuntu-location-provider.override to start |
320 | +location-serviced with just the dummy provider; this should |
321 | +work. Doesn't work? File a bug against location-service. Works? Reset |
322 | +config to defaults and try the next thing. |
323 | + |
324 | +## Hardware GPS breaking all of location-service |
325 | + |
326 | +GPS provider is built-in into location-service and might break all of |
327 | +it if it goes south (working on splitting it out); try enabling only |
328 | +the HERE provider on the location-serviced command-line and see if |
329 | +that works. Works? File a bug against location-service. Doesn't work? |
330 | +Move on. |
331 | + |
332 | +## HERE test |
333 | + |
334 | +To test whether the low-level HERE stack gets a location, put |
335 | +http://people.canonical.com/~lool/espoo-cli on your phone (will be |
336 | +included along HERE bits in the future) and run with: |
337 | + |
338 | + chmod a+x espoo-cli |
339 | + GLOG_logtostderr=1 GLOG_v=100 LD_LIBRARY_PATH=/custom/vendor/here/location-provider/lib/arm-linux-gnueabihf ./espoo-cli 5 |
340 | + |
341 | +NB: 5 is the number of location updates after which the tool exits; |
342 | +updates should come in at approx 15s interval. Output looks like: |
343 | + |
344 | + I1101 21:30:01.285964 4403 cli.cpp:117] Requested number of updates is 2 |
345 | + I1101 21:30:01.299002 4403 cli.cpp:133] Starting location updates |
346 | + I1101 21:30:01.301888 4403 cli.cpp:141] Starting GLib main loop |
347 | + I1101 21:30:11.304612 4403 cli.cpp:158] Location: tstamp=1414891811 lat=xyz long=foo hor. acc.=2569 alt=nan vert. acc.=nan tech=cell |
348 | + I1101 21:30:11.306061 4403 cli.cpp:170] Remaining updates: 1 |
349 | + I1101 21:30:26.736821 4403 cli.cpp:158] Location: tstamp=1414891826 lat=xyz long=foo hor. acc.=2824 alt=nan vert. acc.=nan tech=cell |
350 | + I1101 21:30:26.738348 4403 cli.cpp:148] Stopping location updates |
351 | + |
352 | +Low-level HERE stack works but location-serviced with just HERE |
353 | +provider doesn't work? File a bug against espoo projet (HERE) and/or |
354 | +location-service. Low-level HERE stack doesn't work? Move on |
355 | + |
356 | +## location-service and espoo-service debug |
357 | + |
358 | +Collect some debug data by editing /etc/init/ubuntu-espoo-service.conf |
359 | +and /etc/init/ubuntu-location-service.override and changing the start |
360 | +sequence to add some env vars: |
361 | + |
362 | + export GLOG_v=200 |
363 | + export GLOG_logtostderr=1 |
364 | + |
365 | +before the exec. Reboot, and start some app. You should have some log |
366 | +files under /var/log/upstart/ubuntu-espoo-service.log and |
367 | +/var/log/upstart/ubuntu-location-service.log to attach to a bug |
368 | +report; e.g. a working espoo log looks like this: |
369 | + |
370 | + WARNING: Logging before InitGoogleLogging() is written to STDERR |
371 | + I1105 16:30:10.221474 1620 provider.cpp:568] StartPositionUpdates |
372 | + I1105 16:30:10.224901 1620 provider.cpp:122] Successfully started position updates. |
373 | + I1105 16:30:10.228739 1620 provider.cpp:596] StartVelocityUpdates |
374 | + I1105 16:30:13.046851 1621 provider.cpp:83] Received location: Position(lat: Coordinate(12.34 deg), lon: Coordinate(12.34 deg), alt: Coordinate(nan m), hor.acc.: 1430 m, ver.acc.: nan m) |
375 | + |
376 | +No position there? check connectivity API works by running: |
377 | + |
378 | + cd /tmp |
379 | + wget http://people.ubuntu.com/~lool/connectivity |
380 | + GLOG_v=200 GLOG_logtostderr=1 ./connectivity |
381 | + |
382 | +you should see something like: |
383 | + |
384 | + I1105 16:47:26.431466 11140 cached_radio_cell.cpp:160] (mcc: 123, mnc: 2, lac: 1234, id: 123456, asu: 1) |
385 | + I1105 16:47:26.533818 11140 connectivity.cpp:47] Is wifi enabled: true |
386 | + I1105 16:47:26.533963 11140 connectivity.cpp:48] Is wifi hw enabled: true |
387 | + I1105 16:47:26.534010 11140 connectivity.cpp:49] Is wwan enabled: true |
388 | + I1105 16:47:26.534050 11140 connectivity.cpp:50] Is wwan hw enabled: true |
389 | + I1105 16:47:26.534442 11140 connectivity.cpp:122] umts(mcc: 123, mnc: 2, lac: 1234, id: 123456, asu: 1) |
390 | + I1105 16:47:26.534633 11140 connectivity.cpp:155] (bssid: 12:12:12:12:12:12, ssid: xyz, last seen: 1415224046, mode: Mode::infrastructure, frequency: 2442, strength: 63) |
391 | + I1105 16:47:26.534828 11140 connectivity.cpp:155] (bssid: 12:12:12:12:12:12, ssid: boing, last seen: 1415224046, mode: Mode::infrastructure, frequency: 2467, strength: 57) |
392 | + |
393 | +Also, please attach output of /usr/share/ofono/scripts/list-modems > list-modems-output.txt |
394 | +Please note that the command might take ~1 minute to complete. |
395 | + |
396 | +TODO: document dbus-monitor / d-feet capturing of client / system traffic with snooping config. |
397 | + |
398 | + |
399 | |
400 | === added file 'doc/hacking.md' |
401 | --- doc/hacking.md 1970-01-01 00:00:00 +0000 |
402 | +++ doc/hacking.md 2015-12-09 15:21:10 +0000 |
403 | @@ -0,0 +1,146 @@ |
404 | +# Hacking |
405 | + |
406 | + |
407 | +## Building the code |
408 | + |
409 | +By default, the code is built in release mode. To build a debug version, use |
410 | + |
411 | + $ mkdir builddebug |
412 | + $ cd builddebug |
413 | + $ cmake -DCMAKE_BUILD_TYPE=debug .. |
414 | + $ make |
415 | + |
416 | +For a release version, use -DCMAKE_BUILD_TYPE=release |
417 | + |
418 | +## Running the tests |
419 | + |
420 | + $ make |
421 | + $ make test |
422 | + |
423 | +Note that "make test" alone is dangerous because it does not rebuild |
424 | +any tests if either the library or the test files themselves need |
425 | +rebuilding. It's not possible to fix this with cmake because cmake cannot |
426 | +add build dependencies to built-in targets. To make sure that everything |
427 | +is up-to-date, run "make" before running "make test"! |
428 | + |
429 | +## Coverage |
430 | + |
431 | +To build with the flags for coverage testing enabled and get coverage: |
432 | + |
433 | + $ mkdir buildcoverage |
434 | + $ cd buildcoverage |
435 | + $ cmake -DCMAKE_BUILD_TYPE=coverage |
436 | + $ make |
437 | + $ make test |
438 | + $ make coverage |
439 | + |
440 | +Unfortunately, it is not possible to get 100% coverage for some files, |
441 | +mainly due to gcc's generation of two destructors for dynamic and non- |
442 | +dynamic instances. For abstract base classes and for classes that |
443 | +prevent stack and static allocation, this causes one of the destructors |
444 | +to be reported as uncovered. |
445 | + |
446 | +There are also issues with some functions in header files that are |
447 | +incorrectly reported as uncovered due to inlining, as well as |
448 | +the impossibility of covering defensive assert(false) statements, |
449 | +such as an assert in the default branch of a switch, where the |
450 | +switch is meant to handle all possible cases explicitly. |
451 | + |
452 | +If you run a binary and get lots of warnings about a "merge mismatch for summaries", |
453 | +this is caused by having made changes to the source that add or remove code |
454 | +that was previously run, so the new coverage output cannot sensibly be merged |
455 | +into the old coverage output. You can get rid of this problem by running |
456 | + |
457 | + $ make clean-coverage |
458 | + |
459 | +This deletes all the .gcda files, allowing the merge to (sometimes) succeed again. |
460 | +If this doesn't work either, the only remedy is to do a clean build. |
461 | + |
462 | +If lcov complains about unrecognized lines involving '=====', |
463 | +you can patch geninfo and gcovr as explained here: |
464 | + |
465 | +https://bugs.launchpad.net/gcovr/+bug/1086695/comments/2 |
466 | + |
467 | +## Code style |
468 | + |
469 | +We use a format tool that fixes a whole lot of issues |
470 | +regarding code style. The formatting changes made by |
471 | +the tool are generally sensible (even though they may not be your |
472 | +personal preference in all cases). If there is a case where the formatting |
473 | +really messes things up, consider re-arranging the code to avoid the problem. |
474 | +The convenience of running the entire code base through the pretty-printer |
475 | +far outweighs any minor glitches with pretty printing, and it means that |
476 | +we get consistent code style for free, rather than endlessly having to |
477 | +watch out for formatting issues during code reviews. |
478 | + |
479 | +As of clang-format-3.7, you can use |
480 | + |
481 | + // clang-format off |
482 | + void unformatted_code ; |
483 | + // clang-format on |
484 | + |
485 | +to suppress formatting for a section of code. |
486 | + |
487 | +To format specific files: |
488 | + |
489 | + ${CMAKE_BINARY_DIR}/tools/formatcode x.cpp x.h |
490 | + |
491 | +If no arguments are provided, formatcode reads stdin and writes |
492 | +stdout, so you can easily pipe code into the tool from within an |
493 | +editor. For example, to reformat the entire file in vi (assuming |
494 | +${CMAKE_BINARY_DIR}/tools is in your PATH): |
495 | + |
496 | + 1G!Gformatcode |
497 | + |
498 | +To re-format all source and header files in the tree: |
499 | + |
500 | + $ make formatcode |
501 | + |
502 | +## Thread and address sanitizer |
503 | + |
504 | +Set SANITIZER to "thread" or "address" to build with the |
505 | +corresponding sanitizer enabled. |
506 | + |
507 | +## Updating symbols file |
508 | + |
509 | +To easily spot new/removed/changed symbols in the library, the debian |
510 | +package maintains a .symbols file that lists all exported symbols |
511 | +present in the library .so. If you add new public symbols to the library, |
512 | +it's necessary to refresh the symbols file, otherwise the package will |
513 | +fail to build. The easiest way to do that is using bzr-builddeb: |
514 | + |
515 | + $ bzr bd -- -us -uc -j8 # Don't sign source package or changes file, 8 compiles in parallel |
516 | + $ # this will exit with an error if symbols file isn't up-to-date |
517 | + $ cd ../build-area/location-service-[version] |
518 | + $ ./obj-[arch]/tools/symbol_diff |
519 | + |
520 | +This creates a diff of the symbols in /tmp/symbols.diff. |
521 | +(The demangled symbols from the debian build are in ./new_symbols.) |
522 | + |
523 | +Review any changes in /tmp/symbols.diff. If they are OK: |
524 | + |
525 | + $ cd - |
526 | + $ patch -p0 < /tmp/symbols.diff |
527 | + |
528 | +## ABI compliance test |
529 | + |
530 | +To use this, install abi-compliance-checker package from the archives. |
531 | + |
532 | +You can use abi-compliance-checker to test whether a particular build |
533 | +is ABI compatible with another build. The tool does some source-level |
534 | +analysis in addition to checking library symbols, so it catches things |
535 | +that are potentially dangerous, but won't be picked up by just looking |
536 | +at the symbol table. |
537 | + |
538 | +Assume you have built devel in src/devel, and you have a later build |
539 | +in src/mybranch and want to check that mybranch is still compatible. |
540 | +To run the compliance test: |
541 | + |
542 | + $ cd src |
543 | + $ abi-compliance-checker -lib libunity-scopes.so -old devel/build/test/abi-compliance/abi.xml -new mybranch/build/test/abi-compliance/abi.xml |
544 | + |
545 | +The script will take about two minutes to run. Now point your browser at |
546 | + |
547 | + src/compat_reports/libunity-scopes.so/[version]_to_[version]/compat_report.html |
548 | + |
549 | +The report provides a nicely layed-out page with all the details. |
550 | |
551 | === added directory 'doc/images' |
552 | === added file 'doc/images/LocationServiceHighLevel.png' |
553 | Binary files doc/images/LocationServiceHighLevel.png 1970-01-01 00:00:00 +0000 and doc/images/LocationServiceHighLevel.png 2015-12-09 15:21:10 +0000 differ |
554 | === added file 'doc/intro.md' |
555 | --- doc/intro.md 1970-01-01 00:00:00 +0000 |
556 | +++ doc/intro.md 2015-12-09 15:21:10 +0000 |
557 | @@ -0,0 +1,67 @@ |
558 | +# Introduction {#mainpage} |
559 | + |
560 | +Ubuntu's location service is a central hub for multiplexing access to |
561 | +positioning subsystems available via hard- and software. It provides a |
562 | +client API offering positioning capabilities to applications and other |
563 | +system components, abstracting away the details of individual |
564 | +positioning solutions. |
565 | + |
566 | +## Vocabulary |
567 | + |
568 | +To make the remainder of this documentation as easily understandable |
569 | +as possible, we start over with introducing some vocabulary: |
570 | + |
571 | +- Engine: |
572 | + Responsible for handling input from multiple positioning |
573 | + subsystems and maintaining the state of the overall system. Think |
574 | + about it like the heart of the system. |
575 | + |
576 | +- Provider: |
577 | + A positioning subsystem that feeds into the positioning |
578 | + engine. Common examples are a GPS provider or a network-based |
579 | + positioning provider. |
580 | + |
581 | +- Service: |
582 | + The point of entry for applications and services that would |
583 | + like to receive position data. |
584 | + |
585 | +- Session: |
586 | + In order to receive position information, every application |
587 | + or service has to create a session with the location Service. |
588 | + |
589 | +- Update: An update is a timestamped entity to a certain type of data. |
590 | + |
591 | +- [WGS84, http://en.wikipedia.org/wiki/World_Geodetic_System]: The coordinate system that is used throughout the entire location subsystem. |
592 | + |
593 | +## Architectural Overview |
594 | + |
595 | +The high-level architecture of the service is shown in the following diagram: |
596 | + |
597 | +![High-level architectural overview](images/LocationServiceHighLevel.png) |
598 | + |
599 | +In this diagram, the configuration of the engine refers to: |
600 | + |
601 | + * The current state of any satellite-based positioning subsystems. Can either be off or on. |
602 | + * The current state of reporting facilities responsible for harvesting wifi and cell id measurements together with location information and sending them off to remote services. Can either be off or on. |
603 | + * The overall state of the engine. Can either be off, on or active. |
604 | + |
605 | +The Service takes this configuration and exposes it to client |
606 | +applications. In addition, mainly for debugging purposes, the set of |
607 | +currently visible satellites (if any) is maintained and exposed to |
608 | +privileged client applications. |
609 | + |
610 | +## Privacy & Access Control |
611 | + |
612 | +Location information is highly privacy relevant. For this reason, the |
613 | +location service is deeply integrated with AppArmor and Ubuntu's |
614 | +overall trust infrastructure. Every incoming session request is |
615 | +validated and if in doubt, the user is asked to explicitly grant trust |
616 | +to the application requesting access to positioning |
617 | +information. Please see [@ref com::ubuntu::location::service::PermissionManager] |
618 | +for further details. |
619 | + |
620 | +In addition, the location service allows for selectively adjusting the |
621 | +accuracy and reporting setup of the location Engine to provide further |
622 | +fine-grained control over the exposed data to user. Within this setup, |
623 | +a user is able to entirely disable all positioning. |
624 | + |
625 | |
626 | === added file 'doc/manual_testing.md' |
627 | --- doc/manual_testing.md 1970-01-01 00:00:00 +0000 |
628 | +++ doc/manual_testing.md 2015-12-09 15:21:10 +0000 |
629 | @@ -0,0 +1,174 @@ |
630 | +# Manual Testplan |
631 | + |
632 | +[TOC] |
633 | + |
634 | +While the automatic test suite of the location service is |
635 | +comprehensive and covers large parts of the functionality of the |
636 | +service itself, we still provide an additional level of acceptance |
637 | +testing covering the entire location stack/experience as a part of |
638 | +this document. |
639 | + |
640 | +## Dependents/Clients |
641 | + |
642 | + - qtubuntu-sensors |
643 | + - Qt/QML applications: |
644 | + - Browser |
645 | + - osmTouch |
646 | + |
647 | +## Test Plan |
648 | + |
649 | +This test plan is not supposed to be complete; use it to guide your |
650 | +manual testing so you don't miss big functional areas that are part of |
651 | +the component; also this should be used as guideline to inspire the |
652 | +exploratory testing which should be adapted smartly based on the real |
653 | +content of a MP. |
654 | + |
655 | +Please note that if you're testing the GPS provider, the location |
656 | +service relies on GPS hardware to obtain a location fix. For that, it |
657 | +might be required that you execute the manual steps listed before |
658 | +close to a window or ideally outside, with good satellite visibility |
659 | +conditions. |
660 | + |
661 | +__Note: It can take up to 15 minutes for the GPS device to get a lock, due to lack of assisted GPS__ |
662 | + |
663 | + - Install latest image on phone |
664 | + - Install freshly built MPs that are needed for landing |
665 | + |
666 | +Depending on the default configuration of location-service on the |
667 | +image, you may skip parts of this test plan. E.g. if GPS hardware is |
668 | +disabled, skip this part. You can see which providers are enabled by |
669 | +looking at the list of providers on the location-serviced command-line |
670 | +(`ps fauxw | grep location-service`, then look at the `--provider` |
671 | +flags). |
672 | + |
673 | +### Dummy provider |
674 | + |
675 | +This tests forces location-service to use only the dummy provider; |
676 | +this providers a baseline test for the app to trust-store to |
677 | +location-service path. |
678 | + |
679 | + - phablet-shell into the phone: |
680 | + - `sudo service ubuntu-location-service stop && sudo /usr/bin/ubuntu-location-serviced --bus system --provider dummy::Provider --dummy::Provider::ReferenceLocationLat=48.857503 --dummy::Provider::ReferenceLocationLon=2.295072` |
681 | + - As phablet, start the trust store again (it stops when location-service is stopped) with: `start ubuntu-location-service-trust-stored` |
682 | + - Ensure that all AP tests for the webbrowser pass as expected |
683 | + - Point the browser to maps.google.com (alternatively: here.com, maps.bing.fr). |
684 | + - Request centering the map on current position and observe if it works correctly (should show the Eiffel tower) |
685 | + - Install osmTouch from the app store |
686 | + - Launch osmTouch and check if it centers on the Eiffel tower. |
687 | + - Install a maps webapp such as HERE or Google Maps webapp from the app store |
688 | + - Launch maps webapp and check if it centers on the Eiffel tower. |
689 | + |
690 | +### GPS Test Plan |
691 | + |
692 | +This applies only if GPS provider is enabled. |
693 | + |
694 | + - (If applicable: Remember to add the silo you are testing) |
695 | + - `sudo apt-get install ubuntu-location-service-tests` |
696 | + - If you want to send off crowdsourced information, i.e., information about visible wifis and visible radio cells for the obtained location fixes to Mozilla's location service and our own instance: |
697 | + - `sudo GLOG_v=40 GLOG_logtostderr=1 GPS_TEST_ENABLE_HARVESTING_DURING_TESTS=1 /usr/bin/uls-tests/gps_provider_test --gtest_filter=*.time_to_first_fix_cold_start_without_supl_benchmark_requires_hardware` |
698 | + - If you '''don't''' want to send off crowdsourced information: |
699 | + - `sudo GLOG_v=40 GLOG_logtostderr=1 /usr/bin/uls-tests/gps_provider_test --gtest_filter=*.time_to_first_fix_cold_start_without_supl_benchmark_requires_hardware` |
700 | + |
701 | + - The test will output a lot of diagnostic information to the |
702 | + terminal and will take ~30 minutes. If satellite visibility is |
703 | + limited, it can take even longer. The test will automatically |
704 | + report success or failure. |
705 | + |
706 | +### Preliminary AGPS Test Plan |
707 | + |
708 | +**Does not apply to Krillin** |
709 | + |
710 | +Please note that the Krillin GPS chipset driver and its integration |
711 | +within Ubuntu does not support vanilla AGPS (i.e., SUPL) right |
712 | +now. For that, this test case is irrelevant for Krillin and is likely |
713 | +to fail. |
714 | + |
715 | +This applied only if GPS provider and some other provider (giving |
716 | +_A_ssistance) are enabled. |
717 | + |
718 | + - Add the silo. |
719 | + - `sudo apt-get install ubuntu-location-service-tests` |
720 | + - Obtain a (rough) location estimate for your current location on Google maps. |
721 | + - Make sure to replace INSERT_ESTIMATE_HERE with the respective |
722 | + values obtained from Google maps. |
723 | + - If you want to send off crowdsourced information, i.e., information |
724 | + about visible wifis and visible radio cells for the obtained |
725 | + location fixes to Mozilla's location service and our own instance: |
726 | + - `sudo GLOG_v=40 GLOG_logtostderr=1 GPS_TEST_ENABLE_HARVESTING_DURING_TESTS=1 GPS_TEST_REF_LAT=INSERT_ESTIMATE_HERE GPS_TEST_REF_LON=INSERT_ESTIMATE_HERE /usr/bin/uls-tests/gps_provider_test --gtest_filter=*.time_to_first_fix_cold_start_with_supl_benchmark_requires_hardware` |
727 | + - If you '''don't''' want to send off crowdsourced information: |
728 | + - `sudo GLOG_v=40 GLOG_logtostderr=1 GPS_TEST_REF_LAT=INSERT_ESTIMATE_HERE GPS_TEST_REF_LON=INSERT_ESTIMATE_HERE /usr/bin/uls-tests/gps_provider_test --gtest_filter=*.time_to_first_fix_cold_start_with_supl_benchmark_requires_hardware` |
729 | + |
730 | + - The test will output a lot of diagnostic information to the |
731 | + terminal and will take ~10 minutes or less. The test will |
732 | + automatically report success or failure. |
733 | + |
734 | +### Espoo / HERE provider |
735 | + |
736 | +This applies only if the Espoo / HERE remote provider is enabled. This |
737 | +provider should be enabled by default and may either work standalone |
738 | +as the only provider or as an assistance for the GPS hardware to lock. |
739 | + |
740 | + - Add the silo; special exception for lxc-android-config: see https://wiki.ubuntu.com/Touch/Testing/lxc-android-config |
741 | + - If noted, deploy an updated custom tarball: |
742 | + - Download the tarball under /tmp ('''NOT''' under /) |
743 | + - Unpack there: `cd /tmp; sudo tar xvf custom-vendor-here-*.tar.xz` |
744 | + - Remove older bits: `sudo rm -rf /custom/vendor/here/` |
745 | + - Update custom bits: `sudo mv /tmp/system/custom/vendor/here /custom/vendor` |
746 | + - Reboot |
747 | + - After boot, check you have these three processes running on top of location-service: |
748 | + - slpgwd |
749 | + - posclientd |
750 | + - ubuntu-espoo-service |
751 | + - Make sure SIM is unlocked and attached to the network (has some reliable signal) and that WiFi is turned on. |
752 | + - Install OSMTouch app |
753 | + - Run OSMTouch app, hit the position button every other second until you get a blue circle showing your current location; |
754 | + |
755 | +# Connectivity API |
756 | + |
757 | +For integration of network-based positioning providers, the location |
758 | +service offers a connectivity API that provides access to wifi and |
759 | +cell measurements as well as information on the current overall |
760 | +connectivity status of the device. Please execute the following |
761 | +commands on a newly flashed device with a writable image: |
762 | + |
763 | + - `sudo apt-get update && sudo apt-get build-dep location-service && sudo apt-get install libubuntu-location-service-dev ubuntu-location-service-examples` |
764 | + - `mkdir /tmp/build && cd /tmp/build && cmake /usr/share/ubuntu-location-service/examples/standalone/connectivity/ && make` |
765 | + - `GLOG_logtostderr=1 ./connectivity` |
766 | + |
767 | +Verify that the output looks similar to: |
768 | + |
769 | + phablet@ubuntu-phablet:/tmp/build$ ./connectivity |
770 | + Is wifi enabled: true |
771 | + Is wifi hw enabled: true |
772 | + Is wwan enabled: false |
773 | + Is wwan hw enabled: true |
774 | + umts(mcc: 262, mnc: 2, lac: 5313, id: 131948771, asu: 7) |
775 | + (bssid: BC:F2:AF:AF:19:A2, ssid: devolo-bcf2afaf19a2, last seen: 1408955086, mode: Mode::infrastructure, frequency: 2462, strength: 72) |
776 | + (bssid: 00:22:3F:35:43:58, ssid: JustAnotherWLAN, last seen: 1408955086, mode: Mode::infrastructure, frequency: 2412, strength: 24) |
777 | + (bssid: 82:C7:A6:40:8C:4E, ssid: EasyBox-44D054, last seen: 1408955206, mode: Mode::infrastructure, frequency: 2417, strength: 17) |
778 | + (bssid: 00:24:01:B8:32:8D, ssid: gra, last seen: 1408955086, mode: Mode::infrastructure, frequency: 2412, strength: 12) |
779 | + (bssid: C0:25:06:3C:28:22, ssid: FRITZ!Box 6360 Cable, last seen: 1408954966, mode: Mode::infrastructure, frequency: 2412, strength: 17) |
780 | + (bssid: 00:1C:4A:A5:B7:59, ssid: FRITZ!Box Fon WLAN 7170, last seen: 1408954966, mode: Mode::infrastructure, frequency: 2437, strength: 10) |
781 | + Last seen changed for wifi (bssid: BC:F2:AF:AF:19:A2, ssid: devolo-bcf2afaf19a2, last seen: 1408955257, mode: Mode::infrastructure, frequency: 2462, strength: 72) |
782 | + Last seen changed for wifi (bssid: 00:22:3F:35:43:58, ssid: JustAnotherWLAN, last seen: 1408955257, mode: Mode::infrastructure, frequency: 2412, strength: 24) |
783 | + Signal strength changed for wifi: (bssid: BC:F2:AF:AF:19:A2, ssid: devolo-bcf2afaf19a2, last seen: 1408955257, mode: Mode::infrastructure, frequency: 2462, strength: 73) |
784 | + |
785 | +# Trust Store Integration |
786 | + |
787 | +Please note that we are assuming a freshly wiped system for testing |
788 | +here. If you cannot fulfill that pre-condition, please run `rm -rf |
789 | +/home/phablet/.local/share/UbuntuLocationService && sudo shutdown -r` prior to running the |
790 | +tests: |
791 | + |
792 | +## Unconfined |
793 | + |
794 | + - Open the browser, go to maps.google.com |
795 | + - Observe the in-browser dialog asking for granting access to location. |
796 | + |
797 | +## Confined Web-App |
798 | + |
799 | + - Open the Nokia Here web app, observe the trust dialog appearing. |
800 | + |
801 | +## Confined Application |
802 | + |
803 | + - Open osmtouch and observe the osmtouch surface sliding up, presenting you with a trust dialog. |
804 | |
805 | === added file 'doc/tips_n_tricks.md' |
806 | --- doc/tips_n_tricks.md 1970-01-01 00:00:00 +0000 |
807 | +++ doc/tips_n_tricks.md 2015-12-09 15:21:10 +0000 |
808 | @@ -0,0 +1,21 @@ |
809 | +# Tips'n'Tricks |
810 | + |
811 | +## Mark HERE license as accepted from cmdline |
812 | + |
813 | + sudo LC_ALL=C gdbus call --system --dest org.freedesktop.Accounts --object-path /org/freedesktop/Accounts/User32011 --method org.freedesktop.DBus.Properties.Set com.ubuntu.location.providers.here.AccountsService LicenseAccepted '<true>' |
814 | + |
815 | +## Force startup after ofono and NM are started |
816 | + |
817 | +This is a *workaround* to get connectivity API to collect; mount your |
818 | +system read-write and edit |
819 | +/etc/init/ubuntu-location-provider-here-slpgwd.conf: |
820 | + |
821 | + sudo mount -o remount,rw / |
822 | + sudo vi /etc/init/ubuntu-location-provider-here-slpgwd.conf |
823 | + |
824 | +change: `start on started dbus and (started ofono or started network-manager)` |
825 | +to: `start on started dbus and started ofono and started network-manager` |
826 | + |
827 | + sudo mount -o remount,ro / |
828 | + sync |
829 | + sudo reboot |
830 | |
831 | === modified file 'src/location_service/com/ubuntu/location/CMakeLists.txt' |
832 | --- src/location_service/com/ubuntu/location/CMakeLists.txt 2015-04-23 14:48:44 +0000 |
833 | +++ src/location_service/com/ubuntu/location/CMakeLists.txt 2015-12-09 15:21:10 +0000 |
834 | @@ -38,6 +38,7 @@ |
835 | service/harvester.cpp |
836 | service/demultiplexing_reporter.h |
837 | service/demultiplexing_reporter.cpp |
838 | + service/runtime.cpp |
839 | service/runtime_tests.h |
840 | service/runtime_tests.cpp |
841 | service/trust_store_permission_manager.cpp |
842 | |
843 | === modified file 'src/location_service/com/ubuntu/location/connectivity/cached_wireless_network.cpp' |
844 | --- src/location_service/com/ubuntu/location/connectivity/cached_wireless_network.cpp 2015-05-28 10:57:24 +0000 |
845 | +++ src/location_service/com/ubuntu/location/connectivity/cached_wireless_network.cpp 2015-12-09 15:21:10 +0000 |
846 | @@ -123,7 +123,14 @@ |
847 | const org::freedesktop::NetworkManager::Device& device, |
848 | const org::freedesktop::NetworkManager::AccessPoint& ap) |
849 | : device_(device), |
850 | - access_point_(ap) |
851 | + access_point_(ap), |
852 | + connections |
853 | + { |
854 | + access_point_.properties_changed->connect([this](const std::map<std::string, core::dbus::types::Variant>& dict) |
855 | + { |
856 | + on_access_point_properties_changed(dict); |
857 | + }) |
858 | + } |
859 | { |
860 | last_seen_ = translate_time_stamp(access_point_.last_seen->get()); |
861 | |
862 | @@ -138,12 +145,11 @@ |
863 | { |
864 | static_cast<int>(access_point_.strength->get()) |
865 | }; |
866 | +} |
867 | |
868 | - // Wire up all the connections |
869 | - access_point_.properties_changed->connect([this](const std::map<std::string, core::dbus::types::Variant>& dict) |
870 | - { |
871 | - on_access_point_properties_changed(dict); |
872 | - }); |
873 | +detail::CachedWirelessNetwork::~CachedWirelessNetwork() |
874 | +{ |
875 | + access_point_.properties_changed->disconnect(connections.ap_properties_changed); |
876 | } |
877 | |
878 | void detail::CachedWirelessNetwork::on_access_point_properties_changed(const std::map<std::string, core::dbus::types::Variant>& dict) |
879 | |
880 | === modified file 'src/location_service/com/ubuntu/location/connectivity/cached_wireless_network.h' |
881 | --- src/location_service/com/ubuntu/location/connectivity/cached_wireless_network.h 2014-08-14 20:25:22 +0000 |
882 | +++ src/location_service/com/ubuntu/location/connectivity/cached_wireless_network.h 2015-12-09 15:21:10 +0000 |
883 | @@ -41,6 +41,8 @@ |
884 | const org::freedesktop::NetworkManager::Device& device, |
885 | const org::freedesktop::NetworkManager::AccessPoint& ap); |
886 | |
887 | + ~CachedWirelessNetwork(); |
888 | + |
889 | // Timestamp when the network became visible. |
890 | const core::Property<std::chrono::system_clock::time_point>& last_seen() const override; |
891 | |
892 | @@ -67,6 +69,16 @@ |
893 | // The actual access point stub. |
894 | org::freedesktop::NetworkManager::AccessPoint access_point_; |
895 | |
896 | + // Encapsulates all event connections that have to be cut on destruction. |
897 | + struct |
898 | + { |
899 | + core::dbus::Signal |
900 | + < |
901 | + org::freedesktop::NetworkManager::AccessPoint::PropertiesChanged, |
902 | + org::freedesktop::NetworkManager::AccessPoint::PropertiesChanged::ArgumentType |
903 | + >::SubscriptionToken ap_properties_changed; |
904 | + } connections; |
905 | + |
906 | core::Property<std::chrono::system_clock::time_point> last_seen_; |
907 | core::Property<std::string> bssid_; |
908 | core::Property<std::string> ssid_; |
909 | |
910 | === modified file 'src/location_service/com/ubuntu/location/connectivity/ofono_nm_connectivity_manager.cpp' |
911 | --- src/location_service/com/ubuntu/location/connectivity/ofono_nm_connectivity_manager.cpp 2015-05-27 18:40:37 +0000 |
912 | +++ src/location_service/com/ubuntu/location/connectivity/ofono_nm_connectivity_manager.cpp 2015-12-09 15:21:10 +0000 |
913 | @@ -595,7 +595,7 @@ |
914 | |
915 | xdg::NetworkManager::AccessPoint ap |
916 | { |
917 | - network_manager->service->add_object_for_path(ap_path) |
918 | + network_manager->service->object_for_path(ap_path) |
919 | }; |
920 | |
921 | auto wifi = std::make_shared<detail::CachedWirelessNetwork>(itd->second, ap); |
922 | |
923 | === modified file 'src/location_service/com/ubuntu/location/engine.cpp' |
924 | --- src/location_service/com/ubuntu/location/engine.cpp 2015-04-23 14:48:44 +0000 |
925 | +++ src/location_service/com/ubuntu/location/engine.cpp 2015-12-09 15:21:10 +0000 |
926 | @@ -169,19 +169,28 @@ |
927 | |
928 | // We wire up changes in the engine's configuration to the respective slots |
929 | // of the provider. |
930 | - auto cp = updates.reference_location.changed().connect([provider](const cul::Update<cul::Position>& pos) |
931 | - { |
932 | - provider->on_reference_location_updated(pos); |
933 | - }); |
934 | - |
935 | - auto cv = updates.reference_velocity.changed().connect([provider](const cul::Update<cul::Velocity>& velocity) |
936 | - { |
937 | - provider->on_reference_velocity_updated(velocity); |
938 | - }); |
939 | - |
940 | - auto ch = updates.reference_heading.changed().connect([provider](const cul::Update<cul::Heading>& heading) |
941 | - { |
942 | - provider->on_reference_heading_updated(heading); |
943 | + auto cp = updates.last_known_location.changed().connect([provider](const cul::Optional<cul::Update<cul::Position>>& pos) |
944 | + { |
945 | + if (pos) |
946 | + { |
947 | + provider->on_reference_location_updated(pos.get()); |
948 | + } |
949 | + }); |
950 | + |
951 | + auto cv = updates.last_known_velocity.changed().connect([provider](const cul::Optional<cul::Update<cul::Velocity>>& velocity) |
952 | + { |
953 | + if (velocity) |
954 | + { |
955 | + provider->on_reference_velocity_updated(velocity.get()); |
956 | + } |
957 | + }); |
958 | + |
959 | + auto ch = updates.last_known_heading.changed().connect([provider](const cul::Optional<cul::Update<cul::Heading>>& heading) |
960 | + { |
961 | + if (heading) |
962 | + { |
963 | + provider->on_reference_heading_updated(heading.get()); |
964 | + } |
965 | }); |
966 | |
967 | auto cr = configuration.wifi_and_cell_id_reporting_state.changed().connect([provider](cul::WifiAndCellIdReportingState state) |
968 | @@ -207,7 +216,7 @@ |
969 | // We should come up with a better heuristic here. |
970 | auto cpr = provider->updates().position.connect([this](const cul::Update<cul::Position>& src) |
971 | { |
972 | - updates.reference_location = update_policy->verify_update(src); |
973 | + updates.last_known_location = update_policy->verify_update(src); |
974 | }); |
975 | |
976 | std::lock_guard<std::mutex> lg(guard); |
977 | |
978 | === modified file 'src/location_service/com/ubuntu/location/engine.h' |
979 | --- src/location_service/com/ubuntu/location/engine.h 2015-04-23 14:48:44 +0000 |
980 | +++ src/location_service/com/ubuntu/location/engine.h 2015-12-09 15:21:10 +0000 |
981 | @@ -127,11 +127,11 @@ |
982 | struct Updates |
983 | { |
984 | /** The current best known reference location */ |
985 | - core::Property<Update<Position>> reference_location{}; |
986 | + core::Property<Optional<Update<Position>>> last_known_location{}; |
987 | /** The current best known velocity estimate. */ |
988 | - core::Property<Update<Velocity>> reference_velocity{}; |
989 | + core::Property<Optional<Update<Velocity>>> last_known_velocity{}; |
990 | /** The current best known heading estimate. */ |
991 | - core::Property<Update<Heading>> reference_heading{}; |
992 | + core::Property<Optional<Update<Heading>>> last_known_heading{}; |
993 | /** The current set of visible SpaceVehicles. */ |
994 | core::Property<std::map<SpaceVehicle::Key, SpaceVehicle>> visible_space_vehicles{}; |
995 | }; |
996 | |
997 | === modified file 'src/location_service/com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.cpp' |
998 | --- src/location_service/com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.cpp 2014-10-27 21:58:16 +0000 |
999 | +++ src/location_service/com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.cpp 2015-12-09 15:21:10 +0000 |
1000 | @@ -66,8 +66,6 @@ |
1001 | if (config.count("XTRA_SERVER_3") > 0) |
1002 | result.xtra_hosts.push_back(config.get<std::string>("XTRA_SERVER_3")); |
1003 | |
1004 | - result.timeout = std::chrono::milliseconds{1500}; |
1005 | - |
1006 | return result; |
1007 | } |
1008 | |
1009 | @@ -333,14 +331,14 @@ |
1010 | } else |
1011 | { |
1012 | auto now = location::Clock::now().time_since_epoch(); |
1013 | - auto thiz = static_cast<android::HardwareAbstractionLayer*>(context); |
1014 | + auto ms_since_epoch = std::chrono::duration_cast<std::chrono::milliseconds>(now); |
1015 | |
1016 | static const int zero_uncertainty = 0; |
1017 | |
1018 | u_hardware_gps_inject_time( |
1019 | thiz->impl.gps_handle, |
1020 | - now.count(), |
1021 | - now.count(), |
1022 | + ms_since_epoch.count(), |
1023 | + ms_since_epoch.count(), |
1024 | zero_uncertainty); |
1025 | } |
1026 | } |
1027 | |
1028 | === modified file 'src/location_service/com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.h' |
1029 | --- src/location_service/com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.h 2015-04-22 13:30:04 +0000 |
1030 | +++ src/location_service/com/ubuntu/location/providers/gps/android_hardware_abstraction_layer.h 2015-12-09 15:21:10 +0000 |
1031 | @@ -49,7 +49,7 @@ |
1032 | /** @brief Timeout on gps xtra download operations. */ |
1033 | std::chrono::milliseconds timeout |
1034 | { |
1035 | - 5000 |
1036 | + 30000 |
1037 | }; |
1038 | |
1039 | /** Set of hosts serving GPS xtra data. */ |
1040 | |
1041 | === modified file 'src/location_service/com/ubuntu/location/service/daemon.cpp' |
1042 | --- src/location_service/com/ubuntu/location/service/daemon.cpp 2015-04-16 10:03:29 +0000 |
1043 | +++ src/location_service/com/ubuntu/location/service/daemon.cpp 2015-12-09 15:21:10 +0000 |
1044 | @@ -20,6 +20,9 @@ |
1045 | #include <com/ubuntu/location/boost_ptree_settings.h> |
1046 | #include <com/ubuntu/location/provider_factory.h> |
1047 | |
1048 | +#include <com/ubuntu/location/logging.h> |
1049 | +#include <com/ubuntu/location/connectivity/dummy_connectivity_manager.h> |
1050 | + |
1051 | #include <com/ubuntu/location/service/default_configuration.h> |
1052 | #include <com/ubuntu/location/service/demultiplexing_reporter.h> |
1053 | #include <com/ubuntu/location/service/ichnaea_reporter.h> |
1054 | @@ -30,6 +33,7 @@ |
1055 | |
1056 | #include "program_options.h" |
1057 | #include "daemon.h" |
1058 | +#include "runtime.h" |
1059 | |
1060 | #include <core/dbus/announcer.h> |
1061 | #include <core/dbus/resolver.h> |
1062 | @@ -37,6 +41,8 @@ |
1063 | |
1064 | #include <core/posix/signal.h> |
1065 | |
1066 | +#include <boost/asio.hpp> |
1067 | + |
1068 | #include <system_error> |
1069 | #include <thread> |
1070 | |
1071 | @@ -175,6 +181,8 @@ |
1072 | trap->stop(); |
1073 | }); |
1074 | |
1075 | + auto runtime = location::service::Runtime::create(4); |
1076 | + |
1077 | const location::Configuration empty_provider_configuration; |
1078 | |
1079 | std::set<location::Provider::Ptr> instantiated_providers; |
1080 | @@ -201,8 +209,10 @@ |
1081 | } |
1082 | } |
1083 | |
1084 | - config.incoming->install_executor(dbus::asio::make_executor(config.incoming)); |
1085 | - config.outgoing->install_executor(dbus::asio::make_executor(config.outgoing)); |
1086 | + config.incoming->install_executor(dbus::asio::make_executor(config.incoming, runtime->service())); |
1087 | + config.outgoing->install_executor(dbus::asio::make_executor(config.outgoing, runtime->service())); |
1088 | + |
1089 | + runtime->start(); |
1090 | |
1091 | location::service::DefaultConfiguration dc; |
1092 | |
1093 | @@ -214,77 +224,15 @@ |
1094 | dc.the_permission_manager(config.outgoing), |
1095 | location::service::Harvester::Configuration |
1096 | { |
1097 | - location::connectivity::platform_default_manager(), |
1098 | - // We submit location/wifi/cell measurements to both |
1099 | - // Mozilla's location service and to Ubuntu's own instance. |
1100 | - std::make_shared<service::DemultiplexingReporter>( |
1101 | - std::initializer_list<service::Harvester::Reporter::Ptr> |
1102 | - { |
1103 | - std::make_shared<service::ichnaea::Reporter>( |
1104 | - service::ichnaea::Reporter::Configuration |
1105 | - { |
1106 | - "https://location.services.mozilla.com", |
1107 | - "UbuntuLocationService", |
1108 | - "UbuntuLocationService" |
1109 | - } |
1110 | - ), |
1111 | - std::make_shared<service::ichnaea::Reporter>( |
1112 | - service::ichnaea::Reporter::Configuration |
1113 | - { |
1114 | - "https://162.213.35.107", |
1115 | - "UbuntuLocationService", |
1116 | - "UbuntuLocationService" |
1117 | - } |
1118 | - ) |
1119 | - }) |
1120 | + std::make_shared<dummy::ConnectivityManager>(), |
1121 | + std::make_shared<NullReporter>() |
1122 | } |
1123 | }; |
1124 | |
1125 | auto location_service = std::make_shared<location::service::Implementation>(configuration); |
1126 | - // We need to ensure that any exception raised by the executor does not crash the app |
1127 | - // and also gets logged. |
1128 | - auto execute = [] (std::shared_ptr<core::dbus::Bus> bus) { |
1129 | - while(true) |
1130 | - { |
1131 | - try |
1132 | - { |
1133 | - VLOG(10) << "Starting a bus executor"; |
1134 | - bus->run(); |
1135 | - break; // run() exited normally |
1136 | - } |
1137 | - catch (const std::exception& e) |
1138 | - { |
1139 | - LOG(WARNING) << e.what(); |
1140 | - } |
1141 | - catch (...) |
1142 | - { |
1143 | - LOG(WARNING) << "Unexpected exception was raised by the bus executor"; |
1144 | - } |
1145 | - } |
1146 | - }; |
1147 | - |
1148 | - std::thread t1{execute, config.incoming}; |
1149 | - std::thread t2{execute, config.incoming}; |
1150 | - std::thread t3{execute, config.incoming}; |
1151 | - std::thread t4{execute, config.outgoing}; |
1152 | |
1153 | trap->run(); |
1154 | |
1155 | - config.incoming->stop(); |
1156 | - config.outgoing->stop(); |
1157 | - |
1158 | - if (t1.joinable()) |
1159 | - t1.join(); |
1160 | - |
1161 | - if (t2.joinable()) |
1162 | - t2.join(); |
1163 | - |
1164 | - if (t3.joinable()) |
1165 | - t3.join(); |
1166 | - |
1167 | - if (t4.joinable()) |
1168 | - t4.join(); |
1169 | - |
1170 | return EXIT_SUCCESS; |
1171 | } |
1172 | |
1173 | |
1174 | === modified file 'src/location_service/com/ubuntu/location/service/implementation.cpp' |
1175 | --- src/location_service/com/ubuntu/location/service/implementation.cpp 2014-08-13 13:08:22 +0000 |
1176 | +++ src/location_service/com/ubuntu/location/service/implementation.cpp 2015-12-09 15:21:10 +0000 |
1177 | @@ -113,10 +113,13 @@ |
1178 | { |
1179 | visible_space_vehicles() = svs; |
1180 | }), |
1181 | - configuration.engine->updates.reference_location.changed().connect( |
1182 | - [this](const cul::Update<cul::Position>& update) |
1183 | + configuration.engine->updates.last_known_location.changed().connect( |
1184 | + [this](const cul::Optional<cul::Update<cul::Position>>& update) |
1185 | { |
1186 | - harvester.report_position_update(update); |
1187 | + if (update) |
1188 | + { |
1189 | + harvester.report_position_update(update.get()); |
1190 | + } |
1191 | }) |
1192 | } |
1193 | { |
1194 | @@ -149,5 +152,23 @@ |
1195 | new ProxyProvider{provider_selection} |
1196 | }; |
1197 | |
1198 | - return session::Interface::Ptr{new culs::session::Implementation(proxy_provider)}; |
1199 | + session::Interface::Ptr session_iface{new session::Implementation(proxy_provider)}; |
1200 | + std::weak_ptr<session::Interface> session_weak{session_iface}; |
1201 | + session_iface->updates().position_status.changed().connect([this, session_weak](const session::Interface::Updates::Status& status) |
1202 | + { |
1203 | + cul::Optional<cul::Update<cul::Position>> last_known_position = configuration.engine->updates.last_known_location.get(); |
1204 | + bool has_last_known_position = last_known_position ? true : false; |
1205 | + bool is_session_enabled = status == culs::session::Interface::Updates::Status::enabled; |
1206 | + bool is_session_on_or_active = configuration.engine->configuration.engine_state != Engine::Status::off; |
1207 | + |
1208 | + if (has_last_known_position && is_session_enabled && is_session_on_or_active) |
1209 | + { |
1210 | + // Immediately send the last known position to the client |
1211 | + if (auto session_iface = session_weak.lock()) |
1212 | + { |
1213 | + session_iface->updates().position = last_known_position.get(); |
1214 | + } |
1215 | + } |
1216 | + }); |
1217 | + return session_iface; |
1218 | } |
1219 | |
1220 | === modified file 'src/location_service/com/ubuntu/location/service/provider_daemon.cpp' |
1221 | --- src/location_service/com/ubuntu/location/service/provider_daemon.cpp 2014-10-27 21:58:16 +0000 |
1222 | +++ src/location_service/com/ubuntu/location/service/provider_daemon.cpp 2015-12-09 15:21:10 +0000 |
1223 | @@ -25,6 +25,7 @@ |
1224 | |
1225 | #include <com/ubuntu/location/service/configuration.h> |
1226 | #include <com/ubuntu/location/service/program_options.h> |
1227 | +#include <com/ubuntu/location/service/runtime.h> |
1228 | |
1229 | #include <core/dbus/asio/executor.h> |
1230 | |
1231 | @@ -65,7 +66,6 @@ |
1232 | location::service::ProviderDaemon::Configuration result; |
1233 | |
1234 | result.connection = factory(mutable_daemon_options().bus()); |
1235 | - result.connection->install_executor(core::dbus::asio::make_executor(result.connection)); |
1236 | |
1237 | auto service = core::dbus::Service::add_service( |
1238 | result.connection, |
1239 | @@ -108,7 +108,15 @@ |
1240 | return result; |
1241 | } |
1242 | |
1243 | -int location::service::ProviderDaemon::main(const location::service::ProviderDaemon::Configuration& configuration) |
1244 | +namespace |
1245 | +{ |
1246 | +std::shared_ptr<location::service::Runtime> runtime() |
1247 | +{ |
1248 | + static const auto inst = location::service::Runtime::create(2); |
1249 | + return inst; |
1250 | +} |
1251 | +} |
1252 | +int location::service::ProviderDaemon::main(const location::service::ProviderDaemon::Configuration& config) |
1253 | { |
1254 | auto trap = core::posix::trap_signals_for_all_subsequent_threads( |
1255 | { |
1256 | @@ -121,27 +129,20 @@ |
1257 | trap->stop(); |
1258 | }); |
1259 | |
1260 | - std::thread worker |
1261 | - { |
1262 | - [configuration]() |
1263 | - { |
1264 | - configuration.connection->run(); |
1265 | - } |
1266 | - }; |
1267 | + config.connection->install_executor(core::dbus::asio::make_executor(config.connection, runtime()->service())); |
1268 | |
1269 | auto skeleton = location::providers::remote::skeleton::create_with_configuration(location::providers::remote::skeleton::Configuration |
1270 | { |
1271 | - configuration.object, |
1272 | - configuration.connection, |
1273 | - configuration.provider |
1274 | + config.object, |
1275 | + config.connection, |
1276 | + config.provider |
1277 | }); |
1278 | |
1279 | + runtime()->start(); |
1280 | + |
1281 | trap->run(); |
1282 | |
1283 | - configuration.connection->stop(); |
1284 | - |
1285 | - if (worker.joinable()) |
1286 | - worker.join(); |
1287 | + config.connection->stop(); |
1288 | |
1289 | return EXIT_SUCCESS; |
1290 | } |
1291 | |
1292 | === added file 'src/location_service/com/ubuntu/location/service/runtime.cpp' |
1293 | --- src/location_service/com/ubuntu/location/service/runtime.cpp 1970-01-01 00:00:00 +0000 |
1294 | +++ src/location_service/com/ubuntu/location/service/runtime.cpp 2015-12-09 15:21:10 +0000 |
1295 | @@ -0,0 +1,109 @@ |
1296 | +/* |
1297 | + * Copyright © 2015 Canonical Ltd. |
1298 | + * |
1299 | + * This program is free software: you can redistribute it and/or modify it |
1300 | + * under the terms of the GNU Lesser General Public License version 3, |
1301 | + * as published by the Free Software Foundation. |
1302 | + * |
1303 | + * This program is distributed in the hope that it will be useful, |
1304 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1305 | + * MERCHANTABILITY or FITNESS FOR A PARTIlocationAR PURPOSE. See the |
1306 | + * GNU Lesser General Public License for more details. |
1307 | + * |
1308 | + * You should have received a copy of the GNU Lesser General Public License |
1309 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1310 | + * |
1311 | + * Authored by: Thomas Voß <thomas.voss@canonical.com> |
1312 | + */ |
1313 | +#include <com/ubuntu/location/service/runtime.h> |
1314 | + |
1315 | +#include <com/ubuntu/location/logging.h> |
1316 | + |
1317 | +namespace culs = com::ubuntu::location::service; |
1318 | + |
1319 | +namespace |
1320 | +{ |
1321 | +// exception_safe_run runs service, catching all exceptions and |
1322 | +// restarting operation until an explicit shutdown has been requested. |
1323 | +// |
1324 | +// TODO(tvoss): Catching all exceptions is risky as they might signal unrecoverable |
1325 | +// errors. We should enable calling code to decide whether an exception should be considered |
1326 | +// fatal or not. |
1327 | +void exception_safe_run(boost::asio::io_service& service) |
1328 | +{ |
1329 | + while (true) |
1330 | + { |
1331 | + try |
1332 | + { |
1333 | + service.run(); |
1334 | + // a clean return from run only happens in case of |
1335 | + // stop() being called (we are keeping the service alive with |
1336 | + // a service::work instance). |
1337 | + break; |
1338 | + } |
1339 | + catch (const std::exception& e) |
1340 | + { |
1341 | + LOG(WARNING) << e.what(); |
1342 | + } |
1343 | + catch (...) |
1344 | + { |
1345 | + LOG(WARNING) << "Unknown exception caught while executing boost::asio::io_service"; |
1346 | + } |
1347 | + } |
1348 | +} |
1349 | +} |
1350 | + |
1351 | +std::shared_ptr<culs::Runtime> culs::Runtime::create(std::uint32_t pool_size) |
1352 | +{ |
1353 | + return std::shared_ptr<culs::Runtime>(new culs::Runtime(pool_size)); |
1354 | +} |
1355 | + |
1356 | +culs::Runtime::Runtime(std::uint32_t pool_size) |
1357 | + : pool_size_{pool_size}, |
1358 | + service_{pool_size_}, |
1359 | + strand_{service_}, |
1360 | + keep_alive_{service_} |
1361 | +{ |
1362 | +} |
1363 | + |
1364 | +culs::Runtime::~Runtime() |
1365 | +{ |
1366 | + try |
1367 | + { |
1368 | + stop(); |
1369 | + } catch(...) |
1370 | + { |
1371 | + // Dropping all exceptions to satisfy the nothrow guarantee. |
1372 | + } |
1373 | +} |
1374 | + |
1375 | +void culs::Runtime::start() |
1376 | +{ |
1377 | + for (unsigned int i = 0; i < pool_size_; i++) |
1378 | + workers_.push_back(std::thread{exception_safe_run, std::ref(service_)}); |
1379 | +} |
1380 | + |
1381 | +void culs::Runtime::stop() |
1382 | +{ |
1383 | + service_.stop(); |
1384 | + |
1385 | + for (auto& worker : workers_) |
1386 | + if (worker.joinable()) |
1387 | + worker.join(); |
1388 | +} |
1389 | + |
1390 | +std::function<void(std::function<void()>)> culs::Runtime::to_dispatcher_functional() |
1391 | +{ |
1392 | + // We have to make sure that we stay alive for as long as |
1393 | + // calling code requires the dispatcher to work. |
1394 | + auto sp = shared_from_this(); |
1395 | + return [sp](std::function<void()> task) |
1396 | + { |
1397 | + sp->strand_.post(task); |
1398 | + }; |
1399 | +} |
1400 | + |
1401 | +boost::asio::io_service& culs::Runtime::service() |
1402 | +{ |
1403 | + return service_; |
1404 | +} |
1405 | |
1406 | === added file 'src/location_service/com/ubuntu/location/service/runtime.h' |
1407 | --- src/location_service/com/ubuntu/location/service/runtime.h 1970-01-01 00:00:00 +0000 |
1408 | +++ src/location_service/com/ubuntu/location/service/runtime.h 2015-12-09 15:21:10 +0000 |
1409 | @@ -0,0 +1,90 @@ |
1410 | +/* |
1411 | + * Copyright © 2015 Canonical Ltd. |
1412 | + * |
1413 | + * This program is free software: you can redistribute it and/or modify it |
1414 | + * under the terms of the GNU Lesser General Public License version 3, |
1415 | + * as published by the Free Software Foundation. |
1416 | + * |
1417 | + * This program is distributed in the hope that it will be useful, |
1418 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1419 | + * MERCHANTABILITY or FITNESS FOR A PARTIlocationAR PURPOSE. See the |
1420 | + * GNU Lesser General Public License for more details. |
1421 | + * |
1422 | + * You should have received a copy of the GNU Lesser General Public License |
1423 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1424 | + * |
1425 | + * Authored by: Thomas Voß <thomas.voss@canonical.com> |
1426 | + */ |
1427 | +#ifndef COM_UBUNTU_LOCATION_SERVICE_RUNTIME_H_ |
1428 | +#define COM_UBUNTU_LOCATION_SERVICE_RUNTIME_H_ |
1429 | + |
1430 | +#include <boost/asio.hpp> |
1431 | + |
1432 | +#include <functional> |
1433 | +#include <memory> |
1434 | +#include <thread> |
1435 | +#include <vector> |
1436 | + |
1437 | +#include <cstdint> |
1438 | + |
1439 | +namespace com |
1440 | +{ |
1441 | +namespace ubuntu |
1442 | +{ |
1443 | +namespace location |
1444 | +{ |
1445 | +namespace service |
1446 | +{ |
1447 | +// We bundle our "global" runtime dependencies here, specifically |
1448 | +// a dispatcher to decouple multiple in-process providers from one |
1449 | +// another , forcing execution to a well known set of threads. |
1450 | +class Runtime : public std::enable_shared_from_this<Runtime> |
1451 | +{ |
1452 | +public: |
1453 | + // Our default concurrency setup. |
1454 | + static constexpr const std::uint32_t worker_threads = 2; |
1455 | + |
1456 | + // create returns a Runtime instance with pool_size worker threads |
1457 | + // executing the underlying service. |
1458 | + static std::shared_ptr<Runtime> create(std::uint32_t pool_size = worker_threads); |
1459 | + |
1460 | + Runtime(const Runtime&) = delete; |
1461 | + Runtime(Runtime&&) = delete; |
1462 | + // Tears down the runtime, stopping all worker threads. |
1463 | + ~Runtime() noexcept(true); |
1464 | + Runtime& operator=(const Runtime&) = delete; |
1465 | + Runtime& operator=(Runtime&&) = delete; |
1466 | + |
1467 | + // start executes the underlying io_service on a thread pool with |
1468 | + // the size configured at creation time. |
1469 | + void start(); |
1470 | + |
1471 | + // stop cleanly shuts down a Runtime instance, |
1472 | + // joining all worker threads. |
1473 | + void stop(); |
1474 | + |
1475 | + // to_dispatcher_functional returns a function for integration |
1476 | + // with components that expect a dispatcher for operation. |
1477 | + std::function<void(std::function<void()>)> to_dispatcher_functional(); |
1478 | + |
1479 | + // service returns the underlying boost::asio::io_service that is executed |
1480 | + // by the Runtime. |
1481 | + boost::asio::io_service& service(); |
1482 | + |
1483 | +private: |
1484 | + // Runtime constructs a new instance, firing up pool_size |
1485 | + // worker threads. |
1486 | + Runtime(std::uint32_t pool_size); |
1487 | + |
1488 | + std::uint32_t pool_size_; |
1489 | + boost::asio::io_service service_; |
1490 | + boost::asio::io_service::strand strand_; |
1491 | + boost::asio::io_service::work keep_alive_; |
1492 | + std::vector<std::thread> workers_; |
1493 | +}; |
1494 | +} |
1495 | +} |
1496 | +} |
1497 | +} |
1498 | + |
1499 | +#endif // COM_UBUNTU_LOCATION_SERVICE_RUNTIME_H_ |
1500 | |
1501 | === modified file 'src/location_service/com/ubuntu/location/service/session/skeleton.cpp' |
1502 | --- src/location_service/com/ubuntu/location/service/session/skeleton.cpp 2014-08-14 20:31:09 +0000 |
1503 | +++ src/location_service/com/ubuntu/location/service/session/skeleton.cpp 2015-12-09 15:21:10 +0000 |
1504 | @@ -283,7 +283,13 @@ |
1505 | VLOG(10) << __PRETTY_FUNCTION__; |
1506 | try |
1507 | { |
1508 | - configuration.remote.object->invoke_method_asynchronously<culs::session::Interface::UpdatePosition, void>(position); |
1509 | + configuration.remote.object->invoke_method_asynchronously_with_callback<culs::session::Interface::UpdatePosition, void>([](const core::dbus::Result<void>& result) |
1510 | + { |
1511 | + if (result.is_error()) |
1512 | + { |
1513 | + LOG(INFO) << "Failed to communicate position update to client: " << result.error().print(); |
1514 | + } |
1515 | + }, position); |
1516 | } catch(const std::exception&) |
1517 | { |
1518 | // We consider the session to be dead once we hit an exception here. |
1519 | @@ -300,7 +306,13 @@ |
1520 | VLOG(10) << __PRETTY_FUNCTION__; |
1521 | try |
1522 | { |
1523 | - configuration.remote.object->invoke_method_asynchronously<culs::session::Interface::UpdateHeading, void>(heading); |
1524 | + configuration.remote.object->invoke_method_asynchronously_with_callback<culs::session::Interface::UpdateHeading, void>([](const core::dbus::Result<void>& result) |
1525 | + { |
1526 | + if (result.is_error()) |
1527 | + { |
1528 | + LOG(INFO) << "Failed to communicate position update to client: " << result.error().print(); |
1529 | + } |
1530 | + }, heading); |
1531 | } catch(const std::exception&) |
1532 | { |
1533 | // We consider the session to be dead once we hit an exception here. |
1534 | @@ -317,7 +329,13 @@ |
1535 | VLOG(10) << __PRETTY_FUNCTION__; |
1536 | try |
1537 | { |
1538 | - configuration.remote.object->invoke_method_asynchronously<culs::session::Interface::UpdateVelocity, void>(velocity); |
1539 | + configuration.remote.object->invoke_method_asynchronously_with_callback<culs::session::Interface::UpdateVelocity, void>([](const core::dbus::Result<void>& result) |
1540 | + { |
1541 | + if (result.is_error()) |
1542 | + { |
1543 | + LOG(INFO) << "Failed to communicate position update to client: " << result.error().print(); |
1544 | + } |
1545 | + }, velocity); |
1546 | } catch(const std::exception&) |
1547 | { |
1548 | // We consider the session to be dead once we hit an exception here. |
1549 | |
1550 | === modified file 'src/location_service/com/ubuntu/location/time_based_update_policy.cpp' |
1551 | --- src/location_service/com/ubuntu/location/time_based_update_policy.cpp 2015-04-23 21:30:04 +0000 |
1552 | +++ src/location_service/com/ubuntu/location/time_based_update_policy.cpp 2015-12-09 15:21:10 +0000 |
1553 | @@ -53,8 +53,9 @@ |
1554 | { |
1555 | // if the update has happened within a reasonable amount of time we will just use it if it is more accurate |
1556 | // that the previous one. |
1557 | - use_new_update = last_position_update.value.accuracy.horizontal && update.value.accuracy.horizontal |
1558 | - && *last_position_update.value.accuracy.horizontal >= *update.value.accuracy.horizontal; |
1559 | + use_new_update = !last_position_update.value.accuracy.horizontal || |
1560 | + (update.value.accuracy.horizontal |
1561 | + && *last_position_update.value.accuracy.horizontal >= *update.value.accuracy.horizontal); |
1562 | } |
1563 | |
1564 | if (use_new_update) |
1565 | @@ -118,4 +119,4 @@ |
1566 | |
1567 | } |
1568 | } |
1569 | -} |
1570 | \ No newline at end of file |
1571 | +} |
1572 | |
1573 | === modified file 'tests/CMakeLists.txt' |
1574 | --- tests/CMakeLists.txt 2015-04-23 17:04:09 +0000 |
1575 | +++ tests/CMakeLists.txt 2015-12-09 15:21:10 +0000 |
1576 | @@ -92,6 +92,7 @@ |
1577 | LOCATION_SERVICE_ADD_TEST(provider_test provider_test.cpp) |
1578 | LOCATION_SERVICE_ADD_TEST(wgs84_test wgs84_test.cpp) |
1579 | LOCATION_SERVICE_ADD_TEST(trust_store_permission_manager_test trust_store_permission_manager_test.cpp) |
1580 | +LOCATION_SERVICE_ADD_TEST(runtime_test runtime_test.cpp) |
1581 | |
1582 | # Provider-specific test-cases go here. |
1583 | if (LOCATION_SERVICE_ENABLE_GPS_PROVIDER) |
1584 | |
1585 | === modified file 'tests/acceptance_tests.cpp' |
1586 | --- tests/acceptance_tests.cpp 2015-02-13 13:19:18 +0000 |
1587 | +++ tests/acceptance_tests.cpp 2015-12-09 15:21:10 +0000 |
1588 | @@ -38,12 +38,14 @@ |
1589 | #include <com/ubuntu/location/service/stub.h> |
1590 | |
1591 | #include <core/dbus/announcer.h> |
1592 | +#include <core/dbus/bus.h> |
1593 | #include <core/dbus/fixture.h> |
1594 | #include <core/dbus/resolver.h> |
1595 | |
1596 | #include <core/dbus/asio/executor.h> |
1597 | |
1598 | #include <core/posix/signal.h> |
1599 | +#include <core/posix/this_process.h> |
1600 | |
1601 | #include <core/testing/cross_process_sync.h> |
1602 | #include <core/testing/fork_and_run.h> |
1603 | @@ -663,6 +665,110 @@ |
1604 | EXPECT_EQ(core::testing::ForkAndRunResult::empty, core::testing::fork_and_run(server, client)); |
1605 | } |
1606 | |
1607 | +TEST_F(LocationServiceStandalone, NewSessionsGetLastKnownPosition) |
1608 | +{ |
1609 | + core::testing::CrossProcessSync sync_start; |
1610 | + |
1611 | + auto server = [this, &sync_start]() |
1612 | + { |
1613 | + SCOPED_TRACE("Server"); |
1614 | + |
1615 | + auto trap = core::posix::trap_signals_for_all_subsequent_threads({core::posix::Signal::sig_term}); |
1616 | + trap->signal_raised().connect([trap](core::posix::Signal) |
1617 | + { |
1618 | + trap->stop(); |
1619 | + }); |
1620 | + |
1621 | + auto incoming = session_bus(); |
1622 | + auto outgoing = session_bus(); |
1623 | + |
1624 | + incoming->install_executor(core::dbus::asio::make_executor(incoming)); |
1625 | + outgoing->install_executor(core::dbus::asio::make_executor(outgoing)); |
1626 | + |
1627 | + auto dummy = new DummyProvider(); |
1628 | + cul::Provider::Ptr helper(dummy); |
1629 | + |
1630 | + cul::service::DefaultConfiguration config; |
1631 | + cul::service::Implementation::Configuration configuration |
1632 | + { |
1633 | + incoming, |
1634 | + outgoing, |
1635 | + config.the_engine(config.the_provider_set(helper), config.the_provider_selection_policy(), null_settings()), |
1636 | + config.the_permission_manager(incoming), |
1637 | + cul::service::Harvester::Configuration |
1638 | + { |
1639 | + cul::connectivity::platform_default_manager(), |
1640 | + std::make_shared<NullReporter>() |
1641 | + } |
1642 | + }; |
1643 | + auto location_service = std::make_shared<cul::service::Implementation>(configuration); |
1644 | + |
1645 | + configuration.engine->updates.last_known_location.set(reference_position_update); |
1646 | + std::thread t1{[incoming](){incoming->run();}}; |
1647 | + std::thread t2{[outgoing](){outgoing->run();}}; |
1648 | + |
1649 | + sync_start.try_signal_ready_for(std::chrono::milliseconds{500}); |
1650 | + |
1651 | + trap->run(); |
1652 | + |
1653 | + incoming->stop(); |
1654 | + outgoing->stop(); |
1655 | + |
1656 | + if (t1.joinable()) |
1657 | + t1.join(); |
1658 | + |
1659 | + if (t2.joinable()) |
1660 | + t2.join(); |
1661 | + |
1662 | + return ::testing::Test::HasFailure() ? core::posix::exit::Status::failure : core::posix::exit::Status::success; |
1663 | + }; |
1664 | + |
1665 | + auto client = [this, &sync_start]() |
1666 | + { |
1667 | + SCOPED_TRACE("Client"); |
1668 | + |
1669 | + EXPECT_EQ(1, sync_start.wait_for_signal_ready_for(std::chrono::milliseconds{500})); |
1670 | + |
1671 | + auto bus = session_bus(); |
1672 | + bus->install_executor(dbus::asio::make_executor(bus)); |
1673 | + std::thread t{[bus](){bus->run();}}; |
1674 | + |
1675 | + auto location_service = dbus::resolve_service_on_bus< |
1676 | + cul::service::Interface, |
1677 | + cul::service::Stub>(bus); |
1678 | + |
1679 | + auto s1 = location_service->create_session_for_criteria(cul::Criteria{}); |
1680 | + |
1681 | + std::cout << "Successfully created session" << std::endl; |
1682 | + |
1683 | + cul::Update<cul::Position> position; |
1684 | + auto c1 = s1->updates().position.changed().connect( |
1685 | + [&](const cul::Update<cul::Position>& new_position) { |
1686 | + std::cout << "On position updated: " << new_position << std::endl; |
1687 | + position = new_position; |
1688 | + }); |
1689 | + |
1690 | + std::cout << "Created event connections, starting updates..." << std::endl; |
1691 | + |
1692 | + s1->updates().position_status = culss::Interface::Updates::Status::enabled; |
1693 | + |
1694 | + std::cout << "done" << std::endl; |
1695 | + |
1696 | + std::this_thread::sleep_for(std::chrono::milliseconds{1000}); |
1697 | + |
1698 | + bus->stop(); |
1699 | + |
1700 | + if (t.joinable()) |
1701 | + t.join(); |
1702 | + |
1703 | + EXPECT_EQ(reference_position_update, position); |
1704 | + |
1705 | + return ::testing::Test::HasFailure() ? core::posix::exit::Status::failure : core::posix::exit::Status::success; |
1706 | + }; |
1707 | + |
1708 | + EXPECT_EQ(core::testing::ForkAndRunResult::empty, core::testing::fork_and_run(server, client)); |
1709 | +} |
1710 | + |
1711 | namespace |
1712 | { |
1713 | struct LocationServiceStandaloneLoad : public LocationServiceStandalone |
1714 | @@ -708,7 +814,7 @@ |
1715 | |
1716 | options.add(Keys::update_period, |
1717 | "Update period length for dummy::Provider setup.", |
1718 | - std::uint32_t{100}); |
1719 | + std::uint32_t{10}); |
1720 | |
1721 | options.add(Keys::client_count, |
1722 | "Number of clients that should be fired up.", |
1723 | @@ -761,6 +867,8 @@ |
1724 | }; |
1725 | } |
1726 | |
1727 | +#include "did_finish_successfully.h" |
1728 | + |
1729 | TEST_F(LocationServiceStandaloneLoad, MultipleClientsConnectingAndDisconnectingWorks) |
1730 | { |
1731 | EXPECT_TRUE(trust_store_is_set_up_for_testing); |
1732 | @@ -801,8 +909,8 @@ |
1733 | }; |
1734 | |
1735 | cul::service::Daemon::Configuration config; |
1736 | - config.incoming = session_bus(); |
1737 | - config.outgoing = session_bus(); |
1738 | + config.incoming = std::make_shared<core::dbus::Bus>(core::posix::this_process::env::get_or_throw("DBUS_SESSION_BUS_ADDRESS")); |
1739 | + config.outgoing = std::make_shared<core::dbus::Bus>(core::posix::this_process::env::get_or_throw("DBUS_SESSION_BUS_ADDRESS")); |
1740 | config.is_testing_enabled = false; |
1741 | config.providers = |
1742 | { |
1743 | @@ -829,7 +937,7 @@ |
1744 | status; |
1745 | }, core::posix::StandardStream::empty); |
1746 | |
1747 | - std::this_thread::sleep_for(std::chrono::seconds{2}); |
1748 | + std::this_thread::sleep_for(std::chrono::seconds{15}); |
1749 | |
1750 | auto client = [this]() |
1751 | { |
1752 | @@ -957,17 +1065,11 @@ |
1753 | { |
1754 | VLOG(1) << "Stopping client...: " << client.pid(); |
1755 | client.send_signal_or_throw(core::posix::Signal::sig_term); |
1756 | - auto result = client.wait_for(core::posix::wait::Flags::untraced); |
1757 | - |
1758 | - EXPECT_EQ(core::posix::wait::Result::Status::exited, result.status); |
1759 | - EXPECT_EQ(core::posix::exit::Status::success, result.detail.if_exited.status); |
1760 | + EXPECT_TRUE(did_finish_successfully(client.wait_for(core::posix::wait::Flags::untraced))); |
1761 | } |
1762 | |
1763 | VLOG(1) << "Cleaned up clients, shutting down the service..."; |
1764 | |
1765 | server.send_signal_or_throw(core::posix::Signal::sig_term); |
1766 | - auto result = server.wait_for(core::posix::wait::Flags::untraced); |
1767 | - |
1768 | - EXPECT_EQ(core::posix::wait::Result::Status::exited, result.status); |
1769 | - EXPECT_EQ(core::posix::exit::Status::success, result.detail.if_exited.status); |
1770 | + EXPECT_TRUE(did_finish_successfully(server.wait_for(core::posix::wait::Flags::untraced))); |
1771 | } |
1772 | |
1773 | === modified file 'tests/engine_test.cpp' |
1774 | --- tests/engine_test.cpp 2015-01-21 20:04:56 +0000 |
1775 | +++ tests/engine_test.cpp 2015-12-09 15:21:10 +0000 |
1776 | @@ -154,9 +154,9 @@ |
1777 | EXPECT_CALL(*provider, on_reference_velocity_updated(_)).Times(1); |
1778 | |
1779 | engine.configuration.wifi_and_cell_id_reporting_state = location::WifiAndCellIdReportingState::on; |
1780 | - engine.updates.reference_location = location::Update<location::Position>{}; |
1781 | - engine.updates.reference_heading = location::Update<location::Heading>{}; |
1782 | - engine.updates.reference_velocity = location::Update<location::Velocity>{}; |
1783 | + engine.updates.last_known_location = location::Update<location::Position>{}; |
1784 | + engine.updates.last_known_heading = location::Update<location::Heading>{}; |
1785 | + engine.updates.last_known_velocity = location::Update<location::Velocity>{}; |
1786 | } |
1787 | |
1788 | /* TODO(tvoss): We have to disable these tests as the MP is being refactored to not break ABI. |
1789 | |
1790 | === modified file 'tests/gps_provider_test.cpp' |
1791 | --- tests/gps_provider_test.cpp 2015-01-12 08:41:14 +0000 |
1792 | +++ tests/gps_provider_test.cpp 2015-12-09 15:21:10 +0000 |
1793 | @@ -48,6 +48,31 @@ |
1794 | |
1795 | namespace |
1796 | { |
1797 | + |
1798 | +struct MockHardwareGps |
1799 | +{ |
1800 | + MockHardwareGps() |
1801 | + { |
1802 | + instance_ = this; |
1803 | + } |
1804 | + ~MockHardwareGps() |
1805 | + { |
1806 | + instance_ = nullptr; |
1807 | + } |
1808 | + |
1809 | + MOCK_METHOD5(set_position_mode, bool(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t)); |
1810 | + MOCK_METHOD3(inject_time, void(int64_t, int64_t, int)); |
1811 | + |
1812 | + static MockHardwareGps *mocked(UHardwareGps self) { |
1813 | + return reinterpret_cast<MockHardwareGps*>(self); |
1814 | + } |
1815 | + static MockHardwareGps *instance() { return instance_; } |
1816 | + |
1817 | + static MockHardwareGps *instance_; |
1818 | +}; |
1819 | + |
1820 | +MockHardwareGps *MockHardwareGps::instance_ = nullptr; |
1821 | + |
1822 | struct UpdateTrap |
1823 | { |
1824 | MOCK_METHOD1(on_position_updated, void(const location::Position&)); |
1825 | @@ -211,6 +236,42 @@ |
1826 | |
1827 | } |
1828 | |
1829 | +/* Mock the hardware GPS platform API: the methods defined here will be invoked |
1830 | + * instead of those exported by the system library. |
1831 | + * We redefine these methods using the MockHardwareGps class above, which is |
1832 | + * implemented using google-mock. This effectively allows us to test that the |
1833 | + * right calls to the platform API are made. |
1834 | + */ |
1835 | +UHardwareGps |
1836 | +u_hardware_gps_new(UHardwareGpsParams *) |
1837 | +{ |
1838 | + using namespace ::testing; |
1839 | + |
1840 | + return reinterpret_cast<UHardwareGps>(MockHardwareGps::instance()); |
1841 | +} |
1842 | + |
1843 | +void |
1844 | +u_hardware_gps_delete(UHardwareGps) |
1845 | +{ |
1846 | +} |
1847 | + |
1848 | +bool |
1849 | +u_hardware_gps_set_position_mode(UHardwareGps self, uint32_t mode, uint32_t recurrence, |
1850 | + uint32_t min_interval, uint32_t preferred_accuracy, |
1851 | + uint32_t preferred_time) |
1852 | +{ |
1853 | + MockHardwareGps *thiz = MockHardwareGps::mocked(self); |
1854 | + return thiz->set_position_mode(mode, recurrence, min_interval, |
1855 | + preferred_accuracy, preferred_time); |
1856 | +} |
1857 | + |
1858 | +void |
1859 | +u_hardware_gps_inject_time(UHardwareGps self, int64_t time, int64_t time_reference, int uncertainty) |
1860 | +{ |
1861 | + MockHardwareGps* thiz = MockHardwareGps::mocked(self); |
1862 | + return thiz->inject_time(time, time_reference, uncertainty); |
1863 | +} |
1864 | + |
1865 | TEST(AndroidGpsXtraDownloader, reading_configuration_from_valid_conf_file_works) |
1866 | { |
1867 | std::stringstream ss{gps_conf}; |
1868 | @@ -261,6 +322,28 @@ |
1869 | provider.on_reference_location_updated(pos); |
1870 | } |
1871 | |
1872 | +TEST(GpsProvider, time_requests_inject_current_time_into_the_hal) |
1873 | +{ |
1874 | + using namespace ::testing; |
1875 | + |
1876 | + NiceMock<MockHardwareGps> hardwareGps; |
1877 | + |
1878 | + gps::android::HardwareAbstractionLayer::Configuration configuration; |
1879 | + gps::android::HardwareAbstractionLayer hal(configuration); |
1880 | + std::shared_ptr<gps::HardwareAbstractionLayer> hal_ptr(&hal, [](gps::HardwareAbstractionLayer*){}); |
1881 | + |
1882 | + gps::Provider provider(hal_ptr); |
1883 | + int64_t time = 0; |
1884 | + EXPECT_CALL(hardwareGps, inject_time(_, _, 0)).Times(1).WillOnce(SaveArg<0>(&time)); |
1885 | + |
1886 | + auto t0 = std::chrono::duration_cast<std::chrono::milliseconds>(location::Clock::now().time_since_epoch()); |
1887 | + |
1888 | + gps::android::HardwareAbstractionLayer::on_request_utc_time(&hal); |
1889 | + |
1890 | + auto t1 = std::chrono::duration_cast<std::chrono::milliseconds>(location::Clock::now().time_since_epoch()); |
1891 | + EXPECT_THAT(time, AllOf(Ge(t0.count()), Le(t1.count()))); |
1892 | +} |
1893 | + |
1894 | TEST(GpsProvider, updates_from_hal_are_passed_on_by_the_provider) |
1895 | { |
1896 | using namespace ::testing; |
1897 | |
1898 | === modified file 'tests/position_test.cpp' |
1899 | --- tests/position_test.cpp 2014-06-20 07:40:34 +0000 |
1900 | +++ tests/position_test.cpp 2015-12-09 15:21:10 +0000 |
1901 | @@ -40,7 +40,7 @@ |
1902 | cul::wgs84::Latitude{}, |
1903 | cul::wgs84::Longitude{}, |
1904 | cul::wgs84::Altitude{}}; |
1905 | - EXPECT_TRUE(p.altitude); |
1906 | + EXPECT_TRUE(p.altitude ? true : false); |
1907 | } |
1908 | |
1909 | #include <com/ubuntu/location/codec.h> |
1910 | |
1911 | === added file 'tests/runtime_test.cpp' |
1912 | --- tests/runtime_test.cpp 1970-01-01 00:00:00 +0000 |
1913 | +++ tests/runtime_test.cpp 2015-12-09 15:21:10 +0000 |
1914 | @@ -0,0 +1,118 @@ |
1915 | +/* |
1916 | + * Copyright © 2015Canonical Ltd. |
1917 | + * |
1918 | + * This program is free software: you can redistribute it and/or modify it |
1919 | + * under the terms of the GNU Lesser General Public License version 3, |
1920 | + * as published by the Free Software Foundation. |
1921 | + * |
1922 | + * This program is distributed in the hope that it will be useful, |
1923 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1924 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1925 | + * GNU Lesser General Public License for more details. |
1926 | + * |
1927 | + * You should have received a copy of the GNU Lesser General Public License |
1928 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1929 | + * |
1930 | + * Authored by: Thomas Voß <thomas.voss@canonical.com> |
1931 | + */ |
1932 | +#include <com/ubuntu/location/service/runtime.h> |
1933 | + |
1934 | +#include <gtest/gtest.h> |
1935 | + |
1936 | +#include <condition_variable> |
1937 | +#include <thread> |
1938 | + |
1939 | +namespace culs = com::ubuntu::location::service; |
1940 | + |
1941 | +TEST(Runtime, cleanly_shuts_down_threads) |
1942 | +{ |
1943 | + culs::Runtime::create(); |
1944 | +} |
1945 | + |
1946 | +TEST(Runtime, executes_service) |
1947 | +{ |
1948 | + std::mutex m; |
1949 | + std::unique_lock<std::mutex> ul{m}; |
1950 | + std::condition_variable wc; |
1951 | + |
1952 | + bool signaled = false; |
1953 | + |
1954 | + auto rt = culs::Runtime::create(); |
1955 | + rt->start(); |
1956 | + boost::asio::deadline_timer timer{rt->service(), boost::posix_time::milliseconds(500)}; |
1957 | + timer.async_wait([&wc, &signaled](const boost::system::error_code&) |
1958 | + { |
1959 | + signaled = true; |
1960 | + wc.notify_all(); |
1961 | + }); |
1962 | + |
1963 | + auto result = wc.wait_for(ul, std::chrono::seconds{1}, [&signaled]() { return signaled; }); |
1964 | + EXPECT_TRUE(result); |
1965 | +} |
1966 | + |
1967 | +TEST(Runtime, catches_exceptions_thrown_from_handlers) |
1968 | +{ |
1969 | + std::mutex m; |
1970 | + std::unique_lock<std::mutex> ul{m}; |
1971 | + std::condition_variable wc; |
1972 | + |
1973 | + bool signaled = false; |
1974 | + |
1975 | + auto rt = culs::Runtime::create(); |
1976 | + rt->start(); |
1977 | + boost::asio::deadline_timer fast{rt->service(), boost::posix_time::milliseconds(100)}; |
1978 | + fast.async_wait([](const boost::system::error_code&) |
1979 | + { |
1980 | + throw std::runtime_error{"Should not propagate"}; |
1981 | + }); |
1982 | + |
1983 | + boost::asio::deadline_timer slow{rt->service(), boost::posix_time::milliseconds(500)}; |
1984 | + slow.async_wait([&wc, &signaled](const boost::system::error_code&) |
1985 | + { |
1986 | + signaled = true; |
1987 | + wc.notify_all(); |
1988 | + }); |
1989 | + |
1990 | + auto result = wc.wait_for(ul, std::chrono::seconds{1}, [&signaled]() { return signaled; }); |
1991 | + EXPECT_TRUE(result); |
1992 | +} |
1993 | + |
1994 | +// sets_up_pool_of_threads ensures that the pool size |
1995 | +// passed to the Runtime on construction is honored. The idea is simple: |
1996 | +// We set up two deadline timers, fast and slow. fast fires before slow, |
1997 | +// with fast blocking in a wait on a common condition_variable. When slow |
1998 | +// fires, it notifies the condition variable, thereby unblocking the handler of fast, |
1999 | +// enabling clean shutdown without errors and timeouts. This only works if the |
2000 | +// pool contains at least 2 threads. Otherwise, the handler of slow would not be executed |
2001 | +// until the handler of fast times out in the wait, marking the test as failed. |
2002 | +TEST(Runtime, sets_up_pool_of_threads) |
2003 | +{ |
2004 | + struct State |
2005 | + { |
2006 | + bool signaled{false}; |
2007 | + std::mutex m; |
2008 | + std::condition_variable wc; |
2009 | + }; |
2010 | + |
2011 | + auto state = std::make_shared<State>(); |
2012 | + |
2013 | + auto rt = culs::Runtime::create(2); |
2014 | + rt->start(); |
2015 | + boost::asio::deadline_timer fast{rt->service(), boost::posix_time::milliseconds(100)}; |
2016 | + fast.async_wait([state](const boost::system::error_code&) |
2017 | + { |
2018 | + std::unique_lock<std::mutex> ul{state->m}; |
2019 | + EXPECT_TRUE(state->wc.wait_for(ul, std::chrono::seconds{1}, [state]() { return state->signaled; })); |
2020 | + }); |
2021 | + |
2022 | + boost::asio::deadline_timer slow{rt->service(), boost::posix_time::milliseconds(500)}; |
2023 | + slow.async_wait([state](const boost::system::error_code&) |
2024 | + { |
2025 | + state->signaled = true; |
2026 | + state->wc.notify_all(); |
2027 | + }); |
2028 | + |
2029 | + std::unique_lock<std::mutex> ul{state->m}; |
2030 | + auto result = state->wc.wait_for(ul, std::chrono::seconds{1}, [state]() { return state->signaled; }); |
2031 | + EXPECT_TRUE(result); |
2032 | +} |
2033 | |
2034 | === added directory 'tools' |
2035 | === added file 'tools/CMakeLists.txt' |
2036 | --- tools/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
2037 | +++ tools/CMakeLists.txt 2015-12-09 15:21:10 +0000 |
2038 | @@ -0,0 +1,1 @@ |
2039 | +configure_file(symbol_diff.in symbol_diff) |
2040 | |
2041 | === added file 'tools/symbol_diff.in' |
2042 | --- tools/symbol_diff.in 1970-01-01 00:00:00 +0000 |
2043 | +++ tools/symbol_diff.in 2015-12-09 15:21:10 +0000 |
2044 | @@ -0,0 +1,70 @@ |
2045 | +#! /usr/bin/env python3 |
2046 | + |
2047 | +# |
2048 | +# Copyright (C) 2014 Canonical Ltd |
2049 | +# |
2050 | +# This program is free software: you can redistribute it and/or modify |
2051 | +# it under the terms of the GNU Lesser General Public License version 3 as |
2052 | +# published by the Free Software Foundation. |
2053 | +# |
2054 | +# This program is distributed in the hope that it will be useful, |
2055 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
2056 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2057 | +# GNU Lesser General Public License for more details. |
2058 | +# |
2059 | +# You should have received a copy of the GNU Lesser General Public License |
2060 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
2061 | +# |
2062 | +# Authored by: Michi Henning <michi.henning@canonical.com> |
2063 | +# |
2064 | + |
2065 | +import re |
2066 | +import subprocess |
2067 | + |
2068 | +OLD_FILE = './debian/libubuntu-location-service@UBUNTU_LOCATION_SERVICE_VERSION_MAJOR@.symbols' |
2069 | +NEW_FILE = './debian/libubuntu-location-service@UBUNTU_LOCATION_SERVICE_VERSION_MAJOR@/DEBIAN/symbols' |
2070 | + |
2071 | +def run(): |
2072 | + old_regex = re.compile(r'^ (\(.*\))"(.*)" (.*)$') |
2073 | + |
2074 | + old_syms = {} # Dictionary containing symbol -> ( tag, version ) |
2075 | + with open(OLD_FILE, encoding='utf=8') as file: |
2076 | + file.readline() # Skip first line, which is the library name and version |
2077 | + for line in file: |
2078 | + mo = old_regex.match(line) |
2079 | + if mo: |
2080 | + old_syms[mo.group(2)] = ( mo.group(1), mo.group(3) ) |
2081 | + else: |
2082 | + raise Exception('Invalid input line in ' + OLD_FILE + ': ' + line) |
2083 | + |
2084 | + new_regex = re.compile(r'^ (.*) .+$') |
2085 | + |
2086 | + # Run the new symbols file through "c++filt | sort | uniq". We need |
2087 | + # the sort | uniq because, otherwise, we end up with duplicate demangled symbols. |
2088 | + with open(NEW_FILE) as infile, open('new_symbols', 'w') as outfile: |
2089 | + p = subprocess.Popen(['c++filt | sort | uniq'], shell=True, stdin=infile, stdout=subprocess.PIPE) |
2090 | + |
2091 | + # For each symbol, if it is in the old dictionary, output the tags from the original |
2092 | + # symbol file, followed by the symbol and version. Otherwise, use "(c++)" as the tag |
2093 | + # and add " 0replaceme", so the new symbol will be accepted. |
2094 | + line = p.stdout.readline().decode('utf-8') |
2095 | + outfile.write(line) # Write library name and version |
2096 | + for line in p.stdout: |
2097 | + mo = new_regex.match(line.decode('utf-8')) |
2098 | + if (mo): |
2099 | + sym = mo.group(1) |
2100 | + try: |
2101 | + tag, version = old_syms[sym] |
2102 | + except KeyError: |
2103 | + tag = '(c++)' |
2104 | + version = '0replaceme' |
2105 | + outfile.write(' {}"{}" {}\n'.format(tag, sym, version)) |
2106 | + else: |
2107 | + raise Exception('Cannot parse demangled line: ' + line) |
2108 | + |
2109 | + # Write the diff into /tmp/symbols.diff |
2110 | + with open('/tmp/symbols.diff', 'w') as outfile: |
2111 | + subprocess.call(['diff', '-u', OLD_FILE, 'new_symbols'], stdout=outfile) |
2112 | + |
2113 | +if __name__ == '__main__': |
2114 | + run() |