~thomas-voss/location-service/fix-1347887

« back to all changes in this revision

Viewing changes to src/location_service/com/ubuntu/location/service/main.cpp

This MP consolidates multiple related changes together, with the goal of:

(1.) Make the service instance accessible via a cli. Useful for testing scenarios.
(2.) To cut down time-to-first-fix (ttff) by:
  (2.1) Leveraging SUPL and other supplementary data downloaded over ordinary data connections.
  (2.2) Enabling network-based positioning providers to acquire fast position estimates.

In more detail:

* Added tests for daemon and cli.
* Unified daemon and cli header and implementation files.
* Add a command-line interface to the service.
* Split up provider selection policy to rely on an interface ProviderEnumerator to ease in testing.
* Trimmed down on types.
* Removed connectivity API draft to prepare for simpler approach.
* Refactored includes.
* Added a configuration option to handle cell and wifi ID reporting.
* Add a mock for a connectivity API exposed to providers and reporters.
* Add units for connectivity api.
* Refactor cell class into namespace radio. Fixes: 1226204, 1248973, 1281817

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
 
#include "program_options.h"
19
 
 
20
 
#include "com/ubuntu/location/provider_factory.h"
21
 
 
22
 
#include "com/ubuntu/location/service/default_configuration.h"
23
 
#include "com/ubuntu/location/service/implementation.h"
24
 
 
25
 
#include <core/dbus/announcer.h>
26
 
#include <core/dbus/asio/executor.h>
27
 
 
28
 
#include <thread>
29
 
 
30
 
namespace cul = com::ubuntu::location;
31
 
namespace culs = com::ubuntu::location::service;
32
 
namespace dbus = core::dbus;
33
 
 
34
 
int main(int argc, char** argv)
35
 
{
36
 
    cul::ProgramOptions options;
37
 
 
38
 
    options.add("help", "Produces this help message");
39
 
    options.add(
40
 
        "bus", 
41
 
        "The well-known bus to announce the service upon", 
42
 
        std::string{"session"});
43
 
    options.add_composed<std::vector<std::string>>(
44
 
        "provider", 
45
 
        "The providers that should be added to the engine");
46
 
 
47
 
    if (!options.parse_from_command_line_args(argc, argv))
48
 
        return EXIT_FAILURE;
49
 
 
50
 
    if (options.value_count_for_key("help") > 0)
51
 
    {
52
 
        options.print_help(std::cout);
53
 
        return EXIT_SUCCESS;
54
 
    }
55
 
    
56
 
    if (options.value_count_for_key("provider") == 0)
57
 
    {
58
 
        std::cout << "A set of providers need to be specified. The following providers are known:" << std::endl;
59
 
        cul::ProviderFactory::instance().enumerate(
60
 
            [](const std::string& name, const cul::ProviderFactory::Factory&)
61
 
            {
62
 
                std::cout << "\t" << name << std::endl;
63
 
            });
64
 
        return EXIT_FAILURE;
65
 
    }
66
 
 
67
 
    auto selected_providers = options.value_for_key<std::vector<std::string>>("provider");
68
 
 
69
 
    std::map<std::string, cul::ProviderFactory::Configuration> config_lut;
70
 
    std::set<cul::Provider::Ptr> instantiated_providers;
71
 
 
72
 
    for (const std::string& provider : selected_providers)
73
 
    {
74
 
        std::cout << "Instantiating and configuring: " << provider << std::endl;
75
 
        options.enumerate_unrecognized_options(
76
 
            [&config_lut, provider](const std::string& s)
77
 
            {
78
 
                std::stringstream in(s);
79
 
                std::string key, value;
80
 
                
81
 
                std::getline(in, key, '=');
82
 
                std::getline(in, value, '=');
83
 
                
84
 
                std::size_t pos = key.find(provider);
85
 
                if (pos == std::string::npos)
86
 
                    return;
87
 
                static const std::string option_marker{"--"};
88
 
                static const std::string scope_separator{"::"};
89
 
                key = key.erase(key.find_first_of(option_marker), option_marker.size()); 
90
 
                key = key.erase(key.find_first_of(provider), provider.size());
91
 
                key = key.erase(key.find_first_of(scope_separator), scope_separator.size()); 
92
 
                
93
 
                std::cout << "\t" << key << " -> " << value << std::endl;
94
 
 
95
 
                config_lut[provider].put(key, value);
96
 
            });
97
 
 
98
 
        try
99
 
        {
100
 
            auto p = cul::ProviderFactory::instance().create_provider_for_name_with_config(
101
 
                provider, 
102
 
                config_lut[provider]);
103
 
 
104
 
            if (p)
105
 
                instantiated_providers.insert(p);
106
 
            else
107
 
                throw std::runtime_error("Problem instantiating provider");
108
 
            
109
 
        } catch(const std::runtime_error& e)
110
 
        {
111
 
            std::cerr << "Exception instantiating provider: " << e.what() << " ... Aborting now." << std::endl;
112
 
            return EXIT_FAILURE;
113
 
        }
114
 
    }
115
 
    
116
 
    static const std::map<std::string, dbus::WellKnownBus> lut = 
117
 
    {
118
 
        {"session", dbus::WellKnownBus::session},
119
 
        {"system", dbus::WellKnownBus::system},
120
 
    };
121
 
 
122
 
    dbus::Bus::Ptr bus
123
 
    {
124
 
        new dbus::Bus{lut.at(options.value_for_key<std::string>("bus"))}
125
 
    };
126
 
 
127
 
    bus->install_executor(dbus::asio::make_executor(bus));
128
 
 
129
 
    culs::DefaultConfiguration config;
130
 
    
131
 
    auto location_service =
132
 
            dbus::announce_service_on_bus<
133
 
                culs::Interface, 
134
 
                culs::Implementation
135
 
            >(
136
 
                bus,
137
 
                config.the_engine(
138
 
                    instantiated_providers,
139
 
                    config.the_provider_selection_policy()),
140
 
                config.the_permission_manager());
141
 
    
142
 
    std::thread t{[bus](){bus->run();}};
143
 
    
144
 
    if (t.joinable())
145
 
        t.join();
146
 
 
147
 
    return EXIT_SUCCESS;
148
 
}