ubuntu-location-service  ..
An aggregating location service providing positioning and geocoding capabilities to applications.
~16.04.1+0~20190628174500.1~1.gbp660444_doc_daemon_and_cli Service Daemon and CLI

The location service offers a daemon executable and a corresponding command-line interface for interacting with it. The daemon does not necessarily require root privileges, but might so depending on your configuration.

Run the following command to receive an overview of the arguments to the daemon:

ubuntu-location-serviced --help

An example invocation of the daemon, configuring a GPS provider that relies on the Android HAL to talk to the chipset, exposing the service on the system DBus instance:

ubuntu-location-serviced --bus system --provider gps::Provider

The cli allows for querying properties of a running service instance, e.g.:

ubuntu-location-serviced-cli --bus system --get --property is_online

Configuring an Out-Of-Process Provider

If you want to run a provider out of process, the daemon executable allows you to do so by instantiating a so-called remote provider. The following invocation of the service tries to connect to the provider instance described by the given unique DBus name and path.

ubuntu-location-serviced \
  --bus system \
  --provider remote::Provider \
      --remote::Provider::bus=system \
  --remote::Provider::name=com.ubuntu.location.provider.Gps \
  --remote::Provider::path=/

Please note that the service allows for decorating provider names to uniquely identify per provider configuration options and to allow for loading more than one provider of a certain kind. The following configuration configures two remote providers, one relying on GPS (decorated with ) and another one relying on network-based positioning (decorated with ):

ubuntu-location-serviced \
  --bus system \
  --provider remote::Provider@gps \
      --remote::Provider@gps::bus=system \
  --remote::Provider@gps::name=com.ubuntu.location.provider.Gps \
  --remote::Provider@gps::path=/ \
  --provider remote::Provider@network \
      --remote::Provider@network::bus=system \
  --remote::Provider@network::name=com.ubuntu.location.provider.Network \
  --remote::Provider@network::path=/

Location not working? Here's how to debug.

Layers

Test in OSMTouch (QML app using Qt API) before testing in webapps or webbrowser app. Different results? File a bug where it doesn't work. Same result of no location? Next step.

Check that stack works with dummy provider

Edit /etc/init/ubuntu-location-provider.override to start location-serviced with just the dummy provider; this should work. Doesn't work? File a bug against location-service. Works? Reset config to defaults and try the next thing.

location-service debug

Collect some debug data by editing /etc/init/ubuntu-location-service.override and changing the start sequence to add some env vars:

export GLOG_v=200

before the exec. Reboot, and start some app. You should have some log files under /var/log/upstart/ubuntu-location-service.log to attach to a bug report; e.g. a working log looks like this:

WARNING: Logging before InitGoogleLogging() is written to STDERR
I1105 16:30:10.221474  1620 provider.cpp:568] StartPositionUpdates
I1105 16:30:10.224901  1620 provider.cpp:122] Successfully started position updates.
I1105 16:30:10.228739  1620 provider.cpp:596] StartVelocityUpdates
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)

No position there? check connectivity API works by running:

cd /tmp
wget http://people.ubuntu.com/~lool/connectivity
GLOG_v=200 GLOG_logtostderr=1 ./connectivity

you should see something like:

I1105 16:47:26.431466 11140 cached_radio_cell.cpp:160] (mcc: 123, mnc: 2, lac: 1234, id: 123456, asu: 1)
I1105 16:47:26.533818 11140 connectivity.cpp:47] Is wifi enabled: true
I1105 16:47:26.533963 11140 connectivity.cpp:48] Is wifi hw enabled: true
I1105 16:47:26.534010 11140 connectivity.cpp:49] Is wwan enabled: true
I1105 16:47:26.534050 11140 connectivity.cpp:50] Is wwan hw enabled: true
I1105 16:47:26.534442 11140 connectivity.cpp:122] umts(mcc: 123, mnc: 2, lac: 1234, id: 123456, asu: 1)
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)
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)

Also, please attach output of /usr/share/ofono/scripts/list-modems > list-modems-output.txt Please note that the command might take ~1 minute to complete.

TODO: document dbus-monitor / d-feet capturing of client / system traffic with snooping config.

Building the code

By default, the code is built in release mode. To build a debug version, use

$ mkdir builddebug
$ cd builddebug
$ cmake -DCMAKE_BUILD_TYPE=debug ..
$ make

For a release version, use -DCMAKE_BUILD_TYPE=release

Running the tests

$ make
$ make test

Note that "make test" alone is dangerous because it does not rebuild any tests if either the library or the test files themselves need rebuilding. It's not possible to fix this with cmake because cmake cannot add build dependencies to built-in targets. To make sure that everything is up-to-date, run "make" before running "make test"!

Coverage

To build with the flags for coverage testing enabled and get coverage:

$ mkdir buildcoverage
$ cd buildcoverage
$ cmake -DCMAKE_BUILD_TYPE=coverage
$ make
$ make test
$ make coverage

