Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(110)

Side by Side Diff: content/browser/geolocation/wifi_data_provider.h

Issue 10535157: [WIP] attempt to allow chrome OS to inject its wifi data provider (Closed) Base URL: http://git.chromium.org/chromium/src.git@remove_radio
Patch Set: Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // A device data provider provides data from the device that is used by a 5 // A device data provider provides data from the device that is used by a
6 // NetworkLocationProvider to obtain a position fix. This data may be either 6 // NetworkLocationProvider to obtain a position fix. This data may be either
7 // cell radio data or wifi data. For a given type of data, we use a singleton 7 // cell radio data or wifi data. For a given type of data, we use a singleton
8 // instance of the device data provider, which is used by multiple 8 // instance of the device data provider, which is used by multiple
9 // NetworkLocationProvider objects. 9 // NetworkLocationProvider objects.
10 // 10 //
11 // This file providers DeviceDataProvider, which provides static methods to 11 // This file providers WifiDataProvider, which provides static methods to
12 // access the singleton instance. The singleton instance uses a private 12 // access the singleton instance. The singleton instance uses a private
13 // implementation to abstract across platforms and also to allow mock providers 13 // implementation to abstract across platforms and also to allow mock providers
14 // to be used for testing. 14 // to be used for testing.
15 // 15 //
16 // This file also provides DeviceDataProviderImplBase, a base class which 16 // This file also provides WifiDataProviderImplBase, a base class which
17 // provides commom functionality for the private implementations. 17 // provides commom functionality for the private implementations.
18 // 18 //
19 // This file also declares the data structures used to represent cell radio data 19 // This file also declares the data structures used to represent cell radio data
20 // and wifi data. 20 // and wifi data.
21 21
22 #ifndef CONTENT_BROWSER_GEOLOCATION_DEVICE_DATA_PROVIDER_H_ 22 #ifndef CONTENT_BROWSER_GEOLOCATION_DEVICE_DATA_PROVIDER_H_
23 #define CONTENT_BROWSER_GEOLOCATION_DEVICE_DATA_PROVIDER_H_ 23 #define CONTENT_BROWSER_GEOLOCATION_DEVICE_DATA_PROVIDER_H_
24 #pragma once 24 #pragma once
25 25
26 #include <set> 26 #include <set>
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
63 63
64 // Determines whether a new set of WiFi data differs significantly from this. 64 // Determines whether a new set of WiFi data differs significantly from this.
65 bool DiffersSignificantly(const WifiData& other) const; 65 bool DiffersSignificantly(const WifiData& other) const;
66 66
67 // Store access points as a set, sorted by MAC address. This allows quick 67 // Store access points as a set, sorted by MAC address. This allows quick
68 // comparison of sets for detecting changes and for caching. 68 // comparison of sets for detecting changes and for caching.
69 typedef std::set<AccessPointData, AccessPointDataLess> AccessPointDataSet; 69 typedef std::set<AccessPointData, AccessPointDataLess> AccessPointDataSet;
70 AccessPointDataSet access_point_data; 70 AccessPointDataSet access_point_data;
71 }; 71 };
72 72
73 template<typename DataType> 73 class WifiDataProviderImplBase;
74 class DeviceDataProvider;
75 74
76 // This class just exists to work-around MSVC2005 not being able to have a 75 // A device data provider
77 // template class implement RefCountedThreadSafe 76 //
78 class CONTENT_EXPORT DeviceDataProviderImplBaseHack 77 // We use a singleton instance of this class which is shared by multiple network
79 : public base::RefCountedThreadSafe<DeviceDataProviderImplBaseHack> { 78 // location providers. These location providers access the instance through the
80 protected: 79 // Register and Unregister methods.
81 friend class base::RefCountedThreadSafe<DeviceDataProviderImplBaseHack>; 80 class WifiDataProvider : public base::NonThreadSafe {
82 virtual ~DeviceDataProviderImplBaseHack() {} 81 public:
82 // Interface to be implemented by listeners to a device data provider.
83 class ListenerInterface {
84 public:
85 // Will be called in the context of the thread that called Register().
86 virtual void DeviceDataUpdateAvailable(WifiDataProvider* provider) = 0;
87 virtual ~ListenerInterface() {}
88 };
89
90 // Sets the factory function which will be used by Register to create the
91 // implementation used by the singleton instance. This factory approach is
92 // used to abastract accross both platform-specific implementation and to
93 // inject mock implementations for testing.
94 typedef WifiDataProviderImplBase* (*ImplFactoryFunction)(void);
95 static void SetFactory(ImplFactoryFunction factory_function_in);
96 static void ResetFactory();
97
98 // Adds a listener, which will be called back with DeviceDataUpdateAvailable
99 // whenever new data is available. Returns the singleton instance.
100 static WifiDataProvider* Register(ListenerInterface* listener);
101
102 // Removes a listener. If this is the last listener, deletes the singleton
103 // instance. Return value indicates success.
104 static bool Unregister(ListenerInterface* listener);
105
106 // Provides whatever data the provider has, which may be nothing. Return
107 // value indicates whether this is all the data the provider could ever
108 // obtain.
109 bool GetData(WifiData* data);
110
111 private:
112 // Private constructor and destructor, callers access singleton through
113 // Register and Unregister.
114 WifiDataProvider();
115 virtual ~WifiDataProvider();
116
117 void AddListener(ListenerInterface* listener);
118 bool RemoveListener(ListenerInterface* listener);
119
120 bool has_listeners() const;
121
122 bool StartDataProvider();
123 void StopDataProvider();
124
125 CONTENT_EXPORT static WifiDataProviderImplBase* DefaultFactoryFunction();
126
127 // The singleton-like instance of this class. (Not 'true' singleton, as it
128 // may go through multiple create/destroy/create cycles per process instance,
129 // e.g. when under test).
130 CONTENT_EXPORT static WifiDataProvider* instance_;
131
132 // The factory function used to create the singleton instance.
133 CONTENT_EXPORT static ImplFactoryFunction factory_function_;
134
135 // The internal implementation.
136 scoped_refptr<WifiDataProviderImplBase> impl_;
137
138 DISALLOW_COPY_AND_ASSIGN(WifiDataProvider);
83 }; 139 };
84 140
85 // See class DeviceDataProvider for the public client API. 141
86 // DeviceDataProvider uses containment to hide platform-specific implementation 142 // See class WifiDataProvider for the public client API.
143 // WifiDataProvider uses containment to hide platform-specific implementation
87 // details from common code. This class provides common functionality for these 144 // details from common code. This class provides common functionality for these
88 // contained implementation classes. This is a modified pimpl pattern: this 145 // contained implementation classes. This is a modified pimpl pattern: this
89 // class needs to be in the public header due to use of templating. 146 // class needs to be in the public header due to use of templating.
90 template<typename DataType> 147 class WifiDataProviderImplBase
91 class DeviceDataProviderImplBase : public DeviceDataProviderImplBaseHack { 148 : public base::RefCountedThreadSafe<WifiDataProviderImplBase> {
92 public: 149 public:
93 DeviceDataProviderImplBase() 150 WifiDataProviderImplBase()
94 : container_(NULL), client_loop_(MessageLoop::current()) { 151 : container_(NULL), client_loop_(MessageLoop::current()) {
95 DCHECK(client_loop_); 152 DCHECK(client_loop_);
96 } 153 }
97 154
98 virtual bool StartDataProvider() = 0; 155 virtual bool StartDataProvider() = 0;
99 virtual void StopDataProvider() = 0; 156 virtual void StopDataProvider() = 0;
100 virtual bool GetData(DataType* data) = 0; 157 virtual bool GetData(WifiData* data) = 0;
101 158
102 // Sets the container of this class, which is of type DeviceDataProvider. 159 // Sets the container of this class, which is of type WifiDataProvider.
103 // This is required to pass as a parameter when making the callback to 160 // This is required to pass as a parameter when making the callback to
104 // listeners. 161 // listeners.
105 void SetContainer(DeviceDataProvider<DataType>* container) { 162 void SetContainer(WifiDataProvider* container) {
106 DCHECK(CalledOnClientThread()); 163 DCHECK(CalledOnClientThread());
107 container_ = container; 164 container_ = container;
108 } 165 }
109 166
110 typedef typename DeviceDataProvider<DataType>::ListenerInterface 167 typedef WifiDataProvider::ListenerInterface ListenerInterface;
111 ListenerInterface;
112 void AddListener(ListenerInterface* listener) { 168 void AddListener(ListenerInterface* listener) {
113 DCHECK(CalledOnClientThread()); 169 DCHECK(CalledOnClientThread());
114 listeners_.insert(listener); 170 listeners_.insert(listener);
115 } 171 }
116 bool RemoveListener(ListenerInterface* listener) { 172 bool RemoveListener(ListenerInterface* listener) {
117 DCHECK(CalledOnClientThread()); 173 DCHECK(CalledOnClientThread());
118 return listeners_.erase(listener) == 1; 174 return listeners_.erase(listener) == 1;
119 } 175 }
120 176
121 bool has_listeners() const { 177 bool has_listeners() const {
122 DCHECK(CalledOnClientThread()); 178 DCHECK(CalledOnClientThread());
123 return !listeners_.empty(); 179 return !listeners_.empty();
124 } 180 }
125 181
126 protected: 182 protected:
127 virtual ~DeviceDataProviderImplBase() { 183 friend class base::RefCountedThreadSafe<WifiDataProviderImplBase>;
184 virtual ~WifiDataProviderImplBase() {
128 DCHECK(CalledOnClientThread()); 185 DCHECK(CalledOnClientThread());
129 } 186 }
130 187
131 // Calls DeviceDataUpdateAvailable() on all registered listeners. 188 // Calls DeviceDataUpdateAvailable() on all registered listeners.
132 typedef std::set<ListenerInterface*> ListenersSet; 189 typedef std::set<ListenerInterface*> ListenersSet;
133 void NotifyListeners() { 190 void NotifyListeners() {
134 // Always make the notify callback via a posted task, so we can unwind 191 // Always make the notify callback via a posted task, so we can unwind
135 // callstack here and make callback without causing client re-entrancy. 192 // callstack here and make callback without causing client re-entrancy.
136 client_loop_->PostTask(FROM_HERE, base::Bind( 193 client_loop_->PostTask(FROM_HERE, base::Bind(
137 &DeviceDataProviderImplBase<DataType>::NotifyListenersInClientLoop, 194 &WifiDataProviderImplBase::NotifyListenersInClientLoop,
138 this)); 195 this));
139 } 196 }
140 197
141 bool CalledOnClientThread() const { 198 bool CalledOnClientThread() const {
142 return MessageLoop::current() == this->client_loop_; 199 return MessageLoop::current() == this->client_loop_;
143 } 200 }
144 201
145 MessageLoop* client_loop() const { 202 MessageLoop* client_loop() const {
146 return client_loop_; 203 return client_loop_;
147 } 204 }
148 205
149 private: 206 private:
150 void NotifyListenersInClientLoop() { 207 void NotifyListenersInClientLoop() {
151 DCHECK(CalledOnClientThread()); 208 DCHECK(CalledOnClientThread());
152 // It's possible that all the listeners (and the container) went away 209 // It's possible that all the listeners (and the container) went away
153 // whilst this task was pending. This is fine; the loop will be a no-op. 210 // whilst this task was pending. This is fine; the loop will be a no-op.
154 typename ListenersSet::const_iterator iter = listeners_.begin(); 211 ListenersSet::const_iterator iter = listeners_.begin();
155 while (iter != listeners_.end()) { 212 while (iter != listeners_.end()) {
156 ListenerInterface* listener = *iter; 213 ListenerInterface* listener = *iter;
157 ++iter; // Advance iter before callback, in case listener unregisters. 214 ++iter; // Advance iter before callback, in case listener unregisters.
158 listener->DeviceDataUpdateAvailable(container_); 215 listener->DeviceDataUpdateAvailable(container_);
159 } 216 }
160 } 217 }
161 218
162 DeviceDataProvider<DataType>* container_; 219 WifiDataProvider* container_;
163 220
164 // Reference to the client's message loop, all callbacks and access to 221 // Reference to the client's message loop, all callbacks and access to
165 // the listeners_ member should happen in this context. 222 // the listeners_ member should happen in this context.
166 MessageLoop* client_loop_; 223 MessageLoop* client_loop_;
167 224
168 ListenersSet listeners_; 225 ListenersSet listeners_;
169 226
170 DISALLOW_COPY_AND_ASSIGN(DeviceDataProviderImplBase); 227 DISALLOW_COPY_AND_ASSIGN(WifiDataProviderImplBase);
171 }; 228 };
172 229
173 typedef DeviceDataProviderImplBase<WifiData> WifiDataProviderImplBase;
174
175 // A device data provider
176 //
177 // We use a singleton instance of this class which is shared by multiple network
178 // location providers. These location providers access the instance through the
179 // Register and Unregister methods.
180 template<typename DataType>
181 class DeviceDataProvider : public base::NonThreadSafe {
182 public:
183 // Interface to be implemented by listeners to a device data provider.
184 class ListenerInterface {
185 public:
186 // Will be called in the context of the thread that called Register().
187 virtual void DeviceDataUpdateAvailable(
188 DeviceDataProvider<DataType>* provider) = 0;
189 virtual ~ListenerInterface() {}
190 };
191
192 // Sets the factory function which will be used by Register to create the
193 // implementation used by the singleton instance. This factory approach is
194 // used to abastract accross both platform-specific implementation and to
195 // inject mock implementations for testing.
196 typedef DeviceDataProviderImplBase<DataType>* (*ImplFactoryFunction)(void);
197 static void SetFactory(ImplFactoryFunction factory_function_in) {
198 factory_function_ = factory_function_in;
199 }
200
201 static void ResetFactory() {
202 factory_function_ = DefaultFactoryFunction;
203 }
204
205 // Adds a listener, which will be called back with DeviceDataUpdateAvailable
206 // whenever new data is available. Returns the singleton instance.
207 static DeviceDataProvider* Register(ListenerInterface* listener) {
208 bool need_to_start_thread = false;
209 if (!instance_) {
210 instance_ = new DeviceDataProvider();
211 need_to_start_thread = true;
212 }
213 DCHECK(instance_);
214 DCHECK(instance_->CalledOnValidThread());
215 instance_->AddListener(listener);
216 // Start the provider after adding the listener, to avoid any race in
217 // it receiving an early callback.
218 if (need_to_start_thread) {
219 bool started = instance_->StartDataProvider();
220 DCHECK(started);
221 }
222 return instance_;
223 }
224
225 // Removes a listener. If this is the last listener, deletes the singleton
226 // instance. Return value indicates success.
227 static bool Unregister(ListenerInterface* listener) {
228 DCHECK(instance_);
229 DCHECK(instance_->CalledOnValidThread());
230 DCHECK(instance_->has_listeners());
231 if (!instance_->RemoveListener(listener)) {
232 return false;
233 }
234 if (!instance_->has_listeners()) {
235 // Must stop the provider (and any implementation threads) before
236 // destroying to avoid any race conditions in access to the provider in
237 // the destructor chain.
238 instance_->StopDataProvider();
239 delete instance_;
240 instance_ = NULL;
241 }
242 return true;
243 }
244
245 // Provides whatever data the provider has, which may be nothing. Return
246 // value indicates whether this is all the data the provider could ever
247 // obtain.
248 bool GetData(DataType* data) {
249 DCHECK(this->CalledOnValidThread());
250 return impl_->GetData(data);
251 }
252
253 private:
254 // Private constructor and destructor, callers access singleton through
255 // Register and Unregister.
256 DeviceDataProvider() {
257 DCHECK(factory_function_);
258 impl_ = (*factory_function_)();
259 DCHECK(impl_);
260 impl_->SetContainer(this);
261 }
262 virtual ~DeviceDataProvider() {
263 DCHECK(impl_);
264 impl_->SetContainer(NULL);
265 }
266
267 void AddListener(ListenerInterface* listener) {
268 impl_->AddListener(listener);
269 }
270
271 bool RemoveListener(ListenerInterface* listener) {
272 return impl_->RemoveListener(listener);
273 }
274
275 bool has_listeners() const {
276 return impl_->has_listeners();
277 }
278
279 bool StartDataProvider() {
280 return impl_->StartDataProvider();
281 }
282
283 void StopDataProvider() {
284 impl_->StopDataProvider();
285 }
286
287 CONTENT_EXPORT static DeviceDataProviderImplBase<DataType>*
288 DefaultFactoryFunction();
289
290 // The singleton-like instance of this class. (Not 'true' singleton, as it
291 // may go through multiple create/destroy/create cycles per process instance,
292 // e.g. when under test).
293 CONTENT_EXPORT static DeviceDataProvider* instance_;
294
295 // The factory function used to create the singleton instance.
296 CONTENT_EXPORT static ImplFactoryFunction factory_function_;
297
298 // The internal implementation.
299 scoped_refptr<DeviceDataProviderImplBase<DataType> > impl_;
300
301 DISALLOW_COPY_AND_ASSIGN(DeviceDataProvider);
302 };
303
304 typedef DeviceDataProvider<WifiData> WifiDataProvider;
305
306 #endif // CONTENT_BROWSER_GEOLOCATION_DEVICE_DATA_PROVIDER_H_ 230 #endif // CONTENT_BROWSER_GEOLOCATION_DEVICE_DATA_PROVIDER_H_
OLDNEW
« no previous file with comments | « content/browser/geolocation/network_location_request.h ('k') | content/browser/geolocation/wifi_data_provider.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698