~thomas-voss/location-service/add-snapcraft-setup-next

« back to all changes in this revision

Viewing changes to src/location/providers/geoclue/provider.cpp

Merge lp:~thomas-voss/location-service/simplify-provider-interface.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright © 2012-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
 
 *              Manuel de la Pena <manuel.delapena@canonial.com>
18
 
 */
19
 
 
20
 
#include "provider.h"
21
 
 
22
 
namespace dbus = core::dbus;
23
 
 
24
 
namespace
25
 
{
26
 
dbus::Bus::Ptr the_session_bus()
27
 
{
28
 
    static dbus::Bus::Ptr session_bus = std::make_shared<dbus::Bus>(dbus::WellKnownBus::session);
29
 
    return session_bus;
30
 
}
31
 
}
32
 
 
33
 
void location::providers::geoclue::Provider::start()
34
 
{
35
 
    if (!worker.joinable())
36
 
        worker = std::move(std::thread{std::bind(&dbus::Bus::run, bus)});
37
 
}
38
 
 
39
 
void location::providers::geoclue::Provider::stop()
40
 
{
41
 
    bus->stop();
42
 
    if (worker.joinable())
43
 
        worker.join();
44
 
}
45
 
 
46
 
void location::providers::geoclue::Provider::on_position_changed(const fd::Geoclue::Position::Signals::PositionChanged::ArgumentType& arg)
47
 
{
48
 
    fd::Geoclue::Position::FieldFlags flags{static_cast<unsigned long>(std::get<0>(arg))};
49
 
    location::Position pos
50
 
    {
51
 
        flags.test(fd::Geoclue::Position::Field::latitude) ?
52
 
            location::wgs84::Latitude{std::get<2>(arg)* location::units::Degrees} : location::wgs84::Latitude{},
53
 
        flags.test(fd::Geoclue::Position::Field::longitude) ?
54
 
            location::wgs84::Longitude{std::get<3>(arg)* location::units::Degrees} : location::wgs84::Longitude{}
55
 
    };
56
 
 
57
 
    if (flags.test(fd::Geoclue::Position::Field::altitude))
58
 
        pos.altitude = location::wgs84::Altitude{std::get<4>(arg)* location::units::Meters};
59
 
 
60
 
    location::Update<location::Position> update(pos);
61
 
    mutable_updates().position(update);
62
 
}
63
 
 
64
 
void location::providers::geoclue::Provider::on_velocity_changed(const fd::Geoclue::Velocity::Signals::VelocityChanged::ArgumentType& arg)
65
 
{
66
 
    fd::Geoclue::Velocity::FieldFlags flags{static_cast<unsigned long>(std::get<0>(arg))};
67
 
    if (flags.none())
68
 
        return;
69
 
    if (flags.test(fd::Geoclue::Velocity::Field::speed))
70
 
    {
71
 
        location::Update<location::Velocity> update
72
 
        {
73
 
            std::get<2>(arg) * location::units::MetersPerSecond,
74
 
            location::Clock::now()
75
 
        };
76
 
        mutable_updates().velocity(update);
77
 
    }
78
 
 
79
 
    if (flags.test(fd::Geoclue::Velocity::Field::direction))
80
 
    {
81
 
        location::Update<location::Heading> update
82
 
        {
83
 
            std::get<3>(arg) * location::units::Degrees,
84
 
            location::Clock::now()
85
 
        };
86
 
 
87
 
        mutable_updates().heading(update);
88
 
    }
89
 
}
90
 
 
91
 
location::Provider::Ptr location::providers::geoclue::Provider::create_instance(const location::ProviderFactory::Configuration& config)
92
 
{
93
 
    location::providers::geoclue::Provider::Configuration pConfig;
94
 
    pConfig.name = config.count(Configuration::key_name()) > 0 ?
95
 
                   config.get<std::string>(Configuration::key_name()) : throw std::runtime_error("Missing bus-name");
96
 
    pConfig.path = config.count(Configuration::key_path()) > 0 ?
97
 
                   config.get<std::string>(Configuration::key_path()) : throw std::runtime_error("Missing bus-path");
98
 
    return location::Provider::Ptr{new location::providers::geoclue::Provider{pConfig}};
99
 
}
100
 
 
101
 
location::providers::geoclue::Provider::Provider(const location::providers::geoclue::Provider::Configuration& config)
102
 
        : location::Provider(config.features, config.requirements),
103
 
          bus(the_session_bus()),
104
 
          service(dbus::Service::use_service(bus, config.name)),
105
 
          object(service->object_for_path(config.path)),
106
 
          signal_position_changed(object->get_signal<fd::Geoclue::Position::Signals::PositionChanged>()),
107
 
          signal_velocity_changed(object->get_signal<fd::Geoclue::Velocity::Signals::VelocityChanged>())
108
 
{
109
 
    position_updates_connection = signal_position_changed->connect(
110
 
            std::bind(&location::providers::geoclue::Provider::on_position_changed, this, std::placeholders::_1));
111
 
    velocity_updates_connection = signal_velocity_changed->connect(
112
 
            std::bind(&location::providers::geoclue::Provider::on_velocity_changed, this, std::placeholders::_1));
113
 
 
114
 
    auto info = object->invoke_method_synchronously<
115
 
        fd::Geoclue::GetProviderInfo,
116
 
        fd::Geoclue::GetProviderInfo::ResultType>();
117
 
    auto status = object->invoke_method_synchronously<
118
 
        fd::Geoclue::GetStatus,
119
 
        fd::Geoclue::GetStatus::ResultType>();
120
 
        
121
 
    std::cout << "GeoclueProvider: [" 
122
 
              << std::get<0>(info.value()) << ", " 
123
 
              << std::get<1>(info.value()) << ","
124
 
              << static_cast<fd::Geoclue::Status>(status.value()) << "]" <<std::endl;
125
 
}
126
 
 
127
 
location::providers::geoclue::Provider::~Provider() noexcept
128
 
{
129
 
    stop();
130
 
}
131
 
 
132
 
bool location::providers::geoclue::Provider::matches_criteria(const location::Criteria&)
133
 
{
134
 
    return true;
135
 
}
136
 
 
137
 
void location::providers::geoclue::Provider::start_position_updates()
138
 
{
139
 
    start();
140
 
}
141
 
 
142
 
void location::providers::geoclue::Provider::stop_position_updates()
143
 
{
144
 
    stop();
145
 
}
146
 
 
147
 
void location::providers::geoclue::Provider::start_velocity_updates()
148
 
{
149
 
    start();
150
 
}
151
 
 
152
 
void location::providers::geoclue::Provider::stop_velocity_updates()
153
 
{
154
 
    stop();
155
 
}    
156
 
 
157
 
void location::providers::geoclue::Provider::start_heading_updates()
158
 
{
159
 
    start();
160
 
}
161
 
 
162
 
void location::providers::geoclue::Provider::stop_heading_updates()
163
 
{
164
 
    stop();
165
 
}