ubuntu-location-service  0.0.2
provider.h
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_COM_UBUNTU_LOCATION_PROVIDER_H_
19 #define LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDER_H_
20 
21 #include "com/ubuntu/location/channel.h"
22 #include "com/ubuntu/location/criteria.h"
23 #include "com/ubuntu/location/heading.h"
24 #include "com/ubuntu/location/position.h"
25 #include "com/ubuntu/location/update.h"
26 #include "com/ubuntu/location/velocity.h"
27 
28 #include <atomic>
29 #include <bitset>
30 #include <memory>
31 
32 namespace com
33 {
34 namespace ubuntu
35 {
36 namespace location
37 {
38 class Provider
39 {
40 public:
41  typedef std::shared_ptr<Provider> Ptr;
42 
43  enum class Feature : std::size_t
44  {
45  position,
46  velocity,
47  heading
48  };
49 
50  typedef std::bitset<3> FeatureFlags;
51 
52  enum class Requirement : std::size_t
53  {
54  satellites,
55  cell_network,
56  data_network,
57  monetary_spending
58  };
59 
60  typedef std::bitset<4> RequirementFlags;
61 
62  class Controller
63  {
64  public:
65  typedef std::shared_ptr<Controller> Ptr;
66 
67  template<typename T>
68  class Cache
69  {
70  public:
71  Cache() : d{ T{}, false }
72  {
73  }
74  const T& value() const { return d.value; }
75  void update(const T& new_value) { d.value = new_value; d.is_valid = true; }
76  bool is_valid() const { return d.is_valid; }
77  void invalidate() { d.is_valid = false; }
78 
79  private:
80  struct
81  {
82  T value;
83  bool is_valid;
84  } d;
85  };
86 
87  virtual ~Controller() = default;
88  Controller(const Controller&) = delete;
89  Controller& operator=(const Controller&) = delete;
90 
91  virtual void start_position_updates();
92  virtual void stop_position_updates();
93  bool are_position_updates_running() const;
94 
95  virtual void start_heading_updates();
96  virtual void stop_heading_updates();
97  bool are_heading_updates_running() const;
98 
99  virtual void start_velocity_updates();
100  virtual void stop_velocity_updates();
101  bool are_velocity_updates_running() const;
102 
103  const Cache<Update<Position>>& cached_position_update() const;
104  const Cache<Update<Heading>>& cached_heading_update() const;
105  const Cache<Update<Velocity>>& cached_velocity_update() const;
106 
107  protected:
108  friend class Provider;
109  explicit Controller(Provider& instance);
110 
111  private:
112  void on_position_updated(const Update<Position>& position);
113  void on_velocity_updated(const Update<Velocity>& velocity);
114  void on_heading_updated(const Update<Heading>& heading);
115 
116  Provider& instance;
117  std::atomic<int> position_updates_counter;
118  std::atomic<int> heading_updates_counter;
119  std::atomic<int> velocity_updates_counter;
120  ScopedChannelConnection position_update_connection;
121  ScopedChannelConnection velocity_update_connection;
122  ScopedChannelConnection heading_update_connection;
123  struct
124  {
125  Cache<Update<Position>> position;
126  Cache<Update<Velocity>> velocity;
127  Cache<Update<Heading>> heading;
128  } cached;
129  };
130 
131  virtual ~Provider() = default;
132 
133  Provider(const Provider&) = delete;
134  Provider& operator=(const Provider&) = delete;
135 
136  virtual const Controller::Ptr& state_controller() const;
137 
138  virtual ChannelConnection subscribe_to_position_updates(std::function<void(const Update<Position>&)> f);
139  virtual ChannelConnection subscribe_to_heading_updates(std::function<void(const Update<Heading>&)> f);
140  virtual ChannelConnection subscribe_to_velocity_updates(std::function<void(const Update<Velocity>&)> f);
141 
142  virtual bool supports(const Feature& f) const;
143  virtual bool requires(const Requirement& r) const;
144 
145  virtual bool matches_criteria(const Criteria&);
146 
147 protected:
148  explicit Provider(
149  const FeatureFlags& feature_flags = FeatureFlags(),
150  const RequirementFlags& requirement_flags = RequirementFlags());
151 
152  void deliver_position_updates(const Update<Position>& update);
153  void deliver_heading_updates(const Update<Heading>& update);
154  void deliver_velocity_updates(const Update<Velocity>& update);
155 
156  virtual void start_position_updates();
157  virtual void stop_position_updates();
158 
159  virtual void start_heading_updates();
160  virtual void stop_heading_updates();
161 
162  virtual void start_velocity_updates();
163  virtual void stop_velocity_updates();
164 
165 private:
166  FeatureFlags feature_flags;
167  RequirementFlags requirement_flags;
168  Channel<Update<Position>> position_updates_channel;
169  Channel<Update<Heading>> heading_updates_channel;
170  Channel<Update<Velocity>> velocity_updates_channel;
171  Controller::Ptr controller;
172 };
173 }
174 }
175 }
176 
177 #endif // LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDER_H_