Merge lp:~thomas-voss/location-service/introduce-locationd into lp:location-service

Proposed by Thomas Voß
Status: Merged
Approved by: Thomas Voß
Approved revision: 262
Merged at revision: 261
Proposed branch: lp:~thomas-voss/location-service/introduce-locationd
Merge into: lp:location-service
Diff against target: 3200 lines (+2854/-50)
35 files modified
src/location/CMakeLists.txt (+60/-0)
src/location/cmds/list.cpp (+36/-0)
src/location/cmds/list.h (+41/-0)
src/location/cmds/provider.cpp (+83/-0)
src/location/cmds/provider.h (+52/-0)
src/location/cmds/run.cpp (+109/-0)
src/location/cmds/run.h (+55/-0)
src/location/cmds/status.cpp (+69/-0)
src/location/cmds/status.h (+49/-0)
src/location/cmds/test.cpp (+32/-0)
src/location/cmds/test.h (+41/-0)
src/location/daemon.cpp (+54/-0)
src/location/daemon.h (+49/-0)
src/location/daemon_main.cpp (+26/-0)
src/location/dbus/skeleton/service.cpp (+45/-20)
src/location/dbus/skeleton/service.h (+32/-28)
src/location/dummy_service.cpp (+55/-0)
src/location/dummy_service.h (+55/-0)
src/location/permission_manager.h (+73/-0)
src/location/providers/gps/sntp_reference_time_source.cpp (+2/-2)
src/location/runtime.cpp (+107/-0)
src/location/runtime.h (+81/-0)
src/location/runtime_tests.cpp (+185/-0)
src/location/runtime_tests.h (+30/-0)
src/location/service_with_engine.cpp (+129/-0)
src/location/service_with_engine.h (+61/-0)
src/location/session_with_provider.cpp (+111/-0)
src/location/session_with_provider.h (+60/-0)
src/location/trust_store_permission_manager.cpp (+179/-0)
src/location/trust_store_permission_manager.h (+76/-0)
src/location/util/cli.cpp (+301/-0)
src/location/util/cli.h (+387/-0)
src/location/util/do_not_copy_or_move.h (+44/-0)
src/location/util/well_known_bus.cpp (+48/-0)
src/location/util/well_known_bus.h (+37/-0)
To merge this branch: bzr merge lp:~thomas-voss/location-service/introduce-locationd
Reviewer Review Type Date Requested Status
Simon Fels (community) Approve
Thomas Voß Pending
Review via email: mp+298744@code.launchpad.net

Commit message

Introduce locationd, featuring the following cmds:
 - list: list all known provider implementations
 - provider: run a known provider implementation out of process.
 - run: execute locationd.
 - status: query the status of a locationd instance.
 - test: execute runtime tests.

Description of the change

Introduce locationd, featuring the following cmds:
 - list: list all known provider implementations
 - provider: run a known provider implementation out of process.
 - run: execute locationd.
 - status: query the status of a locationd instance.
 - test: execute runtime tests.

To post a comment you must log in.
Revision history for this message
Simon Fels (morphis) wrote :

