~ci-train-bot/location-service/location-service-ubuntu-yakkety-1895

« back to all changes in this revision

Viewing changes to src/location_service/com/ubuntu/location/providers/geoclue/provider.cpp

  • Committer: Thomas Voß
  • Date: 2013-05-28 14:20:45 UTC
  • Revision ID: thomas.voss@canonical.com-20130528142045-kq5umqdmm4o53vwk
Initial push.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "com/ubuntu/location/providers/geoclue/provider.h"
 
2
 
 
3
#include "com/ubuntu/location/providers/geoclue/geoclue.h"
 
4
 
 
5
#include <thread>
 
6
 
 
7
namespace cul = com::ubuntu::location;
 
8
namespace culpg = com::ubuntu::location::providers::geoclue;
 
9
 
 
10
namespace dbus = org::freedesktop::dbus;
 
11
 
 
12
namespace
 
13
{
 
14
dbus::Bus::Ptr the_session_bus()
 
15
{
 
16
    static dbus::Bus::Ptr session_bus = std::make_shared<dbus::Bus>(dbus::WellKnownBus::session);
 
17
    return session_bus;
 
18
}
 
19
}
 
20
 
 
21
struct culpg::Provider::Private
 
22
{
 
23
    Private(const culpg::Provider::Configuration& config) 
 
24
            : bus(the_session_bus()),
 
25
              service(dbus::Service::use_service(bus, config.name)),
 
26
              object(service->object_for_path(config.path)),
 
27
              signal_position_changed(object->get_signal<org::freedesktop::Geoclue::Position::Signals::PositionChanged>()),
 
28
              signal_velocity_changed(object->get_signal<org::freedesktop::Geoclue::Velocity::Signals::VelocityChanged>())  
 
29
    {        
 
30
    }
 
31
    
 
32
    void start() 
 
33
    { 
 
34
        if (!worker.joinable()) 
 
35
            worker = std::move(std::thread{std::bind(&dbus::Bus::run, bus)});
 
36
    }
 
37
 
 
38
    void stop() 
 
39
    { 
 
40
        bus->stop();
 
41
        if (worker.joinable())
 
42
            worker.join();
 
43
    }
 
44
 
 
45
    dbus::Bus::Ptr bus;
 
46
    dbus::Service::Ptr service;
 
47
    dbus::Object::Ptr object;
 
48
    dbus::Signal<
 
49
        org::freedesktop::Geoclue::Position::Signals::PositionChanged, 
 
50
        org::freedesktop::Geoclue::Position::Signals::PositionChanged::ArgumentType
 
51
        >::Ptr signal_position_changed;
 
52
    dbus::Signal<
 
53
        org::freedesktop::Geoclue::Velocity::Signals::VelocityChanged, 
 
54
        org::freedesktop::Geoclue::Velocity::Signals::VelocityChanged::ArgumentType
 
55
        >::Ptr signal_velocity_changed;
 
56
    dbus::signals::ScopedConnection position_updates_connection;
 
57
    dbus::signals::ScopedConnection velocity_updates_connection;
 
58
 
 
59
    std::thread worker;
 
60
};
 
61
 
 
62
cul::Provider::Ptr culpg::Provider::create_instance(const cul::ProviderFactory::Configuration& config)
 
63
{
 
64
    culpg::Provider::Configuration pConfig;
 
65
    pConfig.name = config.count("name") > 0 ? config.at("name") : throw std::runtime_error("Missing bus-name");
 
66
    pConfig.path = config.count("path") > 0 ? config.at("path") : throw std::runtime_error("Missing bus-path");
 
67
    return cul::Provider::Ptr{new culpg::Provider{pConfig}};
 
68
}
 
69
 
 
70
const cul::Provider::FeatureFlags& culpg::Provider::default_feature_flags()
 
71
{
 
72
    static const cul::Provider::FeatureFlags flags{"001"};
 
73
    return flags;
 
74
}
 
75
 
 
76
const cul::Provider::RequirementFlags& culpg::Provider::default_requirement_flags()
 
77
{
 
78
    static const cul::Provider::RequirementFlags flags{"1010"};
 
79
    return flags;
 
80
}
 
81
 
 
82
culpg::Provider::Provider(const culpg::Provider::Configuration& config) 
 
83
        : com::ubuntu::location::Provider(config.features, config.requirements),
 
84
          d(new Private(config))
 