Unfortunately, it is not possible to get 100% coverage for some files, mainly due to gcc's generation of two destructors for dynamic and non- dynamic instances. For abstract base classes and for classes that prevent stack and static allocation, this causes one of the destructors to be reported as uncovered.

There are also issues with some functions in header files that are incorrectly reported as uncovered due to inlining, as well as the impossibility of covering defensive assert(false) statements, such as an assert in the default branch of a switch, where the switch is meant to handle all possible cases explicitly.

If you run a binary and get lots of warnings about a "merge mismatch for summaries", this is caused by having made changes to the source that add or remove code that was previously run, so the new coverage output cannot sensibly be merged into the old coverage output. You can get rid of this problem by running

$ make clean-coverage

This deletes all the .gcda files, allowing the merge to (sometimes) succeed again. If this doesn't work either, the only remedy is to do a clean build.

If lcov complains about unrecognized lines involving '=====', you can patch geninfo and gcovr as explained here:

https://bugs.launchpad.net/gcovr/+bug/1086695/comments/2

Code style

We use a format tool that fixes a whole lot of issues regarding code style. The formatting changes made by the tool are generally sensible (even though they may not be your personal preference in all cases). If there is a case where the formatting really messes things up, consider re-arranging the code to avoid the problem. The convenience of running the entire code base through the pretty-printer far outweighs any minor glitches with pretty printing, and it means that we get consistent code style for free, rather than endlessly having to watch out for formatting issues during code reviews.

As of clang-format-3.7, you can use

// clang-format off
void    unformatted_code  ;
// clang-format on

to suppress formatting for a section of code.

To format specific files:

${CMAKE_BINARY_DIR}/tools/formatcode x.cpp x.h

If no arguments are provided, formatcode reads stdin and writes stdout, so you can easily pipe code into the tool from within an editor. For example, to reformat the entire file in vi (assuming ${CMAKE_BINARY_DIR}/tools is in your PATH):

1G!Gformatcode

To re-format all source and header files in the tree:

$ make formatcode

Thread and address sanitizer

Set SANITIZER to "thread" or "address" to build with the corresponding sanitizer enabled.

Updating symbols file

To easily spot new/removed/changed symbols in the library, the debian package maintains a .symbols file that lists all exported symbols present in the library .so. If you add new public symbols to the library, it's necessary to refresh the symbols file, otherwise the package will fail to build. The easiest way to do that is using bzr-builddeb:

$ bzr bd -- -us -uc -j8  # Don't sign source package or changes file, 8 compiles in parallel
$ # this will exit with an error if symbols file isn't up-to-date
$ cd ../build-area/location-service-[version]
$ ./obj-[arch]/tools/symbol_diff

This creates a diff of the symbols in /tmp/symbols.diff. (The demangled symbols from the debian build are in ./new_symbols.)

Review any changes in /tmp/symbols.diff. If they are OK:

$ cd -
$ patch -p0 < /tmp/symbols.diff

ABI compliance test

To use this, install abi-compliance-checker package from the archives.

You can use abi-compliance-checker to test whether a particular build is ABI compatible with another build. The tool does some source-level analysis in addition to checking library symbols, so it catches things that are potentially dangerous, but won't be picked up by just looking at the symbol table.

Assume you have built devel in src/devel, and you have a later build in src/mybranch and want to check that mybranch is still compatible. To run the compliance test:

$ cd src
$ abi-compliance-checker -lib libunity-scopes.so -old devel/build/test/abi-compliance/abi.xml -new mybranch/build/test/abi-compliance/abi.xml

The script will take about two minutes to run. Now point your browser at

src/compat_reports/libunity-scopes.so/[version]_to_[version]/compat_report.html

The report provides a nicely layed-out page with all the details.

While the automatic test suite of the location service is comprehensive and covers large parts of the functionality of the service itself, we still provide an additional level of acceptance testing covering the entire location stack/experience as a part of this document.

Dependents/Clients

  • qtubuntu-sensors
  • Qt/QML applications:
    • Browser
    • osmTouch

Test Plan

This test plan is not supposed to be complete; use it to guide your manual testing so you don't miss big functional areas that are part of the component; also this should be used as guideline to inspire the exploratory testing which should be adapted smartly based on the real content of a MP.

Please note that if you're testing the GPS provider, the location service relies on GPS hardware to obtain a location fix. For that, it might be required that you execute the manual steps listed before close to a window or ideally outside, with good satellite visibility conditions.

Note: It can take up to 15 minutes for the GPS device to get a lock, due to lack of assisted GPS

  • Install latest image on phone
  • Install freshly built MPs that are needed for landing

Depending on the default configuration of location-service on the image, you may skip parts of this test plan. E.g. if GPS hardware is disabled, skip this part. You can see which providers are enabled by looking at the list of providers on the location-serviced command-line (ps fauxw | grep location-service, then look at the --provider flags).

Dummy provider

