Merge lp:~thomas-voss/location-service/fix-settings-not-being-applied into lp:location-service/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
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'
553Binary 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()

Subscribers

People subscribed via source and target branches