85
{
 
86
    d->position_updates_connection = 
 
87
            d->signal_position_changed->connect(
 
88
                [this](const org::freedesktop::Geoclue::Position::Signals::PositionChanged::ArgumentType& arg)
 
89
                {
 
90
                    org::freedesktop::Geoclue::Position::FieldFlags flags{static_cast<unsigned long>(std::get<0>(arg))};
 
91
                    cul::Update<cul::Position> update
 
92
                    {
 
93
                        {
 
94
                            flags.test(org::freedesktop::Geoclue::Position::Field::latitude) ? 
 
95
                                    cul::wgs84::Latitude{std::get<2>(arg)* cul::units::Degrees} : cul::wgs84::Latitude{},
 
96
                            flags.test(org::freedesktop::Geoclue::Position::Field::longitude) ? 
 
97
                                    cul::wgs84::Longitude{std::get<3>(arg)* cul::units::Degrees} : cul::wgs84::Longitude{},
 
98
                            flags.test(org::freedesktop::Geoclue::Position::Field::altitude) ? 
 
99
                                    cul::wgs84::Altitude{std::get<4>(arg)* cul::units::Meters} : cul::wgs84::Altitude{}
 
100
                        },
 
101
                        cul::Clock::now()
 
102
                    };
 
103
                    this->deliver_position_updates(update);
 
104
                });
 
105
 
 
106
    d->velocity_updates_connection = 
 
107
            d->signal_velocity_changed->connect(
 
108
                [this](const org::freedesktop::Geoclue::Velocity::Signals::VelocityChanged::ArgumentType& arg)
 
109
                {
 
110
                    org::freedesktop::Geoclue::Velocity::FieldFlags flags{static_cast<unsigned long>(std::get<0>(arg))};
 
111
                    if (flags.none())
 
112
                        return;
 
113
                    if (flags.test(org::freedesktop::Geoclue::Velocity::Field::speed))
 
114
                    {
 
115
                        cul::Update<cul::Velocity> update
 
116
                        {
 
117
                            std::get<2>(arg) * cul::units::MetersPerSecond,
 
118
                            cul::Clock::now()
 
119
                        };
 
120
                        this->deliver_velocity_updates(update);
 
121
                    }
 
122
 
 
123
                    if (flags.test(org::freedesktop::Geoclue::Velocity::Field::direction))
 
124
                    {
 
125
                        cul::Update<cul::Heading> update
 
126
                        {
 
127
                            std::get<3>(arg) * cul::units::Degrees,
 
128
                            cul::Clock::now()
 
129
                        };
 
130
                            
 
131
                        this->deliver_heading_updates(update);
 
132
                    }
 
133
                });
 
134
 
 
135
    auto info = d->object->invoke_method_synchronously<
 
136
        org::freedesktop::Geoclue::GetProviderInfo, 
 
137
        org::freedesktop::Geoclue::GetProviderInfo::ResultType>();
 
138
    auto status = d->object->invoke_method_synchronously<
 
139
        org::freedesktop::Geoclue::GetStatus, 
 
140
        org::freedesktop::Geoclue::GetStatus::ResultType>();
 
141
        
 
142
    std::cout << "GeoclueProvider: [" 
 
143
              << std::get<0>(info.value()) << ", " 
 
144
              << std::get<1>(info.value()) << ","
 
145
              << static_cast<org::freedesktop::Geoclue::Status>(status.value()) << "]" <<std::endl;
 
146
}
 
147
 
 
148
culpg::Provider::~Provider() noexcept
 
149
{
 
150
    d->stop();
 
151
}
 
152
 
 
153
bool culpg::Provider::matches_criteria(const cul::Criteria&)
 
154
{
 
155
    return true;
 
156
}
 
157
 
 
158
void culpg::Provider::start_position_updates()
 
159
{
 
160
    d->start();
 
161
}
 
162
 
 
163
void culpg::Provider::stop_position_updates()
 
164
{
 
165
    d->stop();
 
166
}
 
167
 
 
168
void culpg::Provider::start_velocity_updates()
 
169
{
 
170
    d->start();
 
171
}
 
172
 
 
173
void culpg::Provider::stop_velocity_updates()
 
174
{
 
175
    d->stop();
 
176
}    
 
177
 
 
178
void culpg::Provider::start_heading_updates()
 
179
{
 
180
    d->start();
 
181
}
 
182
 
 
183
void culpg::Provider::stop_heading_updates()
 
184
{
 
185
    d->stop();
 
186
}