This tests forces location-service to use only the dummy provider; this providers a baseline test for the app to trust-store to location-service path.

  • phablet-shell into the phone:
    • 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
  • As phablet, start the trust store again (it stops when location-service is stopped) with: start ubuntu-location-service-trust-stored
  • Ensure that all AP tests for the webbrowser pass as expected
  • Point the browser to maps.google.com (alternatively: here.com, maps.bing.fr).
  • Request centering the map on current position and observe if it works correctly (should show the Eiffel tower)
  • Install osmTouch from the app store
  • Launch osmTouch and check if it centers on the Eiffel tower.
  • Install a maps webapp such as HERE or Google Maps webapp from the app store
  • Launch maps webapp and check if it centers on the Eiffel tower.

GPS Test Plan

This applies only if GPS provider is enabled.

  • (If applicable: Remember to add the silo you are testing)
  • sudo apt-get install ubuntu-location-service-tests
  • 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:
    • 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
  • If you '''don't''' want to send off crowdsourced information:
    • 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
  • The test will output a lot of diagnostic information to the terminal and will take ~30 minutes. If satellite visibility is limited, it can take even longer. The test will automatically report success or failure.

Preliminary AGPS Test Plan

Does not apply to Krillin

Please note that the Krillin GPS chipset driver and its integration within Ubuntu does not support vanilla AGPS (i.e., SUPL) right now. For that, this test case is irrelevant for Krillin and is likely to fail.

This applied only if GPS provider and some other provider (giving _A_ssistance) are enabled.

  • Add the silo.
  • sudo apt-get install ubuntu-location-service-tests
  • Obtain a (rough) location estimate for your current location on Google maps.
  • Make sure to replace INSERT_ESTIMATE_HERE with the respective values obtained from Google maps.
  • 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:
    • 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
  • If you '''don't''' want to send off crowdsourced information:
    • 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
  • The test will output a lot of diagnostic information to the terminal and will take ~10 minutes or less. The test will automatically report success or failure.

Connectivity API

For integration of network-based positioning providers, the location service offers a connectivity API that provides access to wifi and cell measurements as well as information on the current overall connectivity status of the device. Please execute the following commands on a newly flashed device with a writable image:

  • sudo apt-get update && sudo apt-get build-dep location-service && sudo apt-get install libubuntu-location-service-dev ubuntu-location-service-examples
  • mkdir /tmp/build && cd /tmp/build && cmake /usr/share/ubuntu-location-service/examples/standalone/connectivity/ && make
  • GLOG_logtostderr=1 ./connectivity

Verify that the output looks similar to:

phablet@ubuntu-phablet:/tmp/build$ ./connectivity 
Is wifi enabled: true
Is wifi hw enabled: true
Is wwan enabled: false
Is wwan hw enabled: true
umts(mcc: 262, mnc: 2, lac: 5313, id: 131948771, asu: 7)
(bssid: BC:F2:AF:AF:19:A2, ssid: devolo-bcf2afaf19a2, last seen: 1408955086, mode: Mode::infrastructure, frequency: 2462, strength: 72)
(bssid: 00:22:3F:35:43:58, ssid: JustAnotherWLAN, last seen: 1408955086, mode: Mode::infrastructure, frequency: 2412, strength: 24)
(bssid: 82:C7:A6:40:8C:4E, ssid: EasyBox-44D054, last seen: 1408955206, mode: Mode::infrastructure, frequency: 2417, strength: 17)
(bssid: 00:24:01:B8:32:8D, ssid: gra, last seen: 1408955086, mode: Mode::infrastructure, frequency: 2412, strength: 12)
(bssid: C0:25:06:3C:28:22, ssid: FRITZ!Box 6360 Cable, last seen: 1408954966, mode: Mode::infrastructure, frequency: 2412, strength: 17)
(bssid: 00:1C:4A:A5:B7:59, ssid: FRITZ!Box Fon WLAN 7170, last seen: 1408954966, mode: Mode::infrastructure, frequency: 2437, strength: 10)
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)
Last seen changed for wifi (bssid: 00:22:3F:35:43:58, ssid: JustAnotherWLAN, last seen: 1408955257, mode: Mode::infrastructure, frequency: 2412, strength: 24)
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)

Trust Store Integration

Please note that we are assuming a freshly wiped system for testing here. If you cannot fulfill that pre-condition, please run rm -rf /home/phablet/.local/share/UbuntuLocationService && sudo shutdown -r prior to running the tests:

Unconfined

  • Open the browser, go to maps.google.com
  • Observe the in-browser dialog asking for granting access to location.

Confined Web-App

  • Open the Nokia Here web app, observe the trust dialog appearing.

Confined Application

  • Open osmtouch and observe the osmtouch surface sliding up, presenting you with a trust dialog.

Force startup after ofono and NM are started

This is a workaround to get connectivity API to collect; mount your system read-write and edit /etc/init/ubuntu-location-provider-here-slpgwd.conf:

sudo mount -o remount,rw /
sudo vi /etc/init/ubuntu-location-provider-here-slpgwd.conf

change: start on started dbus and (started ofono or started network-manager) to: start on started dbus and started ofono and started network-manager

sudo mount -o remount,ro /
sync
sudo reboot