Very nice. LGTM

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added directory 'build'
=== added directory 'build/src'
=== modified file 'src/location/CMakeLists.txt'
--- src/location/CMakeLists.txt 2016-06-28 11:53:34 +0000
+++ src/location/CMakeLists.txt 2016-06-30 09:21:49 +0000
@@ -39,8 +39,43 @@
3939
40 boost_ptree_settings.cpp40 boost_ptree_settings.cpp
4141
42 daemon.h
43 daemon.cpp
42 service.cpp44 service.cpp
4345
46 dummy_service.h
47 dummy_service.cpp
48
49 permission_manager.h
50 runtime.h
51 runtime.cpp
52 runtime_tests.h
53 runtime_tests.cpp
54 service_with_engine.h
55 service_with_engine.cpp
56 session_with_provider.h
57 session_with_provider.cpp
58
59 trust_store_permission_manager.h
60 trust_store_permission_manager.cpp
61
62 cmds/list.h
63 cmds/list.cpp
64 cmds/provider.h
65 cmds/provider.cpp
66 cmds/run.h
67 cmds/run.cpp
68 cmds/status.h
69 cmds/status.cpp
70 cmds/test.h
71 cmds/test.cpp
72
73 util/cli.h
74 util/cli.cpp
75 util/do_not_copy_or_move.h
76 util/well_known_bus.h
77 util/well_known_bus.cpp
78
44 dbus/skeleton/service.h79 dbus/skeleton/service.h
45 dbus/skeleton/service.cpp80 dbus/skeleton/service.cpp
46 dbus/skeleton/session.h81 dbus/skeleton/session.h
@@ -190,6 +225,12 @@
190 service/daemon_cli_main.cpp225 service/daemon_cli_main.cpp
191)226)
192227
228add_executable(
229 locationd
230
231 daemon_main.cpp
232)
233
193target_link_libraries(234target_link_libraries(
194 ubuntu-location-service-provider-daemon235 ubuntu-location-service-provider-daemon
195236
@@ -244,6 +285,20 @@
244 ${GFlags_LIBRARY}285 ${GFlags_LIBRARY}
245)286)
246287
288target_link_libraries(
289 locationd
290
291 ubuntu-location-service
292
293 ${ENABLED_PROVIDER_TARGETS}
294
295# ${Boost_LIBRARIES}
296# ${DBUS_LIBRARIES}
297# ${DBUS_CPP_LIBRARIES}
298# ${GLog_LIBRARY}
299# ${GFlags_LIBRARY}
300)
301
247install(302install(
248 TARGETS ubuntu-location-service-providerd303 TARGETS ubuntu-location-service-providerd
249 DESTINATION ${CMAKE_INSTALL_BINDIR}304 DESTINATION ${CMAKE_INSTALL_BINDIR}
@@ -258,3 +313,8 @@
258 TARGETS ubuntu-location-serviced-cli313 TARGETS ubuntu-location-serviced-cli
259 DESTINATION ${CMAKE_INSTALL_BINDIR}314 DESTINATION ${CMAKE_INSTALL_BINDIR}
260)315)
316
317install(
318 TARGETS locationd
319 DESTINATION ${CMAKE_INSTALL_BINDIR}
320)
261321
=== added directory 'src/location/cmds'
=== added file 'src/location/cmds/list.cpp'
--- src/location/cmds/list.cpp 1970-01-01 00:00:00 +0000
+++ src/location/cmds/list.cpp 2016-06-30 09:21:49 +0000
@@ -0,0 +1,36 @@
1/*
2 * Copyright (C) 2016 Canonical, Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Thomas Voß <thomas.voss@canonical.com>
17 *
18 */
19
20#include <location/cmds/list.h>
21#include <location/provider_factory.h>
22
23namespace cli = location::util::cli;
24
25location::cmds::List::List()
26 : CommandWithFlagsAndAction{cli::Name{"list"}, cli::Usage{"list"}, cli::Description{"lists known provider implementations"}}
27{
28 action([this](const Context& ctxt)
29 {
30 location::ProviderFactory::instance().enumerate([&ctxt](const std::string& name, const location::ProviderFactory::Factory&)
31 {
32 ctxt.cout << " - " << name << std::endl;
33 });
34 return EXIT_SUCCESS;
35 });
36}
037
=== added file 'src/location/cmds/list.h'
--- src/location/cmds/list.h 1970-01-01 00:00:00 +0000
+++ src/location/cmds/list.h 2016-06-30 09:21:49 +0000
@@ -0,0 +1,41 @@
1/*
2 * Copyright (C) 2016 Canonical, Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Thomas Voß <thomas.voss@canonical.com>
17 *
18 */
19
20#ifndef LOCATION_CMDS_LIST_H_
21#define LOCATION_CMDS_LIST_H_
22
23#include <location/util/cli.h>
24
25#include <iosfwd>
26
27namespace location
28{
29namespace cmds
30{
31// List lists all known provider implementations
32class List : public util::cli::CommandWithFlagsAndAction
33{
34public:
35 // List initializes a new instance.
36 List();
37};
38}
39}
40
41#endif // LOCATION_CMDS_LIST_H_
042
=== added file 'src/location/cmds/provider.cpp'
--- src/location/cmds/provider.cpp 1970-01-01 00:00:00 +0000
+++ src/location/cmds/provider.cpp 2016-06-30 09:21:49 +0000
@@ -0,0 +1,83 @@
1/*
2 * Copyright (C) 2016 Canonical, Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Thomas Voß <thomas.voss@canonical.com>
17 *
18 */
19
20#include <location/cmds/provider.h>
21
22#include <location/provider_factory.h>
23#include <location/runtime.h>
24
25#include <location/providers/remote/skeleton.h>
26
27#include <core/dbus/service.h>
28#include <core/dbus/asio/executor.h>
29#include <core/posix/signal.h>
30
31namespace cli = location::util::cli;
32
33namespace
34{
35void die_if(bool b, std::ostream& out, const std::string& message)
36{
37 if (b) { out << message << std::endl; std::exit(EXIT_FAILURE); }
38}
39}
40
41location::cmds::Provider::Provider()
42 : CommandWithFlagsAndAction{cli::Name{"provider"}, cli::Usage{"provider"}, cli::Description{"executes a built-in provider"}},
43 bus{core::dbus::WellKnownBus::system}
44{
45 flag(cli::make_flag(cli::Name{"bus"}, cli::Description{"bus instance to connect to, defaults to system"}, bus));
46 flag(cli::make_flag(cli::Name{"service"}, cli::Description{"name of the service hosting the provider."}, service));
47 flag(cli::make_flag(cli::Name{"path"}, cli::Description{"dbus object path hosting the provider."}, path));
48 flag(cli::make_flag(cli::Name{"id"}, cli::Description{"id of the actual provider implementation."}, id));
49
50 action([this](const Context& ctxt)
51 {
52 die_if(not service, ctxt.cout, "service name is missing");
53 die_if(not path, ctxt.cout, "object path is missing");
54 die_if(not id, ctxt.cout, "name of actual provider implementation is missing");
55
56 // We exit cleanly for SIGINT and SIGTERM.
57 auto trap = core::posix::trap_signals_for_all_subsequent_threads({core::posix::Signal::sig_int, core::posix::Signal::sig_term});
58 trap->signal_raised().connect([trap](core::posix::Signal)
59 {
60 trap->stop();
61 });
62
63 auto impl = location::ProviderFactory::instance().create_provider_for_name_with_config(*id, location::Configuration{});
64
65 auto rt = location::Runtime::create();
66 rt->start();
67
68 auto incoming = std::make_shared<core::dbus::Bus>(bus);
69 incoming->install_executor(core::dbus::asio::make_executor(incoming, rt->service()));
70 auto object = core::dbus::Service::add_service(incoming, *service)
71 ->add_object_for_path(core::dbus::types::ObjectPath{*path});
72
73 location::providers::remote::skeleton::Configuration config{object, incoming, impl};
74 auto skeleton = location::providers::remote::skeleton::create_with_configuration(config);
75
76 trap->run();
77
78 incoming->stop(); rt->stop();
79
80 return EXIT_SUCCESS;
81 });
82}
83
084
=== added file 'src/location/cmds/provider.h'
--- src/location/cmds/provider.h 1970-01-01 00:00:00 +0000
+++ src/location/cmds/provider.h 2016-06-30 09:21:49 +0000
@@ -0,0 +1,52 @@
1/*
2 * Copyright (C) 2016 Canonical, Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Thomas Voß <thomas.voss@canonical.com>
17 *
18 */
19
20#ifndef LOCATION_CMDS_PROVIDER_H_
21#define LOCATION_CMDS_PROVIDER_H_
22
23#include <location/optional.h>
24#include <location/util/cli.h>
25
26#include <location/util/well_known_bus.h>
27
28#include <boost/filesystem.hpp>
29
30#include <iosfwd>
31
32namespace location
33{
34namespace cmds
35{
36// Provider executes an in-tree provider out-of-process.
37class Provider : public util::cli::CommandWithFlagsAndAction
38{
39public:
40 // Run initializes a new instance.
41 Provider();
42
43private:
44 core::dbus::WellKnownBus bus; // The bus we should connect to.
45 Optional<std::string> service; // The name of the service under which the provider should be exposed.
46 Optional<std::string> path; // The dbus object path under which the provider is known.
47 Optional<std::string> id; // The id of the actual provider implementation.
48};
49}
50}
51
52#endif // LOCATION_CMDS_PROVIDER_H_
053
=== added file 'src/location/cmds/run.cpp'
--- src/location/cmds/run.cpp 1970-01-01 00:00:00 +0000
+++ src/location/cmds/run.cpp 2016-06-30 09:21:49 +0000
@@ -0,0 +1,109 @@
1/*
2 * Copyright (C) 2016 Canonical, Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Thomas Voß <thomas.voss@canonical.com>
17 *
18 */
19
20#include <location/cmds/run.h>
21
22#include <location/boost_ptree_settings.h>
23#include <location/fusion_provider_selection_policy.h>
24#include <location/service_with_engine.h>
25#include <location/settings.h>
26#include <location/trust_store_permission_manager.h>
27
28#include <location/dbus/skeleton/service.h>
29#include <location/runtime.h>
30
31#include <location/util/well_known_bus.h>
32
33#include <core/dbus/asio/executor.h>
34#include <core/posix/signal.h>
35
36namespace cli = location::util::cli;
37
38location::cmds::Run::Run()
39 : CommandWithFlagsAndAction{cli::Name{"run"}, cli::Usage{"run"}, cli::Description{"runs the daemon"}},
40 bus{core::dbus::WellKnownBus::system},
41 settings{"/var/lib/ubuntu-location-service/config.ini"}
42{
43 flag(cli::make_flag(cli::Name{"bus"}, cli::Description{"bus instance to connect to, defaults to system"}, bus));
44 flag(cli::make_flag(cli::Name{"config"}, cli::Description{"daemon configuration"}, config));
45 flag(cli::make_flag(cli::Name{"settings"}, cli::Description{"path to runtime persistent state data"}, settings));
46
47 action([this](const Context& ctxt)
48 {
49 account_for_lp1447110();
50
51 // We exit cleanly for SIGINT and SIGTERM.
52 auto trap = core::posix::trap_signals_for_all_subsequent_threads({core::posix::Signal::sig_int, core::posix::Signal::sig_term});
53 trap->signal_raised().connect([trap](core::posix::Signal)
54 {
55 trap->stop();
56 });
57
58 // The engine instance is the core piece of functionality.
59 auto engine = std::make_shared<location::Engine>(
60 // We default to a fusion provider selection policy, providing
61 // fusioned and filtered updates to sessions.
62 std::make_shared<location::FusionProviderSelectionPolicy>(),
63 // We default to a location::Settings implementation that reads state from
64 // an ini file, immediately syncing back changes to the underlying file whenever
65 // parameters change.
66 std::make_shared<location::SyncingSettings>(std::make_shared<location::BoostPtreeSettings>(settings.string())));
67
68 auto rt = location::Runtime::create();
69
70 auto incoming = std::make_shared<core::dbus::Bus>(bus);
71 auto outgoing = std::make_shared<core::dbus::Bus>(bus);
72
73 incoming->install_executor(core::dbus::asio::make_executor(incoming, rt->service()));
74 outgoing->install_executor(core::dbus::asio::make_executor(outgoing, rt->service()));
75
76 auto service = core::dbus::Service::add_service<location::dbus::Service>(incoming);
77
78 location::dbus::skeleton::Service::Configuration config
79 {
80 std::make_shared<location::ServiceWithEngine>(engine),
81 incoming,
82 outgoing,
83 service,
84 // We resolve credentials of incoming calls by talking back to the dbus daemon and subsequently
85 // querying apparmor for the confinement profile.
86 std::make_shared<location::dbus::skeleton::Service::DBusDaemonCredentialsResolver>(outgoing),
87 std::make_shared<location::dbus::skeleton::Service::ObjectPathGenerator>(),
88 // Incoming requests are verified by talking to a trust-store instance.
89 location::TrustStorePermissionManager::create_default_instance_with_bus(outgoing)
90 };
91
92 rt->start();
93
94 auto skeleton = std::make_shared<location::dbus::skeleton::Service>(config);
95
96 trap->run();
97
98 incoming->stop(); outgoing->stop(); rt->stop();
99
100 return EXIT_SUCCESS;
101 });
102}
103
104void location::cmds::Run::account_for_lp1447110() const
105{
106 static const boost::filesystem::path old_log_dir{"/var/log/ubuntu-location-service"};
107 boost::system::error_code ec;
108 boost::filesystem::remove_all(old_log_dir, ec);
109}
0110
=== added file 'src/location/cmds/run.h'
--- src/location/cmds/run.h 1970-01-01 00:00:00 +0000
+++ src/location/cmds/run.h 2016-06-30 09:21:49 +0000
@@ -0,0 +1,55 @@
1/*
2 * Copyright (C) 2016 Canonical, Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Thomas Voß <thomas.voss@canonical.com>
17 *
18 */
19
20#ifndef LOCATION_CMDS_RUN_H_
21#define LOCATION_CMDS_RUN_H_
22
23#include <location/optional.h>
24#include <location/util/cli.h>
25
26#include <location/util/well_known_bus.h>
27
28#include <boost/filesystem.hpp>
29
30#include <iosfwd>
31
32namespace location
33{
34namespace cmds
35{
36// Run executes locationd, exposing the service via DBus.
37class Run : public util::cli::CommandWithFlagsAndAction
38{
39public:
40 // Run initializes a new instance.
41 Run();
42
43private:
44 // Ensure that log files dating back to before the fix
45 // for lp:1447110 are removed and do not waste space.
46 void account_for_lp1447110() const;
47
48 core::dbus::WellKnownBus bus; // The bus we should connect to.
49 Optional<boost::filesystem::path> config; // Optionally load configuration from this config file.
50 boost::filesystem::path settings; // Runtime persistent state settings are loaded from this file.
51};
52}
53}
54
55#endif // LOCATION_CMDS_RUN_H_
056
=== added file 'src/location/cmds/status.cpp'
--- src/location/cmds/status.cpp 1970-01-01 00:00:00 +0000
+++ src/location/cmds/status.cpp 2016-06-30 09:21:49 +0000
@@ -0,0 +1,69 @@
1/*
2 * Copyright (C) 2016 Canonical, Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Thomas Voß <thomas.voss@canonical.com>
17 *
18 */
19
20#include <location/cmds/status.h>
21#include <location/dbus/stub/service.h>
22#include <location/service/runtime.h>
23#include <location/util/well_known_bus.h>
24
25#include <core/dbus/asio/executor.h>
26
27namespace cli = location::util::cli;
28
29location::cmds::Status::Status()
30 : CommandWithFlagsAndAction{cli::Name{"status"}, cli::Usage{"status"}, cli::Description{"queries the status of the daemon"}},
31 bus{core::dbus::WellKnownBus::system}
32{
33 flag(cli::make_flag(cli::Name{"bus"}, cli::Description{"bus instance to connect to, defaults to system"}, bus));
34 action([this](const Context& ctxt)
35 {
36 auto rt = location::service::Runtime::create();
37
38 auto conn = std::make_shared<core::dbus::Bus>(bus);
39
40 conn->install_executor(core::dbus::asio::make_executor(conn, rt->service()));
41
42 auto service = core::dbus::Service::use_service<location::dbus::Service>(conn);
43 auto stub = std::make_shared<location::dbus::stub::Service>(conn, service, service->object_for_path(core::dbus::types::ObjectPath{location::dbus::Service::path()}));
44
45 rt->start();
46
47 ctxt.cout << " is online: " << std::boolalpha << stub->is_online() << std::endl
48 << " state: " << stub->state() << std::endl
49 << " satellite based positioning: " << std::boolalpha << stub->does_satellite_based_positioning() << std::endl
50 << " reports cell & wifi ids: " << std::boolalpha << stub->does_report_cell_and_wifi_ids() << std::endl;
51 auto svs = stub->visible_space_vehicles().get();
52 if (svs.size() > 0)
53 {
54 ctxt.cout << " svs:" << std::endl;
55 for (const auto& pair : svs)
56 ctxt.cout << " " << pair.second << std::endl;
57 }
58 else
59 {
60 ctxt.cout << " svs: " << "none";
61 }
62
63 ctxt.cout << std::endl;
64
65 conn->stop(); rt->stop();
66
67 return EXIT_SUCCESS;
68 });
69}
070
=== added file 'src/location/cmds/status.h'
--- src/location/cmds/status.h 1970-01-01 00:00:00 +0000
+++ src/location/cmds/status.h 2016-06-30 09:21:49 +0000
@@ -0,0 +1,49 @@
1/*
2 * Copyright (C) 2016 Canonical, Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Thomas Voß <thomas.voss@canonical.com>
17 *
18 */
19
20#ifndef LOCATION_CMDS_STATUS_H_
21#define LOCATION_CMDS_STATUS_H_
22
23#include <location/optional.h>
24#include <location/util/cli.h>
25
26#include <core/dbus/well_known_bus.h>
27
28#include <boost/filesystem.hpp>
29
30#include <iosfwd>
31
32namespace location
33{
34namespace cmds
35{
36// Status queries the status of the daemon
37class Status : public util::cli::CommandWithFlagsAndAction
38{
39public:
40 // Status initializes a new instance.
41 Status();
42
43private:
44 core::dbus::WellKnownBus bus; // The bus we should connect to.
45};
46}
47}
48
49#endif // LOCATION_CMDS_STATUS_H_
050
=== added file 'src/location/cmds/test.cpp'
--- src/location/cmds/test.cpp 1970-01-01 00:00:00 +0000
+++ src/location/cmds/test.cpp 2016-06-30 09:21:49 +0000
@@ -0,0 +1,32 @@
1/*
2 * Copyright (C) 2016 Canonical, Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Thomas Voß <thomas.voss@canonical.com>
17 *
18 */
19
20#include <location/cmds/test.h>
21#include <location/runtime_tests.h>
22
23namespace cli = location::util::cli;
24
25location::cmds::Test::Test()
26 : CommandWithFlagsAndAction{cli::Name{"test"}, cli::Usage{"test"}, cli::Description{"executes runtime tests against the gps provider."}}
27{
28 action([this](const Context& ctxt)
29 {
30 return location::execute_runtime_tests(ctxt.cout, ctxt.cout);
31 });
32}
033
=== added file 'src/location/cmds/test.h'
--- src/location/cmds/test.h 1970-01-01 00:00:00 +0000
+++ src/location/cmds/test.h 2016-06-30 09:21:49 +0000
@@ -0,0 +1,41 @@
1/*
2 * Copyright (C) 2016 Canonical, Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Thomas Voß <thomas.voss@canonical.com>
17 *
18 */
19
20#ifndef LOCATION_CMDS_TEST_H_
21#define LOCATION_CMDS_TEST_H_
22
23#include <location/util/cli.h>
24
25#include <iosfwd>
26
27namespace location
28{
29namespace cmds
30{
31// Test executes runtime tests against the gps provider.
32class Test : public util::cli::CommandWithFlagsAndAction
33{
34public:
35 // List initializes a new instance.
36 Test();
37};
38}
39}
40
41#endif // LOCATION_CMDS_TEST_H_
042
=== added file 'src/location/daemon.cpp'
--- src/location/daemon.cpp 1970-01-01 00:00:00 +0000
+++ src/location/daemon.cpp 2016-06-30 09:21:49 +0000
@@ -0,0 +1,54 @@
1/*
2 * Copyright (C) 2016 Canonical, Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Thomas Voß <thomas.voss@canonical.com>
17 *
18 */
19
20#include <location/daemon.h>
21
22#include <location/cmds/list.h>
23#include <location/cmds/provider.h>
24#include <location/cmds/run.h>
25#include <location/cmds/status.h>
26#include <location/cmds/test.h>
27
28#include <glog/logging.h>
29
30#include <iostream>
31
32namespace cli = location::util::cli;
33
34location::Daemon::Daemon()
35 : cmd{cli::Name{"locationd"}, cli::Usage{"locationd"}, cli::Description{"locationd"}}
36{
37 cmd.command(std::make_shared<location::cmds::List>());
38 cmd.command(std::make_shared<location::cmds::Provider>());
39 cmd.command(std::make_shared<location::cmds::Run>());
40 cmd.command(std::make_shared<location::cmds::Status>());
41 cmd.command(std::make_shared<location::cmds::Test>());
42}
43
44int location::Daemon::run(const std::vector<std::string> &args)
45{
46 // Setup logging for the daemon.
47 FLAGS_logtostderr = true;
48 FLAGS_stop_logging_if_full_disk = true;
49 FLAGS_max_log_size = 5;
50
51 google::InitGoogleLogging("locationd");
52
53 return cmd.run(cli::Command::Context{std::cin, std::cout, args});
54}
055
=== added file 'src/location/daemon.h'
--- src/location/daemon.h 1970-01-01 00:00:00 +0000
+++ src/location/daemon.h 2016-06-30 09:21:49 +0000
@@ -0,0 +1,49 @@
1/*
2 * Copyright (C) 2016 Canonical, Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Thomas Voß <thomas.voss@canonical.com>
17 *
18 */
19
20#ifndef LOCATION_DAEMON_H_
21#define LOCATION_DAEMON_H_
22
23#include <location/util/cli.h>
24#include <location/util/do_not_copy_or_move.h>
25
26#include <memory>
27#include <set>
28#include <sstream>
29#include <string>
30#include <vector>
31
32namespace location
33{
34/// @brief Daemon implements biometryd.
35class Daemon : private util::DoNotCopyOrMove
36{
37public:
38 /// @brief Daemon creates a new instance, populating the map of known commands.
39 Daemon();
40
41 /// @brief run executes the daemon.
42 int run(const std::vector<std::string>& args);
43
44private:
45 util::cli::CommandWithSubcommands cmd;
46};
47}
48
49#endif // LOCATION_DAEMON_H_
050
=== added file 'src/location/daemon_main.cpp'
--- src/location/daemon_main.cpp 1970-01-01 00:00:00 +0000
+++ src/location/daemon_main.cpp 2016-06-30 09:21:49 +0000
@@ -0,0 +1,26 @@
1/*
2 * Copyright (C) 2016 Canonical, Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Thomas Voß <thomas.voss@canonical.com>
17 *
18 */
19
20#include <location/daemon.h>
21
22int main(int argc, char** argv)
23{
24 location::Daemon daemon;
25 return daemon.run(location::util::cli::args(argc, argv));
26}
027
=== modified file 'src/location/dbus/skeleton/service.cpp'
--- src/location/dbus/skeleton/service.cpp 2016-06-28 11:53:34 +0000
+++ src/location/dbus/skeleton/service.cpp 2016-06-30 09:21:49 +0000
@@ -42,17 +42,17 @@
42{42{
43}43}
4444
45location::service::Credentials45location::Credentials
46location::dbus::skeleton::Service::DBusDaemonCredentialsResolver::resolve_credentials_for_incoming_message(const core::dbus::Message::Ptr& msg)46location::dbus::skeleton::Service::DBusDaemonCredentialsResolver::resolve_credentials_for_incoming_message(const core::dbus::Message::Ptr& msg)
47{47{
48 return location::service::Credentials48 return location::Credentials
49 {49 {
50 static_cast<pid_t>(daemon.get_connection_unix_process_id(msg->sender())),50 static_cast<pid_t>(daemon.get_connection_unix_process_id(msg->sender())),
51 static_cast<uid_t>(daemon.get_connection_unix_user(msg->sender()))51 static_cast<uid_t>(daemon.get_connection_unix_user(msg->sender()))
52 };52 };
53}53}
5454
55core::dbus::types::ObjectPath location::dbus::skeleton::Service::ObjectPathGenerator::object_path_for_caller_credentials(const location::service::Credentials&)55core::dbus::types::ObjectPath location::dbus::skeleton::Service::ObjectPathGenerator::object_path_for_caller_credentials(const location::Credentials&)
56{56{
57 static std::uint32_t index{0};57 static std::uint32_t index{0};
58 std::stringstream ss; ss << "/sessions/" << index++;58 std::stringstream ss; ss << "/sessions/" << index++;
@@ -76,22 +76,42 @@
76 },76 },
77 connections77 connections
78 {78 {
79 properties.state->changed().connect([this](State state)79 {
80 {80 properties.state->changed().connect([this](State state)
81 on_state_changed(state);81 {
82 }),82 on_state_changed(state);
83 properties.does_satellite_based_positioning->changed().connect([this](bool value)83 }),
84 {84 properties.does_satellite_based_positioning->changed().connect([this](bool value) mutable
85 on_does_satellite_based_positioning_changed(value);85 {
86 }),86 on_does_satellite_based_positioning_changed(value); Service::configuration.impl->does_satellite_based_positioning() = value;
87 properties.does_report_cell_and_wifi_ids->changed().connect([this](bool value)87 }),
88 {88 properties.does_report_cell_and_wifi_ids->changed().connect([this](bool value) mutable
89 on_does_report_cell_and_wifi_ids_changed(value);89 {
90 }),90 on_does_report_cell_and_wifi_ids_changed(value); Service::configuration.impl->does_report_cell_and_wifi_ids() = value;
91 properties.is_online->changed().connect([this](bool value)91 }),
92 {92 properties.is_online->changed().connect([this](bool value) mutable
93 on_is_online_changed(value);93 {
94 })94 on_is_online_changed(value); Service::configuration.impl->is_online() = value;
95 })
96 },
97 {
98 Service::configuration.impl->state().changed().connect([this](State state) mutable
99 {
100 properties.state->set(state);
101 }),
102 Service::configuration.impl->does_satellite_based_positioning().changed().connect([this](bool value) mutable
103 {
104 properties.does_satellite_based_positioning->set(value);
105 }),
106 Service::configuration.impl->does_report_cell_and_wifi_ids().changed().connect([this](bool value) mutable
107 {
108 properties.does_report_cell_and_wifi_ids->set(value);
109 }),
110 Service::configuration.impl->is_online().changed().connect([this](bool value) mutable
111 {
112 properties.is_online->set(value);
113 })
114 }
95 }115 }
96{116{
97 object->install_method_handler<location::dbus::Service::CreateSessionForCriteria>([this](const core::dbus::Message::Ptr& msg)117 object->install_method_handler<location::dbus::Service::CreateSessionForCriteria>([this](const core::dbus::Message::Ptr& msg)
@@ -129,7 +149,7 @@
129 auto result =149 auto result =
130 configuration.permission_manager->check_permission_for_credentials(criteria, credentials);150 configuration.permission_manager->check_permission_for_credentials(criteria, credentials);
131151
132 if (service::PermissionManager::Result::rejected == result) throw std::runtime_error152 if (PermissionManager::Result::rejected == result) throw std::runtime_error
133 {153 {
134 "Client lacks permissions to access the service with the given criteria"154 "Client lacks permissions to access the service with the given criteria"
135 };155 };
@@ -306,3 +326,8 @@
306{326{
307 return *properties.visible_space_vehicles;327 return *properties.visible_space_vehicles;
308}328}
329
330location::Service::Session::Ptr location::dbus::skeleton::Service::create_session_for_criteria(const Criteria& criteria)
331{
332 return configuration.impl->create_session_for_criteria(criteria);
333}
309334
=== modified file 'src/location/dbus/skeleton/service.h'
--- src/location/dbus/skeleton/service.h 2016-06-28 11:53:34 +0000
+++ src/location/dbus/skeleton/service.h 2016-06-30 09:21:49 +0000
@@ -20,11 +20,10 @@
20#define LOCATION_DBUS_SKELETON_SERVICE_H_20#define LOCATION_DBUS_SKELETON_SERVICE_H_
2121
22#include <location/service.h>22#include <location/service.h>
23#include <location/permission_manager.h>
2324
24#include <location/dbus/service.h>25#include <location/dbus/service.h>
2526
26#include <location/service/permission_manager.h>
27
28#include <core/dbus/dbus.h>27#include <core/dbus/dbus.h>
29#include <core/dbus/object.h>28#include <core/dbus/object.h>
30#include <core/dbus/property.h>29#include <core/dbus/property.h>
@@ -55,7 +54,7 @@
55 virtual ~CredentialsResolver() = default;54 virtual ~CredentialsResolver() = default;
5655
57 // Resolves the sender of msg to the respective credentials.56 // Resolves the sender of msg to the respective credentials.
58 virtual service::Credentials resolve_credentials_for_incoming_message(const core::dbus::Message::Ptr& msg) = 0;57 virtual Credentials resolve_credentials_for_incoming_message(const core::dbus::Message::Ptr& msg) = 0;
59 };58 };
6059
61 // Implements CredentialsResolver by reaching out to the dbus daemon and60 // Implements CredentialsResolver by reaching out to the dbus daemon and
@@ -68,7 +67,7 @@
68 DBusDaemonCredentialsResolver(const core::dbus::Bus::Ptr& bus);67 DBusDaemonCredentialsResolver(const core::dbus::Bus::Ptr& bus);
6968
70 // Resolves the sender of msg to pid, uid by calling out to the dbus daemon.69 // Resolves the sender of msg to pid, uid by calling out to the dbus daemon.
71 service::Credentials resolve_credentials_for_incoming_message(const core::dbus::Message::Ptr& msg);70 Credentials resolve_credentials_for_incoming_message(const core::dbus::Message::Ptr& msg);
7271
73 // Stub for accessing the dbus daemon.72 // Stub for accessing the dbus daemon.
74 core::dbus::DBus daemon;73 core::dbus::DBus daemon;
@@ -90,36 +89,30 @@
90 // [1.] Query the AppArmor profile name for pid in credentials.89 // [1.] Query the AppArmor profile name for pid in credentials.
91 // [1.1] If the process is running unconfined, rely on a counter to assemble the session name.90 // [1.1] If the process is running unconfined, rely on a counter to assemble the session name.
92 // [1.2] If the process is confined, use the AppArmor profile name to generate the path.91 // [1.2] If the process is confined, use the AppArmor profile name to generate the path.
93 virtual core::dbus::types::ObjectPath object_path_for_caller_credentials(const service::Credentials& credentials);92 virtual core::dbus::types::ObjectPath object_path_for_caller_credentials(const Credentials& credentials);
94 };93 };
9594
96 struct Configuration95 struct Configuration
97 {96 {
98 // DBus connection set up for handling requests to the service.97 location::Service::Ptr impl; // The actual service implementation.
99 core::dbus::Bus::Ptr incoming;98 core::dbus::Bus::Ptr incoming; // DBus connection set up for handling requests to the service.
100 // DBus connection for reaching out to other services in a non-blocking way.99 core::dbus::Bus::Ptr outgoing; // DBus connection for reaching out to other services in a non-blocking way.
101 core::dbus::Bus::Ptr outgoing;100 core::dbus::Service::Ptr service; // Service instance that the skeleton should be exposed upon.
102 // Service instance that the skeleton should be exposed upon.101 CredentialsResolver::Ptr credentials_resolver; // An implementation of CredentialsResolver.
103 core::dbus::Service::Ptr service;102 ObjectPathGenerator::Ptr object_path_generator; // An implementation of ObjectPathGenerator.
104 // An implementation of CredentialsResolver for resolving incoming message sender103 PermissionManager::Ptr permission_manager; // A permission manager implementation.
105 // to Credentials = uid, pid.
106 CredentialsResolver::Ptr credentials_resolver;
107 // An implementation of ObjectPathGenerator for generating session names.
108 ObjectPathGenerator::Ptr object_path_generator;
109 // Permission manager implementation for verifying incoming requests.
110 service::PermissionManager::Ptr permission_manager;
111 };104 };
112105
113 Service(const Configuration& configuration);106 Service(const Configuration& configuration);
114 ~Service() noexcept;107 ~Service() noexcept;
115108
116 // From location::service::Interface109 // From location::service::Interface
117 const core::Property<State>& state() const;110 const core::Property<State>& state() const override;
118 core::Property<bool>& does_satellite_based_positioning();111 core::Property<bool>& does_satellite_based_positioning() override;
119 core::Property<bool>& does_report_cell_and_wifi_ids();112 core::Property<bool>& does_report_cell_and_wifi_ids() override;
120 core::Property<bool>& is_online();113 core::Property<bool>& is_online() override;
121 core::Property<std::map<SpaceVehicle::Key, SpaceVehicle>>& visible_space_vehicles();114 core::Property<std::map<SpaceVehicle::Key, SpaceVehicle>>& visible_space_vehicles() override;
122115 Session::Ptr create_session_for_criteria(const Criteria& criteria) override;
123protected:116protected:
124 // Enable subclasses to alter the state.117 // Enable subclasses to alter the state.
125 core::Property<State>& mutable_state();118 core::Property<State>& mutable_state();
@@ -172,10 +165,21 @@
172 // We sign up to property changes here, to be able to report them to the bus165 // We sign up to property changes here, to be able to report them to the bus
173 struct166 struct
174 {167 {
175 core::ScopedConnection state;168 struct
176 core::ScopedConnection does_satellite_based_positioning;169 {
177 core::ScopedConnection does_report_cell_and_wifi_ids;170 core::ScopedConnection state;
178 core::ScopedConnection is_online;171 core::ScopedConnection does_satellite_based_positioning;
172 core::ScopedConnection does_report_cell_and_wifi_ids;
173 core::ScopedConnection is_online;
174 } dbus;
175
176 struct
177 {
178 core::ScopedConnection state;
179 core::ScopedConnection does_satellite_based_positioning;
180 core::ScopedConnection does_report_cell_and_wifi_ids;
181 core::ScopedConnection is_online;
182 } impl;
179 } connections;183 } connections;
180 // Guards the session store.184 // Guards the session store.
181 std::mutex guard;185 std::mutex guard;
182186
=== added file 'src/location/dummy_service.cpp'
--- src/location/dummy_service.cpp 1970-01-01 00:00:00 +0000
+++ src/location/dummy_service.cpp 2016-06-30 09:21:49 +0000
@@ -0,0 +1,55 @@
1/*
2 * Copyright (C) 2016 Canonical, Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Thomas Voß <thomas.voss@canonical.com>
17 *
18 */
19
20#include <location/dummy_service.h>
21
22location::Service::Session::Updates& location::DummyService::Session::updates()
23{
24 return updates_;
25}
26
27const core::Property<location::Service::State>& location::DummyService::state() const
28{
29 return state_;
30}
31
32core::Property<bool>& location::DummyService::does_satellite_based_positioning()
33{
34 return does_satellite_based_positioning_;
35}
36
37core::Property<bool>& location::DummyService::is_online()
38{
39 return is_online_;
40}
41
42core::Property<bool>& location::DummyService::does_report_cell_and_wifi_ids()
43{
44 return does_report_cell_and_wifi_ids_;
45}
46
47core::Property<std::map<location::SpaceVehicle::Key, location::SpaceVehicle>>& location::DummyService::visible_space_vehicles()
48{
49 return visible_space_vehicles_;
50}
51
52location::Service::Session::Ptr location::DummyService::create_session_for_criteria(const Criteria&)
53{
54 return std::make_shared<DummyService::Session>();
55}
056
=== added file 'src/location/dummy_service.h'
--- src/location/dummy_service.h 1970-01-01 00:00:00 +0000
+++ src/location/dummy_service.h 2016-06-30 09:21:49 +0000
@@ -0,0 +1,55 @@
1/*
2 * Copyright (C) 2016 Canonical, Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Thomas Voß <thomas.voss@canonical.com>
17 *
18 */
19
20#ifndef LOCATION_DUMMY_SERVICE_H_
21#define LOCATION_DUMMY_SERVICE_H_
22
23#include <location/service.h>
24
25namespace location
26{
27class DummyService : public Service
28{
29public:
30 class Session : public Service::Session
31 {
32 public:
33 Updates& updates() override;
34
35 private:
36 Updates updates_;
37 };
38
39 const core::Property<State>& state() const override;
40 core::Property<bool>& does_satellite_based_positioning() override;
41 core::Property<bool>& is_online() override;
42 core::Property<bool>& does_report_cell_and_wifi_ids() override;
43 core::Property<std::map<SpaceVehicle::Key, SpaceVehicle>>& visible_space_vehicles() override;
44 Session::Ptr create_session_for_criteria(const Criteria& criteria) override;
45
46private:
47 core::Property<State> state_;
48 core::Property<bool> does_satellite_based_positioning_;
49 core::Property<bool> is_online_;
50 core::Property<bool> does_report_cell_and_wifi_ids_;
51 core::Property<std::map<SpaceVehicle::Key, SpaceVehicle>> visible_space_vehicles_;
52};
53}
54
55#endif // LOCATION_DUMMY_SERVICE_H_
056
=== added file 'src/location/permission_manager.h'
--- src/location/permission_manager.h 1970-01-01 00:00:00 +0000
+++ src/location/permission_manager.h 2016-06-30 09:21:49 +0000
@@ -0,0 +1,73 @@
1/*
2 * Copyright © 2012-2013 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Thomas Voß <thomas.voss@canonical.com>
17 */
18#ifndef LOCATION_PERMISSION_MANAGER_H_
19#define LOCATION_PERMISSION_MANAGER_H_
20
21#include <memory>
22
23namespace location
24{
25struct Criteria;
26/** @brief Credentials of a remote session. */
27struct Credentials
28{
29 /** @brief The process id of the remote peer. */
30 pid_t pid;
31 /** @brief The user id the remote peer runs under. */
32 uid_t uid;
33};
34
35/**
36 * @brief The PermissionManager class is an interface to check whether an application
37 * is allowed to access the location services.
38 */
39class PermissionManager
40{
41public:
42 /** Manager pointer type. */
43 typedef std::shared_ptr<PermissionManager> Ptr;
44
45 /**
46 * @brief The Result enum summarizes the results of a query for permissions.
47 */
48 enum class Result
49 {
50 granted, ///< The app is allowed to access the location service.
51 rejected ///< The app is not allowed to access the location service.
52 };
53
54 virtual ~PermissionManager() = default;
55 PermissionManager(const PermissionManager&) = delete;
56 PermissionManager& operator=(const PermissionManager&) = delete;
57
58 /**
59 * @brief Checks whether the app with the given credentials is allowed to access the service for the given criteria.
60 * @param criteria The requirements of the remote peer.
61 * @param credentials The credentials identifying the remote peer.
62 * @return Result::granted if the remote peer is allowed to access the location service, Result::rejected otherwise.
63 */
64 virtual Result check_permission_for_credentials(
65 const Criteria& criteria,
66 const Credentials& credentials) = 0;
67
68protected:
69 PermissionManager() = default;
70};
71}
72
73#endif // LOCATION_PERMISSION_MANAGER_H_
074
=== modified file 'src/location/providers/gps/sntp_reference_time_source.cpp'
--- src/location/providers/gps/sntp_reference_time_source.cpp 2016-06-26 21:17:03 +0000
+++ src/location/providers/gps/sntp_reference_time_source.cpp 2016-06-30 09:21:49 +0000
@@ -19,7 +19,7 @@
19#include <location/providers/gps/sntp_reference_time_source.h>19#include <location/providers/gps/sntp_reference_time_source.h>
2020
21#include <location/configuration.h>21#include <location/configuration.h>
22#include <location/service/runtime.h>22#include <location/runtime.h>
2323
24#include <boost/property_tree/ini_parser.hpp>24#include <boost/property_tree/ini_parser.hpp>
2525
@@ -46,7 +46,7 @@
4646
47gps::HardwareAbstractionLayer::ReferenceTimeSample gps::SntpReferenceTimeSource::sample()47gps::HardwareAbstractionLayer::ReferenceTimeSample gps::SntpReferenceTimeSource::sample()
48{48{
49 auto rt = location::service::Runtime::create();49 auto rt = location::Runtime::create();
50 rt->start();50 rt->start();
5151
52 location::providers::gps::sntp::Client sntp_client;52 location::providers::gps::sntp::Client sntp_client;
5353
=== added file 'src/location/runtime.cpp'
--- src/location/runtime.cpp 1970-01-01 00:00:00 +0000
+++ src/location/runtime.cpp 2016-06-30 09:21:49 +0000
@@ -0,0 +1,107 @@
1/*
2 * Copyright © 2015 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTIlocationAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Thomas Voß <thomas.voss@canonical.com>
17 */
18#include <location/runtime.h>
19
20#include <location/logging.h>
21
22namespace
23{
24// exception_safe_run runs service, catching all exceptions and
25// restarting operation until an explicit shutdown has been requested.
26//
27// TODO(tvoss): Catching all exceptions is risky as they might signal unrecoverable
28// errors. We should enable calling code to decide whether an exception should be considered
29// fatal or not.
30void exception_safe_run(boost::asio::io_service& service)
31{
32 while (true)
33 {
34 try
35 {
36 service.run();
37 // a clean return from run only happens in case of
38 // stop() being called (we are keeping the service alive with
39 // a service::work instance).
40 break;
41 }
42 catch (const std::exception& e)
43 {
44 LOG(WARNING) << e.what();
45 }
46 catch (...)
47 {
48 LOG(WARNING) << "Unknown exception caught while executing boost::asio::io_service";
49 }
50 }
51}
52}
53
54std::shared_ptr<location::Runtime> location::Runtime::create(std::uint32_t pool_size)
55{
56 return std::shared_ptr<location::Runtime>(new location::Runtime(pool_size));
57}
58
59location::Runtime::Runtime(std::uint32_t pool_size)
60 : pool_size_{pool_size},
61 service_{pool_size_},
62 strand_{service_},
63 keep_alive_{service_}
64{
65}
66
67location::Runtime::~Runtime()
68{
69 try
70 {
71 stop();
72 } catch(...)
73 {
74 // Dropping all exceptions to satisfy the nothrow guarantee.
75 }
76}
77
78void location::Runtime::start()
79{
80 for (unsigned int i = 0; i < pool_size_; i++)
81 workers_.push_back(std::thread{exception_safe_run, std::ref(service_)});
82}
83
84void location::Runtime::stop()
85{
86 service_.stop();
87
88 for (auto& worker : workers_)
89 if (worker.joinable())
90 worker.join();
91}
92
93std::function<void(std::function<void()>)> location::Runtime::to_dispatcher_functional()
94{
95 // We have to make sure that we stay alive for as long as
96 // calling code requires the dispatcher to work.
97 auto sp = shared_from_this();
98 return [sp](std::function<void()> task)
99 {
100 sp->strand_.post(task);
101 };
102}
103
104boost::asio::io_service& location::Runtime::service()
105{
106 return service_;
107}
0108
=== added file 'src/location/runtime.h'
--- src/location/runtime.h 1970-01-01 00:00:00 +0000
+++ src/location/runtime.h 2016-06-30 09:21:49 +0000
@@ -0,0 +1,81 @@
1/*
2 * Copyright © 2015 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTIlocationAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Thomas Voß <thomas.voss@canonical.com>
17 */
18#ifndef LOCATION_RUNTIME_H_
19#define LOCATION_RUNTIME_H_
20
21#include <boost/asio.hpp>
22
23#include <functional>
24#include <memory>
25#include <thread>
26#include <vector>
27
28#include <cstdint>
29
30namespace location
31{
32// We bundle our "global" runtime dependencies here, specifically
33// a dispatcher to decouple multiple in-process providers from one
34// another , forcing execution to a well known set of threads.
35class Runtime : public std::enable_shared_from_this<Runtime>
36{
37public:
38 // Our default concurrency setup.
39 static constexpr const std::uint32_t worker_threads = 4;
40
41 // create returns a Runtime instance with pool_size worker threads
42 // executing the underlying service.
43 static std::shared_ptr<Runtime> create(std::uint32_t pool_size = worker_threads);
44
45 Runtime(const Runtime&) = delete;
46 Runtime(Runtime&&) = delete;
47 // Tears down the runtime, stopping all worker threads.
48 ~Runtime() noexcept(true);
49 Runtime& operator=(const Runtime&) = delete;
50 Runtime& operator=(Runtime&&) = delete;
51
52 // start executes the underlying io_service on a thread pool with
53 // the size configured at creation time.
54 void start();
55
56 // stop cleanly shuts down a Runtime instance,
57 // joining all worker threads.
58 void stop();
59
60 // to_dispatcher_functional returns a function for integration
61 // with components that expect a dispatcher for operation.
62 std::function<void(std::function<void()>)> to_dispatcher_functional();
63
64 // service returns the underlying boost::asio::io_service that is executed
65 // by the Runtime.
66 boost::asio::io_service& service();
67
68private:
69 // Runtime constructs a new instance, firing up pool_size
70 // worker threads.
71 Runtime(std::uint32_t pool_size);
72
73 std::uint32_t pool_size_;
74 boost::asio::io_service service_;
75 boost::asio::io_service::strand strand_;
76 boost::asio::io_service::work keep_alive_;
77 std::vector<std::thread> workers_;
78};
79}
80
81#endif // LOCATION_RUNTIME_H_
082
=== added file 'src/location/runtime_tests.cpp'
--- src/location/runtime_tests.cpp 1970-01-01 00:00:00 +0000
+++ src/location/runtime_tests.cpp 2016-06-30 09:21:49 +0000
@@ -0,0 +1,185 @@
1/*
2 * Copyright © 2015 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Thomas Voß <thomas.voss@canonical.com>
17 */
18
19#include <location/runtime.h>
20#include <location/runtime_tests.h>
21
22#include <location/clock.h>
23#include <location/providers/gps/hardware_abstraction_layer.h>
24
25#include <boost/accumulators/accumulators.hpp>
26#include <boost/accumulators/statistics/stats.hpp>
27#include <boost/accumulators/statistics/mean.hpp>
28#include <boost/accumulators/statistics/variance.hpp>
29
30#include <cstdlib>
31
32#include <chrono>
33#include <condition_variable>
34#include <iostream>
35#include <mutex>
36#include <thread>
37
38namespace gps = location::providers::gps;
39
40namespace
41{
42template<bool expected, typename Exception>
43void expect(bool value, const std::string& what)
44{
45 if (value != expected) throw Exception{what};
46}
47
48// Poor man's testing fixture, taking care of shutting down the currently
49// running service instance and restarting it after the tests have been run.
50struct Fixture
51{
52 Fixture()
53 {
54 // We need to make sure that we are running as root. In addition, we will stop
55 // any running location service instance prior to executing the test.
56 expect<true, std::logic_error>(::getuid() == 0, "This test has to be run as root.");
57
58 int rc = ::system("service ubuntu-location-service stop");
59 // We consciously ignore any issues and assume that we are good to go.
60 (void) rc;
61 }
62
63 ~Fixture()
64 {
65 int rc = ::system("service ubuntu-location-service start");
66 // We consciously ignore any issues reported by the call to system
67 // as we would make an otherwise fine test-suite failing just because
68 // an "uninteresting" post-condition is not satisfied.
69 (void) rc;
70 }
71};
72
73#if defined(LOCATION_PROVIDERS_GPS)
74int snr_and_ttff(std::ostream& cout, std::ostream& cerr)
75{
76 typedef boost::accumulators::accumulator_set<
77 double,
78 boost::accumulators::stats<
79 boost::accumulators::tag::mean,
80 boost::accumulators::tag::variance
81 >
82 > Statistics;
83
84 using boost::accumulators::mean;
85 using boost::accumulators::variance;
86
87 static const unsigned int trials = 3;
88
89 Statistics stats;
90 auto hal = gps::HardwareAbstractionLayer::create_default_instance();
91
92 struct State
93 {
94 State() : fix_received(false)
95 {
96 }
97
98 bool wait_for_fix_for(const std::chrono::seconds& seconds)
99 {
100 std::unique_lock<std::mutex> ul(guard);
101 return wait_condition.wait_for(
102 ul,
103 seconds,
104 [this]() {return fix_received == true;});
105 }
106
107 void on_position_updated(const location::Position&)
108 {
109 fix_received = true;
110 wait_condition.notify_all();
111 }
112
113 void reset()
114 {
115 fix_received = false;
116 }
117
118 std::mutex guard;
119 std::condition_variable wait_condition;
120 bool fix_received;
121 } state;
122
123 // We want to run in standalone mode
124 hal->set_assistance_mode(gps::AssistanceMode::standalone);
125
126 // We wire up our state to position updates from the hal.
127 hal->position_updates().connect([&state](const location::Position& pos)
128 {
129 state.on_position_updated(pos);
130 });
131
132 // We report updates to the visible space vehicles here.
133 hal->space_vehicle_updates().connect([&cout](const std::set<location::SpaceVehicle>& svs)
134 {
135 cout << std::scientific;
136 cout << "key snr has_almanac_data has_ephimeris_data used_in_fix azimuth elevation" << std::endl;
137 for (const auto& sv : svs)
138 cout << sv.key.id << " " << sv.snr << " " << sv.has_almanac_data << " " << sv.has_ephimeris_data << " " << sv.used_in_fix << " " << sv.azimuth.value() << " " << sv.elevation.value() << std::endl;
139 });
140
141 for (unsigned int i = 0; i < trials; i++)
142 {
143 // We want to force a cold start per trial.
144 hal->delete_all_aiding_data();
145
146 state.reset();
147 auto start = std::chrono::duration_cast<std::chrono::microseconds>(location::Clock::now().time_since_epoch());
148 {
149 hal->start_positioning();
150 // We expect a maximum cold start time of 15 minutes. The theoretical
151 // limit is 12.5 minutes, and we add up some grace period to make the
152 // test more robust (see http://en.wikipedia.org/wiki/Time_to_first_fix).
153 expect<true, std::runtime_error>(state.wait_for_fix_for(std::chrono::seconds{15 * 60}), "Wait for fix timed out.");
154 hal->stop_positioning();
155 }
156 auto stop = std::chrono::duration_cast<std::chrono::microseconds>(location::Clock::now().time_since_epoch());
157
158 stats((stop - start).count());
159 }
160
161 cout << "Mean time to first fix in [ms]: "
162 << std::chrono::duration_cast<std::chrono::milliseconds>(
163 std::chrono::microseconds(
164 static_cast<std::uint64_t>(mean(stats)))).count()
165 << std::endl;
166 cout << "Variance in time to first fix in [ms]: "
167 << std::chrono::duration_cast<std::chrono::milliseconds>(
168 std::chrono::microseconds(
169 static_cast<std::uint64_t>(variance(stats)))).count()
170 << std::endl;
171
172 return 0;
173}
174#else
175int snr_and_ttff(std::ostream&, std::ostream&) { return 0; }
176#endif // LOCATION_PROVIDERS_GPS
177}
178
179int location::execute_runtime_tests(std::ostream& cout, std::ostream& cerr)
180{
181 Fixture fixture; // This throws in case of issues.
182 auto rc = snr_and_ttff(cout, cerr); if (rc != 0) return rc;
183 // Other runtime tests go here;
184 return rc;
185}
0186
=== added file 'src/location/runtime_tests.h'
--- src/location/runtime_tests.h 1970-01-01 00:00:00 +0000
+++ src/location/runtime_tests.h 2016-06-30 09:21:49 +0000
@@ -0,0 +1,30 @@
1/*
2 * Copyright © 2015 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Thomas Voß <thomas.voss@canonical.com>
17 */
18#ifndef LOCATION_RUNTIME_TESTS_H_
19#define LOCATION_RUNTIME_TESTS_H_
20
21#include <iosfwd>
22
23namespace location
24{
25// execute_runtime_tests runs all configured runtime tests.
26// Returns 0 if successful.
27int execute_runtime_tests(std::ostream& cout, std::ostream& cerr);
28}
29
30#endif // LOCATION_RUNTIME_TESTS_H_
031
=== added file 'src/location/service_with_engine.cpp'
--- src/location/service_with_engine.cpp 1970-01-01 00:00:00 +0000
+++ src/location/service_with_engine.cpp 2016-06-30 09:21:49 +0000
@@ -0,0 +1,129 @@
1/*
2 * Copyright © 2016 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Thomas Voß <thomas.voss@canonical.com>
17 */
18
19#include <location/proxy_provider.h>
20#include <location/service_with_engine.h>
21#include <location/session_with_provider.h>
22
23location::ServiceWithEngine::ServiceWithEngine(const Engine::Ptr& engine)
24 : engine{engine},
25 connections
26 {
27 is_online_.changed().connect(
28 [this](bool value)
29 {
30 ServiceWithEngine::engine->configuration.engine_state
31 = value ?
32 Engine::Status::on :
33 Engine::Status::off;
34 }),
35 does_report_cell_and_wifi_ids_.changed().connect(
36 [this](bool value)
37 {
38 ServiceWithEngine::engine->configuration.wifi_and_cell_id_reporting_state
39 = value ?
40 location::WifiAndCellIdReportingState::on :
41 location::WifiAndCellIdReportingState::off;
42 }),
43 does_satellite_based_positioning_.changed().connect(
44 [this](bool value)
45 {
46 ServiceWithEngine::engine->configuration.satellite_based_positioning_state
47 = value ?
48 location::SatelliteBasedPositioningState::on :
49 location::SatelliteBasedPositioningState::off;
50 }),
51 engine->configuration.engine_state.changed().connect(
52 [this](Engine::Status status)
53 {
54 switch (status)
55 {
56 case Engine::Status::off:
57 is_online_ = false;
58 state_ = State::disabled;
59 break;
60 case Engine::Status::on:
61 is_online_ = true;
62 state_ = State::enabled;
63 break;
64 case Engine::Status::active:
65 is_online_ = true;
66 state_ = State::active;
67 break;
68 }
69 }),
70 engine->configuration.satellite_based_positioning_state.changed().connect(
71 [this](location::SatelliteBasedPositioningState state)
72 {
73 does_satellite_based_positioning_ =
74 state == location::SatelliteBasedPositioningState::on;
75 }),
76 engine->updates.visible_space_vehicles.changed().connect(
77 [this](const std::map<location::SpaceVehicle::Key, location::SpaceVehicle>&svs)
78 {
79 visible_space_vehicles_ = svs;
80 })
81 }
82{
83}
84
85const core::Property<location::Service::State>& location::ServiceWithEngine::state() const
86{
87 return state_;
88}
89
90core::Property<bool>& location::ServiceWithEngine::does_satellite_based_positioning()
91{
92 return does_satellite_based_positioning_;
93}
94
95core::Property<bool>& location::ServiceWithEngine::is_online()
96{
97 return is_online_;
98}
99
100core::Property<bool>& location::ServiceWithEngine::does_report_cell_and_wifi_ids()
101{
102 return does_report_cell_and_wifi_ids_;
103}
104
105core::Property<std::map<location::SpaceVehicle::Key, location::SpaceVehicle>>& location::ServiceWithEngine::visible_space_vehicles()
106{
107 return visible_space_vehicles_;
108}
109
110location::Service::Session::Ptr location::ServiceWithEngine::create_session_for_criteria(const Criteria& criteria)
111{
112 auto proxy_provider = std::make_shared<ProxyProvider>(engine->determine_provider_selection_for_criteria(criteria));
113 auto session = std::make_shared<SessionWithProvider>(proxy_provider);
114 std::weak_ptr<Session> wp{session};
115
116 session->updates().position_status.changed().connect([this, wp](const Session::Updates::Status& status)
117 {
118 location::Optional<location::Update<location::Position>> last_known_position = engine->updates.last_known_location.get();
119 bool has_last_known_position = last_known_position ? true : false;
120 bool is_session_enabled = status == Session::Updates::Status::enabled;
121 bool is_session_on_or_active = engine->configuration.engine_state != Engine::Status::off;
122
123 if (has_last_known_position && is_session_enabled && is_session_on_or_active)
124 if (auto sp = wp.lock()) // Immediately send the last known position to the client
125 sp->updates().position = last_known_position.get();
126 });
127
128 return session;
129}
0130
=== added file 'src/location/service_with_engine.h'
--- src/location/service_with_engine.h 1970-01-01 00:00:00 +0000
+++ src/location/service_with_engine.h 2016-06-30 09:21:49 +0000
@@ -0,0 +1,61 @@
1/*
2 * Copyright © 2016 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Thomas Voß <thomas.voss@canonical.com>
17 */
18#ifndef LOCATION_SERVICE_WITH_ENGINE_H_
19#define LOCATION_SERVICE_WITH_ENGINE_H_
20
21#include <location/engine.h>
22#include <location/service.h>
23
24namespace location
25{
26class ServiceWithEngine : public Service
27{
28public:
29 ServiceWithEngine(const Engine::Ptr& engine);
30
31 // From Service
32 const core::Property<State>& state() const override;
33 core::Property<bool>& does_satellite_based_positioning() override;
34 core::Property<bool>& is_online() override;
35 core::Property<bool>& does_report_cell_and_wifi_ids() override;
36 core::Property<std::map<SpaceVehicle::Key, SpaceVehicle>>& visible_space_vehicles() override;
37 Session::Ptr create_session_for_criteria(const Criteria& criteria) override;
38
39private:
40 Engine::Ptr engine; // The engine instance we use for positioning.
41
42 // Properties of the service implementation.
43 core::Property<State> state_;
44 core::Property<bool> does_satellite_based_positioning_;
45 core::Property<bool> is_online_;
46 core::Property<bool> does_report_cell_and_wifi_ids_;
47 core::Property<std::map<SpaceVehicle::Key, SpaceVehicle>> visible_space_vehicles_;
48
49 struct
50 {
51 core::ScopedConnection is_online;
52 core::ScopedConnection does_report_cell_and_wifi_ids;
53 core::ScopedConnection does_satellite_based_positioning;
54 core::ScopedConnection engine_state;
55 core::ScopedConnection satellite_based_positioning_state;
56 core::ScopedConnection visible_space_vehicles;
57 } connections; // All event connections are automatically cut on destruction.
58};
59}
60
61#endif // LOCATION_SERVICE_WITH_ENGINE_H_
062
=== added file 'src/location/session_with_provider.cpp'
--- src/location/session_with_provider.cpp 1970-01-01 00:00:00 +0000
+++ src/location/session_with_provider.cpp 2016-06-30 09:21:49 +0000
@@ -0,0 +1,111 @@
1/*
2 * Copyright © 2016 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Thomas Voß <thomas.voss@canonical.com>
17 */
18
19#include <location/session_with_provider.h>
20
21location::SessionWithProvider::SessionWithProvider(const Provider::Ptr& provider)
22 : provider_{provider},
23 connections_
24 {
25 provider_->updates().position.connect(
26 [this](const Update<Position>& update)
27 {
28 updates().position = update;
29 }),
30 provider_->updates().heading.connect(
31 [this](const Update<Heading>& update)
32 {
33 updates().heading = update;
34 }),
35 provider_->updates().velocity.connect(
36 [this](const Update<Velocity>& update)
37 {
38 updates().velocity = update;
39 }),
40 updates().position_status.changed().connect(
41 [this](const Updates::Status& status)
42 {
43 switch(status)
44 {
45 case Updates::Status::enabled:
46 start_position_updates(); break;
47 case Updates::Status::disabled:
48 stop_position_updates(); break;
49 }
50 }),
51 updates().velocity_status.changed().connect(
52 [this](const Updates::Status& status)
53 {
54 switch(status)
55 {
56 case Updates::Status::enabled:
57 start_velocity_updates(); break;
58 case Updates::Status::disabled:
59 stop_velocity_updates(); break;
60 }
61 }),
62 updates().heading_status.changed().connect(
63 [this](const Updates::Status& status)
64 {
65 switch(status)
66 {
67 case Updates::Status::enabled:
68 start_heading_updates(); break;
69 case Updates::Status::disabled:
70 stop_heading_updates(); break;
71 }
72 })
73 }
74{
75}
76
77location::Service::Session::Updates& location::SessionWithProvider::updates()
78{
79 return updates_;
80}
81
82void location::SessionWithProvider::start_position_updates()
83{
84 provider_->state_controller()->start_position_updates();
85}
86
87void location::SessionWithProvider::stop_position_updates()
88{
89 provider_->state_controller()->stop_position_updates();
90}
91
92void location::SessionWithProvider::start_velocity_updates()
93{
94 provider_->state_controller()->start_velocity_updates();
95}
96
97void location::SessionWithProvider::stop_velocity_updates()
98{
99 provider_->state_controller()->stop_velocity_updates();
100}
101
102void location::SessionWithProvider::start_heading_updates()
103{
104 provider_->state_controller()->start_heading_updates();
105}
106
107void location::SessionWithProvider::stop_heading_updates()
108{
109 provider_->state_controller()->stop_heading_updates();
110}
111
0112
=== added file 'src/location/session_with_provider.h'
--- src/location/session_with_provider.h 1970-01-01 00:00:00 +0000
+++ src/location/session_with_provider.h 2016-06-30 09:21:49 +0000
@@ -0,0 +1,60 @@
1/*
2 * Copyright © 2016 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Thomas Voß <thomas.voss@canonical.com>
17 */
18#ifndef LOCATION_SESSION_WITH_PROVIDER_H_
19#define LOCATION_SESSION_WITH_PROVIDER_H_
20
21#include <location/provider.h>
22#include <location/service.h>
23
24namespace location
25{
26class SessionWithProvider : public Service::Session
27{
28public:
29 SessionWithProvider(const Provider::Ptr& provider);
30
31 // From Session::Service.
32 Updates& updates() override;
33
34private:
35 void start_position_updates();
36 void stop_position_updates();
37
38 void start_velocity_updates();
39 void stop_velocity_updates();
40
41 void start_heading_updates();
42 void stop_heading_updates();
43
44 Updates updates_;
45 Provider::Ptr provider_;
46
47 struct
48 {
49 core::ScopedConnection position_updates;
50 core::ScopedConnection velocity_updates;
51 core::ScopedConnection heading_updates;
52
53 core::ScopedConnection position_status_updates;
54 core::ScopedConnection heading_status_updates;
55 core::ScopedConnection velocity_status_updates;
56 } connections_;
57};
58}
59
60#endif // LOCATION_SESSION_WITH_PROVIDER_H_
061
=== added file 'src/location/trust_store_permission_manager.cpp'
--- src/location/trust_store_permission_manager.cpp 1970-01-01 00:00:00 +0000
+++ src/location/trust_store_permission_manager.cpp 2016-06-30 09:21:49 +0000
@@ -0,0 +1,179 @@
1/*
2 * Copyright © 2012-2013 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Thomas Voß <thomas.voss@canonical.com>
17 */
18
19#include <location/trust_store_permission_manager.h>
20#include <location/logging.h>
21
22#include <core/trust/dbus_agent.h>
23
24#include <core/dbus/bus.h>
25#include <core/dbus/asio/executor.h>
26
27#include <core/posix/this_process.h>
28
29#include <boost/format.hpp>
30
31#include <sys/apparmor.h>
32
33namespace
34{
35bool is_running_under_testing()
36{
37 return core::posix::this_process::env::get(
38 "TRUST_STORE_PERMISSION_MANAGER_IS_RUNNING_UNDER_TESTING",
39 "0") == "1";
40
41}
42
43namespace i18n
44{
45// We only tag strings that should be translated but do not do the actual translation.
46// Point is: The service might run in a system context, without correct locale information.
47// We leave the translation to in-session trust-store instances.
48std::string tr(const std::string& msg)
49{
50 return msg;
51}
52}
53
54// At least make the name a constant, no need to expose it, though.
55static constexpr const char* trust_store_service_name{"UbuntuLocationService"};
56}
57
58location::TrustStorePermissionManager::AppArmorProfileResolver location::TrustStorePermissionManager::libapparmor_profile_resolver()
59{
60 return [](core::trust::Pid pid)
61 {
62 static const int app_armor_error{-1};
63
64 // We make sure to clean up the returned string.
65 struct Scope
66 {
67 ~Scope()
68 {
69 if (con) ::free(con);
70 }
71
72 char* con{nullptr};
73 char* mode{nullptr};
74 } scope;
75
76 // Reach out to apparmor
77 auto rc = aa_gettaskcon(pid.value, &scope.con, &scope.mode);
78
79 // From man aa_gettaskcon:
80 // On success size of data placed in the buffer is returned, this includes the mode if
81 //present and any terminating characters. On error, -1 is returned, and errno(3) is
82 //set appropriately.
83 if (rc == app_armor_error) throw std::system_error
84 {
85 errno,
86 std::system_category()
87 };
88
89 // Safely construct the string
90 return std::string
91 {
92 scope.con ? scope.con : ""
93 };
94 };
95}
96
97core::trust::Feature location::TrustStorePermissionManager::default_feature()
98{
99 return core::trust::Feature{0};
100}
101
102location::TrustStorePermissionManager::Ptr location::TrustStorePermissionManager::create_default_instance_with_bus(const std::shared_ptr<core::dbus::Bus>& bus)
103{
104 return Ptr
105 {
106 new TrustStorePermissionManager
107 {
108 core::trust::dbus::create_multi_user_agent_for_bus_connection(
109 bus,
110 trust_store_service_name),
111 TrustStorePermissionManager::libapparmor_profile_resolver()
112 }
113 };
114}
115
116location::TrustStorePermissionManager::TrustStorePermissionManager(
117 const std::shared_ptr<core::trust::Agent>& agent,
118 location::TrustStorePermissionManager::AppArmorProfileResolver app_armor_profile_resolver)
119 : agent{agent},
120 app_armor_profile_resolver{app_armor_profile_resolver}
121{
122}
123
124location::PermissionManager::Result location::TrustStorePermissionManager::check_permission_for_credentials(
125 const location::Criteria&,
126 const location::Credentials& credentials)
127{
128 // This is ugly and we should get rid of it. Ideally, we would be able
129 // inject a mocked trust-store into our acceptance testing.
130 if (is_running_under_testing())
131 return Result::granted;
132
133 std::string profile;
134 try
135 {
136 profile = app_armor_profile_resolver(core::trust::Pid{credentials.pid});
137 } catch(const std::exception& e)
138 {
139 SYSLOG(ERROR) << "Could not resolve PID " << credentials.pid << " to apparmor profile: " << e.what();
140 return location::PermissionManager::Result::rejected;
141 } catch(...)
142 {
143 SYSLOG(ERROR) << "Could not resolve PID " << credentials.pid << " to apparmor profile.";
144 return location::PermissionManager::Result::rejected;
145 }
146
147 std::string description = i18n::tr("wants to access your current location.");
148
149 core::trust::Agent::RequestParameters params
150 {
151 core::trust::Uid{credentials.uid},
152 core::trust::Pid{credentials.pid},
153 profile,
154 TrustStorePermissionManager::default_feature(),
155 description
156 };
157
158 Result result{Result::rejected};
159
160 try
161 {
162 auto answer = agent->authenticate_request_with_parameters(params);
163 switch(answer)
164 {
165 case core::trust::Request::Answer::granted:
166 result = Result::granted;
167 break;
168 case core::trust::Request::Answer::denied:
169 result = Result::rejected;
170 break;
171 }
172 } catch(...)
173 {
174 // We silently drop all issues here and return rejected.
175 result = Result::rejected;
176 }
177
178 return result;
179}
0180
=== added file 'src/location/trust_store_permission_manager.h'
--- src/location/trust_store_permission_manager.h 1970-01-01 00:00:00 +0000
+++ src/location/trust_store_permission_manager.h 2016-06-30 09:21:49 +0000
@@ -0,0 +1,76 @@
1/*
2 * Copyright © 2012-2013 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Thomas Voß <thomas.voss@canonical.com>
17 */
18#ifndef LOCATION_SERVICE_TRUST_STORE_PERMISSION_MANAGER_H_
19#define LOCATION_SERVICE_TRUST_STORE_PERMISSION_MANAGER_H_
20
21#include <location/permission_manager.h>
22
23#include <core/trust/agent.h>
24
25namespace core
26{
27namespace dbus
28{
29class Bus;
30}
31}
32
33namespace location
34{
35// A PermmissionManager implementation leveraging the trust-store
36// infrastructure to cache a user's answer and to dispatch
37// to user-specific trust-store instances.
38class TrustStorePermissionManager : public PermissionManager
39{
40public:
41 // Just a convenience typedef.
42 typedef std::shared_ptr<TrustStorePermissionManager> Ptr;
43
44 // Functor for resolving a process id to an app-armor profile name.
45 typedef std::function<std::string(const core::trust::Pid&)> AppArmorProfileResolver;
46
47 // Returns an AppArmorProfileResolver leveraging libapparmor.
48 static AppArmorProfileResolver libapparmor_profile_resolver();
49
50 // The default feature tag we use when calling out to the agent.
51 static core::trust::Feature default_feature();
52
53 // Creates a default instance, initializing the agent and resolver
54 // fields to sensible default choices.
55 static Ptr create_default_instance_with_bus(const std::shared_ptr<core::dbus::Bus>& bus);
56
57 // Sets up the manager for operation and stores the agent and resolver
58 // instances given to the ctor.
59 TrustStorePermissionManager(
60 const std::shared_ptr<core::trust::Agent>& agent,
61 AppArmorProfileResolver app_armor_profile_resolver);
62
63 // From PermissionManager
64 Result check_permission_for_credentials(const Criteria&, const Credentials& credentials) override;
65
66private:
67 // The agent instance we leverage to authenticate
68 // permission requests.
69 std::shared_ptr<core::trust::Agent> agent;
70
71 // Helper to resolve an application's pid to an app-armor profile name.
72 AppArmorProfileResolver app_armor_profile_resolver;
73};
74}
75
76#endif // LOCATION_SERVICE_TRUST_STORE_PERMISSION_MANAGER_H_
077
=== added directory 'src/location/util'
=== added file 'src/location/util/cli.cpp'
--- src/location/util/cli.cpp 1970-01-01 00:00:00 +0000
+++ src/location/util/cli.cpp 2016-06-30 09:21:49 +0000
@@ -0,0 +1,301 @@
1/*
2 * Copyright (C) 2016 Canonical, Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Thomas Voß <thomas.voss@canonical.com>
17 *
18 */
19
20#include <location/util/cli.h>
21
22#include <boost/format.hpp>
23#include <boost/program_options.hpp>
24
25#include <iomanip>
26
27namespace cli = location::util::cli;
28namespace po = boost::program_options;
29
30namespace
31{
32namespace pattern
33{
34static constexpr const char* help_for_command_with_subcommands =
35"NAME:\n"
36" %1% - %2%\n"
37"\n"
38"USAGE:\n"
39" %3% [command options] [arguments...]";
40
41static constexpr const char* commands = "COMMANDS:";
42static constexpr const char* command = " %1% %2%";
43
44static constexpr const char* options = "OPTIONS:";
45static constexpr const char* option = " --%1% %2%";
46}
47
48void add_to_desc_for_flags(po::options_description& desc, const std::set<cli::Flag::Ptr>& flags)
49{
50 for (auto flag : flags)
51 {
52 auto v = po::value<std::string>()->notifier([flag](const std::string& s)
53 {
54 flag->notify(s);
55 });
56 desc.add_options()(flag->name().as_string().c_str(), v, flag->description().as_string().c_str());
57 }
58}
59}
60
61location::util::cli::ProgressBar::ProgressBar(std::ostream& out, const std::string& prefix, std::uint32_t width)
62 : prefix{prefix}, width{width}, out{out}
63{
64}
65
66location::util::cli::ProgressBar::~ProgressBar()
67{
68 out << std::endl;
69}
70
71void location::util::cli::ProgressBar::update(double percentage)
72{
73 struct CursorState
74 {
75 CursorState(std::ostream& out) : out{out} { out << "\33[?25l"; }
76 ~CursorState() { out << "\33[?25h"; }
77 std::ostream& out;
78 } cs{out};
79
80 out << "\r" << prefix << "[" << std::setw(width) << std::left << std::setfill(' ') << std::string(percentage * width, '=') << "] " << std::setw(5) << std::fixed << std::setprecision(2) << percentage * 100 << " %" << std::flush;
81}
82
83std::vector<std::string> cli::args(int argc, char **argv)
84{
85 std::vector<std::string> result;
86 for (int i = 1; i < argc; i++) result.push_back(argv[i]);
87 return result;
88}
89
90const cli::Name& cli::Flag::name() const
91{
92 return name_;
93}
94
95const cli::Description& cli::Flag::description() const
96{
97 return description_;
98}
99
100cli::Flag::Flag(const Name& name, const Description& description)
101 : name_{name},
102 description_{description}
103{
104}
105
106cli::Command::FlagsWithInvalidValue::FlagsWithInvalidValue() : std::runtime_error{"Flags with invalid value"}
107{
108}
109
110cli::Command::FlagsMissing::FlagsMissing() : std::runtime_error{"Flags are missing in command invocation"}
111{
112}
113
114cli::Name cli::Command::name() const
115{
116 return name_;
117}
118
119cli::Usage cli::Command::usage() const
120{
121 return usage_;
122}
123
124cli::Description cli::Command::description() const
125{
126 return description_;
127}
128
129cli::Command::Command(const cli::Name& name, const cli::Usage& usage, const cli::Description& description)
130 : name_(name),
131 usage_(usage),
132 description_(description)
133{
134}
135
136cli::CommandWithSubcommands::CommandWithSubcommands(const Name& name, const Usage& usage, const Description& description)
137 : Command{name, usage, description}
138{
139 command(std::make_shared<cmd::Help>(*this));
140}
141
142cli::CommandWithSubcommands& cli::CommandWithSubcommands::command(const Command::Ptr& command)
143{
144 commands_[command->name().as_string()] = command;
145 return *this;
146}
147
148cli::CommandWithSubcommands& cli::CommandWithSubcommands::flag(const Flag::Ptr& flag)
149{
150 flags_.insert(flag);
151 return *this;
152}
153
154void cli::CommandWithSubcommands::help(std::ostream& out)
155{
156 out << boost::format(pattern::help_for_command_with_subcommands)
157 % name().as_string() % usage().as_string()
158 % name().as_string() << std::endl;
159
160 if (flags_.size() > 0)
161 {
162 out << std::endl << pattern::options << std::endl;
163 for (const auto& flag : flags_)
164 out << boost::format(pattern::option) % flag->name() % flag->description() << std::endl;
165 }
166
167 if (commands_.size() > 0)
168 {
169 out << std::endl << pattern::commands << std::endl;
170 for (const auto& cmd : commands_)
171 out << boost::format(pattern::command) % cmd.second->name() % cmd.second->description() << std::endl;
172 }
173}
174
175int cli::CommandWithSubcommands::run(const cli::Command::Context& ctxt)
176{
177 po::positional_options_description pdesc;
178 pdesc.add("command", 1);
179
180 po::options_description desc("Options");
181 desc.add_options()("command", po::value<std::string>()->required(), "the command to be executed");
182
183 add_to_desc_for_flags(desc, flags_);
184
185 try
186 {
187 po::variables_map vm;
188 auto parsed = po::command_line_parser(ctxt.args)
189 .options(desc)
190 .positional(pdesc)
191 .style(po::command_line_style::unix_style)
192 .allow_unregistered()
193 .run();
194
195 po::store(parsed, vm);
196 po::notify(vm);
197
198 return commands_[vm["command"].as<std::string>()]->run(cli::Command::Context
199 {
200 ctxt.cin,
201 ctxt.cout,
202 po::collect_unrecognized(parsed.options, po::include_positional)
203 });
204 }
205 catch (const po::error& e)
206 {
207 ctxt.cout << e.what() << std::endl;
208 help(ctxt.cout);
209 return EXIT_FAILURE;
210 }
211
212 return EXIT_FAILURE;
213}
214
215cli::CommandWithFlagsAndAction::CommandWithFlagsAndAction(const Name& name, const Usage& usage, const Description& description)
216 : Command{name, usage, description}
217{
218}
219
220cli::CommandWithFlagsAndAction& cli::CommandWithFlagsAndAction::flag(const Flag::Ptr& flag)
221{
222 flags_.insert(flag);
223 return *this;
224}
225
226cli::CommandWithFlagsAndAction& cli::CommandWithFlagsAndAction::action(const Action& action)
227{
228 action_ = action;
229 return *this;
230}
231
232int cli::CommandWithFlagsAndAction::run(const Context& ctxt)
233{
234 po::options_description cd(name().as_string());
235
236 bool help_requested{false};
237 cd.add_options()("help", po::bool_switch(&help_requested), "produces a help message");
238
239 add_to_desc_for_flags(cd, flags_);
240
241 try
242 {
243 po::variables_map vm;
244 auto parsed = po::command_line_parser(ctxt.args).options(cd).style(po::command_line_style::unix_style).allow_unregistered().run();
245 po::store(parsed, vm);
246 po::notify(vm);
247
248 if (help_requested)
249 {
250 help(ctxt.cout);
251 return EXIT_SUCCESS;
252 }
253
254 return action_(cli::Command::Context
255 {
256 ctxt.cin,
257 ctxt.cout,
258 po::collect_unrecognized(parsed.options, po::exclude_positional)
259 });
260 }
261 catch (const po::error& e)
262 {
263 ctxt.cout << e.what() << std::endl;
264 help(ctxt.cout);
265 return EXIT_FAILURE;
266 }
267
268 return EXIT_FAILURE;
269}
270
271void cli::CommandWithFlagsAndAction::help(std::ostream& out)
272{
273 out << boost::format(pattern::help_for_command_with_subcommands)
274 % name().as_string() % description().as_string()
275 % name().as_string() << std::endl;
276
277 if (flags_.size() > 0)
278 {
279 out << std::endl << boost::format(pattern::options) << std::endl;
280 for (const auto& flag : flags_)
281 out << boost::format(pattern::option) % flag->name() % flag->description() << std::endl;
282 }
283}
284
285cli::cmd::Help::Help(Command& cmd)
286 : Command{cli::Name{"help"}, cli::Usage{"prints a short help message"}, cli::Description{"prints a short help message"}},
287 command{cmd}
288{
289}
290
291// From Command
292int cli::cmd::Help::run(const Context &context)
293{
294 command.help(context.cout);
295 return EXIT_FAILURE;
296}
297
298void cli::cmd::Help::help(std::ostream &out)
299{
300 command.help(out);
301}
0302
=== added file 'src/location/util/cli.h'
--- src/location/util/cli.h 1970-01-01 00:00:00 +0000
+++ src/location/util/cli.h 2016-06-30 09:21:49 +0000
@@ -0,0 +1,387 @@
1/*
2 * Copyright (C) 2016 Canonical, Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Thomas Voß <thomas.voss@canonical.com>
17 *
18 */
19#ifndef LOCATION_UTIL_CLI_H_
20#define LOCATION_UTIL_CLI_H_
21
22#include <location/util/do_not_copy_or_move.h>
23#include <location/optional.h>
24
25// TODO(tvoss): Reenable once we introduce visibility of symbols
26// #include <biometry/visibility.h>
27#define LOCATION_DLL_PUBLIC
28
29#include <iomanip>
30#include <iostream>
31#include <memory>
32#include <set>
33#include <sstream>
34#include <stdexcept>
35#include <string>
36#include <unordered_map>
37#include <vector>
38
39namespace location
40{
41namespace util
42{
43namespace cli
44{
45/// @brief ProgressBar prints a progress bar on the terminal.
46///
47/// Looks like:
48/// Prefix[===============----------] xxx.xx %
49/// |--------------- width ------------|
50class LOCATION_DLL_PUBLIC ProgressBar
51{
52public:
53 /// @brief ProgressBar initializes an instance with out, prefix and width.
54 ProgressBar(std::ostream& out, const std::string& prefix = std::string{}, std::uint32_t width = 80);
55 /// @brief ~ProgressBar cleans up and inserts a std::endl into out.
56 ~ProgressBar();
57
58 /// @brief update updates the terminal output for the given percentage.
59 void update(double percentage);
60
61private:
62 /// @cond
63 std::string prefix;
64 std::uint32_t width;
65 std::ostream& out;
66 /// @endcond
67};
68
69template<std::size_t max>
70class LOCATION_DLL_PUBLIC SizeConstrainedString
71{
72public:
73 SizeConstrainedString(const std::string& s) : s{s}
74 {
75 if(s.size() > max)
76 throw std::logic_error{"Max size exceeded " + std::to_string(max)};
77 }
78
79 const std::string& as_string() const
80 {
81 return s;
82 }
83
84 operator std::string() const
85 {
86 return s;
87 }
88
89private:
90 std::string s;
91};
92
93template<std::size_t max>
94LOCATION_DLL_PUBLIC bool operator<(const SizeConstrainedString<max>& lhs, const SizeConstrainedString<max>& rhs)
95{
96 return lhs.as_string() < rhs.as_string();
97}
98
99template<std::size_t max>
100LOCATION_DLL_PUBLIC bool operator==(const SizeConstrainedString<max>& lhs, const SizeConstrainedString<max>& rhs)
101{
102 return lhs.as_string() == rhs.as_string();
103}
104
105template<std::size_t max>
106LOCATION_DLL_PUBLIC std::ostream& operator<<(std::ostream& out, const SizeConstrainedString<max>& scs)
107{
108 return out << std::setw(max) << std::left << scs.as_string();
109}
110
111// We are imposing size constraints to ensure a consistent CLI layout.
112typedef SizeConstrainedString<15> Name;
113typedef SizeConstrainedString<60> Usage;
114typedef SizeConstrainedString<60> Description;
115
116/// @brief Flag models an input parameter to a command.
117class LOCATION_DLL_PUBLIC Flag : public DoNotCopyOrMove
118{
119public:
120 // Safe us some typing.
121 typedef std::shared_ptr<Flag> Ptr;
122
123 /// @brief notify announces a new value to the flag.
124 virtual void notify(const std::string& value) = 0;
125 /// @brief name returns the name of the Flag.
126 const Name& name() const;
127 /// @brief description returns a human-readable description of the flag.
128 const Description& description() const;
129
130protected:
131 /// @brief Flag creates a new instance, initializing name and description
132 /// from the given values.
133 Flag(const Name& name, const Description& description);
134
135private:
136 Name name_;
137 Description description_;
138};
139
140/// @brief TypedFlag implements Flag relying on operator<< and operator>> to read/write values to/from strings.
141template<typename T>
142class LOCATION_DLL_PUBLIC TypedFlag : public Flag
143{
144public:
145 typedef std::shared_ptr<TypedFlag<T>> Ptr;
146
147 TypedFlag(const Name& name, const Description& description) : Flag{name, description}
148 {
149 }
150
151 /// @brief value installs the given value in the flag.
152 TypedFlag& value(const T& value)
153 {
154 value_ = value;
155 return *this;
156 }
157
158 /// @brief value returns the optional value associated with the flag.
159 const Optional<T>& value() const
160 {
161 return value_;
162 }
163
164 /// @brief notify tries to unwrap a value of type T from value.
165 void notify(const std::string& s) override
166 {
167 std::stringstream ss{s};
168 T value; ss >> value;
169 value_ = value;
170 }
171
172private:
173 Optional<T> value_;
174};
175
176/// @brief TypedReferenceFlag implements Flag, relying on operator<</>> to convert to/from string representations,
177/// updating the given mutable reference to a value of type T.
178template<typename T>
179class LOCATION_DLL_PUBLIC TypedReferenceFlag : public Flag
180{
181public:
182 // Safe us some typing.
183 typedef std::shared_ptr<TypedReferenceFlag<T>> Ptr;
184
185 /// @brief TypedReferenceFlag initializes a new instance with name, description and value.
186 TypedReferenceFlag(const Name& name, const Description& description, T& value)
187 : Flag{name, description},
188 value_{value}
189 {
190 }
191
192 /// @brief notify tries to unwrap a value of type T from value,
193 /// relying on operator>> to read from given string s.
194 void notify(const std::string& s) override
195 {
196 std::stringstream ss{s};
197 ss >> value_.get();
198 }
199
200private:
201 std::reference_wrapper<T> value_;
202};
203
204/// @brief OptionalTypedReferenceFlag handles Optional<T> references, making sure that
205/// a value is always read on notify, even if the Optional<T> wasn't initialized previously.
206template<typename T>
207class LOCATION_DLL_PUBLIC OptionalTypedReferenceFlag : public Flag
208{
209public:
210 typedef std::shared_ptr<OptionalTypedReferenceFlag<T>> Ptr;
211
212 OptionalTypedReferenceFlag(const Name& name, const Description& description, Optional<T>& value)
213 : Flag{name, description},
214 value_{value}
215 {
216 }
217
218 /// @brief notify tries to unwrap a value of type T from value.
219 void notify(const std::string& s) override
220 {
221 std::stringstream ss{s}; T value; ss >> value;
222 value_.get() = value;
223 }
224
225private:
226 std::reference_wrapper<Optional<T>> value_;
227};
228
229/// @brief Command abstracts an individual command available from the daemon.
230class LOCATION_DLL_PUBLIC Command : public DoNotCopyOrMove
231{
232public:
233 // Safe us some typing
234 typedef std::shared_ptr<Command> Ptr;
235
236 /// @brief FlagsMissing is thrown if at least one required flag is missing.
237 struct FlagsMissing : public std::runtime_error
238 {
239 /// @brief FlagsMissing initializes a new instance.
240 FlagsMissing();
241 };
242
243 /// @brief FlagsWithWrongValue is thrown if a value passed on the command line is invalid.
244 struct FlagsWithInvalidValue : public std::runtime_error
245 {
246 /// @brief FlagsWithInvalidValue initializes a new instance.
247 FlagsWithInvalidValue();
248 };
249
250 /// @brief Context bundles information passed to Command::run invocations.
251 struct Context
252 {
253 std::istream& cin; ///< The std::istream that should be used for reading.
254 std::ostream& cout; ///< The std::ostream that should be used for writing.
255 std::vector<std::string> args; ///< The command line args.
256 };
257
258 /// @brief name returns the Name of the command.
259 virtual Name name() const;
260
261 /// @brief usage returns a short usage string for the command.
262 virtual Usage usage() const;
263
264 /// @brief description returns a longer string explaining the command.
265 virtual Description description() const;
266
267 /// @brief run puts the command to execution.
268 virtual int run(const Context& context) = 0;
269
270 /// @brief help prints information about a command to out.
271 virtual void help(std::ostream& out) = 0;
272
273protected:
274 /// @brief Command initializes a new instance with the given name, usage and description.
275 Command(const Name& name, const Usage& usage, const Description& description);
276
277 /// @brief name adjusts the name of the command to n.
278 // virtual void name(const Name& n);
279 /// @brief usage adjusts the usage string of the comand to u.
280 // virtual void usage(const Usage& u);
281 /// @brief description adjusts the description string of the command to d.
282 // virtual void description(const Description& d);
283
284private:
285 Name name_;
286 Usage usage_;
287 Description description_;
288};
289
290/// @brief CommandWithSubcommands implements Command, selecting one of a set of actions.
291class LOCATION_DLL_PUBLIC CommandWithSubcommands : public Command
292{
293public:
294 typedef std::shared_ptr<CommandWithSubcommands> Ptr;
295 typedef std::function<int(const Context&)> Action;
296
297 /// @brief CommandWithSubcommands initializes a new instance with the given name, usage and description
298 CommandWithSubcommands(const Name& name, const Usage& usage, const Description& description);
299
300 /// @brief command adds the given command to the set of known commands.
301 CommandWithSubcommands& command(const Command::Ptr& command);
302
303 /// @brief flag adds the given flag to the set of known flags.
304 CommandWithSubcommands& flag(const Flag::Ptr& flag);
305
306 // From Command
307 int run(const Context& context) override;
308 void help(std::ostream &out) override;
309
310private:
311 std::unordered_map<std::string, Command::Ptr> commands_;
312 std::set<Flag::Ptr> flags_;
313};
314
315/// @brief CommandWithFlagsAction implements Command, executing an Action after handling
316class LOCATION_DLL_PUBLIC CommandWithFlagsAndAction : public Command
317{
318public:
319 typedef std::shared_ptr<CommandWithFlagsAndAction> Ptr;
320 typedef std::function<int(const Context&)> Action;
321
322 /// @brief CommandWithFlagsAndAction initializes a new instance with the given name, usage and description
323 CommandWithFlagsAndAction(const Name& name, const Usage& usage, const Description& description);
324
325 /// @brief flag adds the given flag to the set of known flags.
326 CommandWithFlagsAndAction& flag(const Flag::Ptr& flag);
327
328 /// @brief action installs the given action.
329 CommandWithFlagsAndAction& action(const Action& action);
330
331 // From Command
332 int run(const Context& context) override;
333 void help(std::ostream &out) override;
334
335private:
336 std::set<Flag::Ptr> flags_;
337 Action action_;
338};
339
340namespace cmd
341{
342/// @brief HelpFor prints a help message for the given command on execution.
343class Help : public Command
344{
345public:
346 /// @brief HelpFor initializes a new instance with the given reference to a cmd.
347 explicit Help(Command& cmd);
348
349 // From Command
350 int run(const Context &context) override;
351 void help(std::ostream &out) override;
352
353private:
354 /// @cond
355 Command& command;
356 /// @endcond
357};
358}
359
360/// @brief args returns a vector of strings assembled from argc and argv.
361LOCATION_DLL_PUBLIC std::vector<std::string> args(int argc, char** argv);
362
363/// @brief make_flag returns a flag with the given name and description.
364template<typename T>
365LOCATION_DLL_PUBLIC typename TypedFlag<T>::Ptr make_flag(const Name& name, const Description& description)
366{
367 return std::make_shared<TypedFlag<T>>(name, description);
368}
369
370/// @brief make_flag returns a flag with the given name and description, notifying updates to value.
371template<typename T>
372LOCATION_DLL_PUBLIC typename TypedReferenceFlag<T>::Ptr make_flag(const Name& name, const Description& desc, T& value)
373{
374 return std::make_shared<TypedReferenceFlag<T>>(name, desc, value);
375}
376
377/// @brief make_flag returns a flag with the given name and description, updating the given optional value.
378template<typename T>
379LOCATION_DLL_PUBLIC typename OptionalTypedReferenceFlag<T>::Ptr make_flag(const Name& name, const Description& desc, Optional<T>& value)
380{
381 return std::make_shared<OptionalTypedReferenceFlag<T>>(name, desc, value);
382}
383}
384}
385}
386
387#endif // LOCATION_UTIL_CLI_H_
0388
=== added file 'src/location/util/do_not_copy_or_move.h'
--- src/location/util/do_not_copy_or_move.h 1970-01-01 00:00:00 +0000
+++ src/location/util/do_not_copy_or_move.h 2016-06-30 09:21:49 +0000
@@ -0,0 +1,44 @@
1/*
2 * Copyright (C) 2016 Canonical, Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Thomas Voß <thomas.voss@canonical.com>
17 *
18 */
19
20#ifndef LOCATION_UTIL_DO_NOT_COPY_OR_MOVE_H_
21#define LOCATION_UTIL_DO_NOT_COPY_OR_MOVE_H_
22
23namespace location
24{
25namespace util
26{
27/// @cond
28class DoNotCopyOrMove
29{
30public:
31 DoNotCopyOrMove(const DoNotCopyOrMove&) = delete;
32 DoNotCopyOrMove(DoNotCopyOrMove&&) = delete;
33 virtual ~DoNotCopyOrMove() = default;
34 DoNotCopyOrMove& operator=(const DoNotCopyOrMove&) = delete;
35 DoNotCopyOrMove& operator=(DoNotCopyOrMove&&) = delete;
36
37protected:
38 DoNotCopyOrMove() = default;
39};
40/// @endcond
41}
42}
43
44#endif // LOCATION_UTIL_DO_NOT_COPY_OR_MOVE_H_
045
=== added file 'src/location/util/well_known_bus.cpp'
--- src/location/util/well_known_bus.cpp 1970-01-01 00:00:00 +0000
+++ src/location/util/well_known_bus.cpp 2016-06-30 09:21:49 +0000
@@ -0,0 +1,48 @@
1/*
2 * Copyright (C) 2016 Canonical, Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Thomas Voß <thomas.voss@canonical.com>
17 *
18 */
19
20#include <location/util/well_known_bus.h>
21
22#include <boost/assign/list_of.hpp>
23#include <boost/bimap.hpp>
24
25namespace
26{
27typedef boost::bimap<std::string, core::dbus::WellKnownBus> Lut;
28const Lut& lut()
29{
30 static Lut instance = boost::assign::list_of<Lut::relation>
31 ("session", core::dbus::WellKnownBus::session)
32 ("system", core::dbus::WellKnownBus::system)
33 ("starter", core::dbus::WellKnownBus::starter);
34
35 return instance;
36}
37}
38
39std::ostream& core::dbus::operator<<(std::ostream& out, core::dbus::WellKnownBus bus)
40{
41 return out << lut().right.at(bus);
42}
43
44std::istream& core::dbus::operator>>(std::istream& in, core::dbus::WellKnownBus& bus)
45{
46 std::string s; in >> s; bus = lut().left.at(s);
47 return in;
48}
049
=== added file 'src/location/util/well_known_bus.h'
--- src/location/util/well_known_bus.h 1970-01-01 00:00:00 +0000
+++ src/location/util/well_known_bus.h 2016-06-30 09:21:49 +0000
@@ -0,0 +1,37 @@
1/*
2 * Copyright (C) 2016 Canonical, Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Thomas Voß <thomas.voss@canonical.com>
17 *
18 */
19#ifndef LOCATION_UTIL_WELL_KNOWN_BUS_H_
20#define LOCATION_UTIL_WELL_KNOWN_BUS_H_
21
22#include <core/dbus/well_known_bus.h>
23
24#include <iosfwd>
25
26namespace core
27{
28namespace dbus
29{
30// operator<< inserts bus into out.
31std::ostream& operator<<(std::ostream& out, WellKnownBus bus);
32// operator>> extracts bus from in.
33std::istream& operator>>(std::istream& in, WellKnownBus& bus);
34}
35}
36
37#endif // LOCATION_UTIL_WELL_KNOWN_BUS_H_

Subscribers

People subscribed via source and target branches

to all changes: