| OLD | NEW |
| 1 // Copyright 2008, Google Inc. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| 2 // | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // Redistribution and use in source and binary forms, with or without | 3 // found in the LICENSE file. |
| 4 // modification, are permitted provided that the following conditions are met: | 4 |
| 5 // | |
| 6 // 1. Redistributions of source code must retain the above copyright notice, | |
| 7 // this list of conditions and the following disclaimer. | |
| 8 // 2. Redistributions in binary form must reproduce the above copyright notice, | |
| 9 // this list of conditions and the following disclaimer in the documentation | |
| 10 // and/or other materials provided with the distribution. | |
| 11 // 3. Neither the name of Google Inc. nor the names of its contributors may be | |
| 12 // used to endorse or promote products derived from this software without | |
| 13 // specific prior written permission. | |
| 14 // | |
| 15 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED | |
| 16 // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |
| 17 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO | |
| 18 // EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
| 19 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
| 20 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; | |
| 21 // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | |
| 22 // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | |
| 23 // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | |
| 24 // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 25 // | |
| 26 // 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 |
| 27 // NetworkLocationProvider to obtain a position fix. This data may be either | 6 // NetworkLocationProvider to obtain a position fix. This data may be either |
| 28 // 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 |
| 29 // instance of the device data provider, which is used by multiple | 8 // instance of the device data provider, which is used by multiple |
| 30 // NetworkLocationProvider objects. | 9 // NetworkLocationProvider objects. |
| 31 // | 10 // |
| 32 // This file providers DeviceDataProvider, which provides static methods to | 11 // This file providers DeviceDataProvider, which provides static methods to |
| 33 // access the singleton instance. The singleton instance uses a private | 12 // access the singleton instance. The singleton instance uses a private |
| 34 // implementation to abstract across platforms and also to allow mock providers | 13 // implementation to abstract across platforms and also to allow mock providers |
| 35 // to be used for testing. | 14 // to be used for testing. |
| 36 // | 15 // |
| 37 // This file also provides DeviceDataProviderImplBase, a base class which | 16 // This file also provides DeviceDataProviderImplBase, a base class which |
| 38 // provides commom functionality for the private implementations. | 17 // provides commom functionality for the private implementations. |
| 39 // | 18 // |
| 40 // 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 |
| 41 // and wifi data. | 20 // and wifi data. |
| 42 | 21 |
| 43 #ifndef GEARS_GEOLOCATION_DEVICE_DATA_PROVIDER_H__ | 22 #ifndef CHROME_BROWSER_GEOLOCATION_DEVICE_DATA_PROVIDER_H_ |
| 44 #define GEARS_GEOLOCATION_DEVICE_DATA_PROVIDER_H__ | 23 #define CHROME_BROWSER_GEOLOCATION_DEVICE_DATA_PROVIDER_H_ |
| 45 | 24 |
| 46 #include <algorithm> | 25 #include <algorithm> |
| 26 #include <functional> |
| 47 #include <set> | 27 #include <set> |
| 28 #include <string> |
| 48 #include <vector> | 29 #include <vector> |
| 49 #include "gears/base/common/basictypes.h" // For int64 | 30 |
| 50 #include "gears/base/common/common.h" | 31 #include "base/basictypes.h" |
| 51 #include "gears/base/common/mutex.h" | 32 #include "base/lock.h" |
| 52 #include "gears/base/common/scoped_refptr.h" // For RefCount | 33 #include "base/string16.h" |
| 53 #include "gears/base/common/string16.h" | 34 #include "base/string_util.h" |
| 54 #include "third_party/scoped_ptr/scoped_ptr.h" | 35 #include "base/scoped_ptr.h" |
| 55 | 36 |
| 56 // The following data structures are used to store cell radio data and wifi | 37 // The following data structures are used to store cell radio data and wifi |
| 57 // data. See the Geolocation API design document at | 38 // data. See the Geolocation API design document at |
| 58 // http://code.google.com/p/google-gears/wiki/LocationAPI for a more complete | 39 // http://code.google.com/p/google-gears/wiki/LocationAPI for a more complete |
| 59 // description. | 40 // description. |
| 60 // | 41 // |
| 61 // For all integer fields, we use kint32min to represent unknown values. | 42 // For all integer fields, we use kint32min to represent unknown values. |
| 62 | 43 |
| 63 // Cell radio data relating to a single cell tower. | 44 // Cell radio data relating to a single cell tower. |
| 64 struct CellData { | 45 struct CellData { |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 121 radio_type == other.radio_type && | 102 radio_type == other.radio_type && |
| 122 carrier == other.carrier; | 103 carrier == other.carrier; |
| 123 } | 104 } |
| 124 // Determines whether a new set of radio data differs significantly from this. | 105 // Determines whether a new set of radio data differs significantly from this. |
| 125 bool DiffersSignificantly(const RadioData &other) const { | 106 bool DiffersSignificantly(const RadioData &other) const { |
| 126 // This is required by MockDeviceDataProviderImpl. | 107 // This is required by MockDeviceDataProviderImpl. |
| 127 // TODO(steveblock): Implement properly. | 108 // TODO(steveblock): Implement properly. |
| 128 return !Matches(other); | 109 return !Matches(other); |
| 129 } | 110 } |
| 130 | 111 |
| 131 std::string16 device_id; | 112 string16 device_id; |
| 132 std::vector<CellData> cell_data; | 113 std::vector<CellData> cell_data; |
| 133 int home_mobile_network_code; // For the device's home network. | 114 int home_mobile_network_code; // For the device's home network. |
| 134 int home_mobile_country_code; // For the device's home network. | 115 int home_mobile_country_code; // For the device's home network. |
| 135 RadioType radio_type; // Mobile radio type. | 116 RadioType radio_type; // Mobile radio type. |
| 136 std::string16 carrier; // Carrier name. | 117 string16 carrier; // Carrier name. |
| 137 }; | 118 }; |
| 138 | 119 |
| 139 // Wifi data relating to a single access point. | 120 // Wifi data relating to a single access point. |
| 140 struct AccessPointData { | 121 struct AccessPointData { |
| 141 AccessPointData() | 122 AccessPointData() |
| 142 : radio_signal_strength(kint32min), | 123 : radio_signal_strength(kint32min), |
| 143 age(kint32min), | 124 age(kint32min), |
| 144 channel(kint32min), | 125 channel(kint32min), |
| 145 signal_to_noise(kint32min) {} | 126 signal_to_noise(kint32min) {} |
| 146 | 127 |
| 147 std::string16 mac_address; | 128 string16 mac_address; |
| 148 int radio_signal_strength; // Measured in dBm | 129 int radio_signal_strength; // Measured in dBm |
| 149 int age; // Milliseconds since this access point was detected | 130 int age; // Milliseconds since this access point was detected |
| 150 int channel; | 131 int channel; |
| 151 int signal_to_noise; // Ratio in dB | 132 int signal_to_noise; // Ratio in dB |
| 152 std::string16 ssid; // Network identifier | 133 string16 ssid; // Network identifier |
| 153 }; | 134 }; |
| 154 | 135 |
| 155 // This is to allow AccessPointData to be used in std::set. We order | 136 // This is to allow AccessPointData to be used in std::set. We order |
| 156 // lexicographically by MAC address. | 137 // lexicographically by MAC address. |
| 157 struct AccessPointDataLess : public std::less<AccessPointData> { | 138 struct AccessPointDataLess : public std::less<AccessPointData> { |
| 158 bool operator()(const AccessPointData &data1, | 139 bool operator()(const AccessPointData& data1, |
| 159 const AccessPointData &data2) const { | 140 const AccessPointData& data2) const { |
| 160 return data1.mac_address < data2.mac_address; | 141 return data1.mac_address < data2.mac_address; |
| 161 } | 142 } |
| 162 }; | 143 }; |
| 163 | 144 |
| 164 // All data for wifi. | 145 // All data for wifi. |
| 165 struct WifiData { | 146 struct WifiData { |
| 166 // Determines whether a new set of WiFi data differs significantly from this. | 147 // Determines whether a new set of WiFi data differs significantly from this. |
| 167 bool DiffersSignificantly(const WifiData &other) const { | 148 bool DiffersSignificantly(const WifiData &other) const { |
| 168 // At least 5 or 50% of access points added or removed is significant. | 149 // At least 5 or 50% of access points added or removed is significant. |
| 169 static const size_t kMinChangedAccessPoints = 5; | 150 static const size_t kMinChangedAccessPoints = 5; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 200 | 181 |
| 201 // DeviceDataProvider uses containment to hide platform-specific implementation | 182 // DeviceDataProvider uses containment to hide platform-specific implementation |
| 202 // details from common code. This class provides common functionality for these | 183 // details from common code. This class provides common functionality for these |
| 203 // contained implementation classes. | 184 // contained implementation classes. |
| 204 template<typename DataType> | 185 template<typename DataType> |
| 205 class DeviceDataProviderImplBase { | 186 class DeviceDataProviderImplBase { |
| 206 public: | 187 public: |
| 207 DeviceDataProviderImplBase() : container_(NULL) {} | 188 DeviceDataProviderImplBase() : container_(NULL) {} |
| 208 virtual ~DeviceDataProviderImplBase() {} | 189 virtual ~DeviceDataProviderImplBase() {} |
| 209 | 190 |
| 210 virtual bool GetData(DataType *data) = 0; | 191 virtual bool StartDataProvider() = 0; |
| 192 |
| 193 virtual bool GetData(DataType* data) = 0; |
| 211 | 194 |
| 212 // Sets the container of this class, which is of type DeviceDataProvider. | 195 // Sets the container of this class, which is of type DeviceDataProvider. |
| 213 // This is required to pass as a parameter when making the callback to | 196 // This is required to pass as a parameter when making the callback to |
| 214 // listeners. | 197 // listeners. |
| 215 void SetContainer(DeviceDataProvider<DataType> *container) { | 198 void SetContainer(DeviceDataProvider<DataType>* container) { |
| 216 container_ = container; | 199 container_ = container; |
| 217 } | 200 } |
| 218 | 201 |
| 219 typedef typename DeviceDataProvider<DataType>::ListenerInterface | 202 typedef typename DeviceDataProvider<DataType>::ListenerInterface |
| 220 ListenerInterface; | 203 ListenerInterface; |
| 221 void AddListener(ListenerInterface *listener) { | 204 void AddListener(ListenerInterface* listener) { |
| 222 MutexLock mutex(&listeners_mutex_); | 205 AutoLock mutex(listeners_mutex_); |
| 223 listeners_.insert(listener); | 206 listeners_.insert(listener); |
| 224 } | 207 } |
| 225 bool RemoveListener(ListenerInterface *listener) { | 208 bool RemoveListener(ListenerInterface* listener) { |
| 226 MutexLock mutex(&listeners_mutex_); | 209 AutoLock mutex(listeners_mutex_); |
| 227 typename ListenersSet::iterator iter = find(listeners_.begin(), | 210 typename ListenersSet::iterator iter = find(listeners_.begin(), |
| 228 listeners_.end(), | 211 listeners_.end(), |
| 229 listener); | 212 listener); |
| 230 if (iter == listeners_.end()) { | 213 if (iter == listeners_.end()) { |
| 231 return false; | 214 return false; |
| 232 } | 215 } |
| 233 listeners_.erase(iter); | 216 listeners_.erase(iter); |
| 234 return true; | 217 return true; |
| 235 } | 218 } |
| 236 | 219 |
| 237 protected: | 220 protected: |
| 238 // Calls DeviceDataUpdateAvailable() on all registered listeners. | 221 // Calls DeviceDataUpdateAvailable() on all registered listeners. |
| 239 typedef std::set<ListenerInterface*> ListenersSet; | 222 typedef std::set<ListenerInterface*> ListenersSet; |
| 240 void NotifyListeners() { | 223 void NotifyListeners() { |
| 241 MutexLock lock(&listeners_mutex_); | 224 AutoLock lock(listeners_mutex_); |
| 242 for (typename ListenersSet::const_iterator iter = listeners_.begin(); | 225 for (typename ListenersSet::const_iterator iter = listeners_.begin(); |
| 243 iter != listeners_.end(); | 226 iter != listeners_.end(); |
| 244 ++iter) { | 227 ++iter) { |
| 245 (*iter)->DeviceDataUpdateAvailable(container_); | 228 (*iter)->DeviceDataUpdateAvailable(container_); |
| 246 } | 229 } |
| 247 } | 230 } |
| 248 | 231 |
| 249 private: | 232 private: |
| 250 DeviceDataProvider<DataType> *container_; | 233 DeviceDataProvider<DataType>* container_; |
| 251 | 234 |
| 252 // The listeners to this class and their mutex. | 235 // The listeners to this class and their mutex. |
| 236 // TODO(joth): Once we've established the client is always single threaded, |
| 237 // remove mutex and instead capture client's MessageLoop to stage the |
| 238 // NotifyListeners callback via. |
| 253 ListenersSet listeners_; | 239 ListenersSet listeners_; |
| 254 Mutex listeners_mutex_; | 240 Lock listeners_mutex_; |
| 255 | 241 |
| 256 DISALLOW_EVIL_CONSTRUCTORS(DeviceDataProviderImplBase); | 242 DISALLOW_COPY_AND_ASSIGN(DeviceDataProviderImplBase); |
| 257 }; | 243 }; |
| 258 | 244 |
| 259 typedef DeviceDataProviderImplBase<RadioData> RadioDataProviderImplBase; | 245 typedef DeviceDataProviderImplBase<RadioData> RadioDataProviderImplBase; |
| 260 typedef DeviceDataProviderImplBase<WifiData> WifiDataProviderImplBase; | 246 typedef DeviceDataProviderImplBase<WifiData> WifiDataProviderImplBase; |
| 261 | 247 |
| 262 // A device data provider | 248 // A device data provider |
| 263 // | 249 // |
| 264 // We use a singleton instance of this class which is shared by multiple network | 250 // We use a singleton instance of this class which is shared by multiple network |
| 265 // location providers. These location providers access the instance through the | 251 // location providers. These location providers access the instance through the |
| 266 // Register and Unregister methods. | 252 // Register and Unregister methods. |
| 267 template<typename DataType> | 253 template<typename DataType> |
| 268 class DeviceDataProvider { | 254 class DeviceDataProvider { |
| 269 public: | 255 public: |
| 270 // Interface to be implemented by listeners to a device data provider. | 256 // Interface to be implemented by listeners to a device data provider. |
| 271 class ListenerInterface { | 257 class ListenerInterface { |
| 272 public: | 258 public: |
| 259 // NOTE this may be called back in the context of the implementation private |
| 260 // worker thread. (TODO Is there a naming convention to use for this?) |
| 273 virtual void DeviceDataUpdateAvailable( | 261 virtual void DeviceDataUpdateAvailable( |
| 274 DeviceDataProvider<DataType> *provider) = 0; | 262 DeviceDataProvider<DataType>* provider) = 0; |
| 275 virtual ~ListenerInterface() {} | 263 virtual ~ListenerInterface() {} |
| 276 }; | 264 }; |
| 277 | 265 |
| 278 // Sets the factory function which will be used by Register to create the | 266 // Sets the factory function which will be used by Register to create the |
| 279 // implementation used by the singleton instance. This factory approach is | 267 // implementation used by the singleton instance. This factory approach is |
| 280 // used to abastract accross both platform-specific implementation and to | 268 // used to abastract accross both platform-specific implementation and to |
| 281 // inject mock implementations for testing. | 269 // inject mock implementations for testing. |
| 282 typedef DeviceDataProviderImplBase<DataType> *(*ImplFactoryFunction)(void); | 270 typedef DeviceDataProviderImplBase<DataType>* (*ImplFactoryFunction)(void); |
| 283 static void SetFactory(ImplFactoryFunction factory_function_in) { | 271 static void SetFactory(ImplFactoryFunction factory_function_in) { |
| 284 factory_function_ = factory_function_in; | 272 factory_function_ = factory_function_in; |
| 285 } | 273 } |
| 286 | 274 |
| 287 static void ResetFactory() { | 275 static void ResetFactory() { |
| 288 factory_function_ = DefaultFactoryFunction; | 276 factory_function_ = DefaultFactoryFunction; |
| 289 } | 277 } |
| 290 | 278 |
| 291 // Adds a listener, which will be called back with DeviceDataUpdateAvailable | 279 // Adds a listener, which will be called back with DeviceDataUpdateAvailable |
| 292 // whenever new data is available. Returns the singleton instance. | 280 // whenever new data is available. Returns the singleton instance. |
| 293 static DeviceDataProvider *Register(ListenerInterface *listener) { | 281 static DeviceDataProvider* Register(ListenerInterface* listener) { |
| 282 // TODO(joth): The following comment applied when this was used in Gears; |
| 283 // revisit if this is still needed once usage is established in Chromium. |
| 294 // We protect against Register and Unregister being called asynchronously | 284 // We protect against Register and Unregister being called asynchronously |
| 295 // from different threads. This is the case when a device data provider is | 285 // from different threads. This is the case when a device data provider is |
| 296 // used by a NetworkLocationProvider object. Register is always called from | 286 // used by a NetworkLocationProvider object. Register is always called from |
| 297 // the JavaScript thread. Unregister is called when NetworkLocationProvider | 287 // the JavaScript thread. Unregister is called when NetworkLocationProvider |
| 298 // objects are destructed, which happens asynchronously once the | 288 // objects are destructed, which happens asynchronously once the |
| 299 // NetworkLocationProvider HTTP request has completed. | 289 // NetworkLocationProvider HTTP request has completed. |
| 300 MutexLock mutex(&instance_mutex_); | 290 AutoLock mutex(instance_mutex_); |
| 301 if (!instance_) { | 291 if (!instance_) { |
| 302 instance_ = new DeviceDataProvider(); | 292 instance_ = new DeviceDataProvider(); |
| 303 } | 293 } |
| 304 assert(instance_); | 294 assert(instance_); |
| 305 instance_->Ref(); | 295 instance_->Ref(); |
| 306 instance_->AddListener(listener); | 296 instance_->AddListener(listener); |
| 307 return instance_; | 297 return instance_; |
| 308 } | 298 } |
| 309 | 299 |
| 310 // Removes a listener. If this is the last listener, deletes the singleton | 300 // Removes a listener. If this is the last listener, deletes the singleton |
| 311 // instance. Return value indicates success. | 301 // instance. Return value indicates success. |
| 312 static bool Unregister(ListenerInterface *listener) { | 302 static bool Unregister(ListenerInterface* listener) { |
| 313 MutexLock mutex(&instance_mutex_); | 303 AutoLock mutex(instance_mutex_); |
| 314 if (!instance_->RemoveListener(listener)) { | 304 if (!instance_->RemoveListener(listener)) { |
| 315 return false; | 305 return false; |
| 316 } | 306 } |
| 317 if (instance_->Unref()) { | 307 if (instance_->Unref()) { |
| 318 delete instance_; | 308 delete instance_; |
| 319 instance_ = NULL; | 309 instance_ = NULL; |
| 320 } | 310 } |
| 321 return true; | 311 return true; |
| 322 } | 312 } |
| 323 | 313 |
| 324 // Provides whatever data the provider has, which may be nothing. Return | 314 // Provides whatever data the provider has, which may be nothing. Return |
| 325 // value indicates whether this is all the data the provider could ever | 315 // value indicates whether this is all the data the provider could ever |
| 326 // obtain. | 316 // obtain. |
| 327 bool GetData(DataType *data) { | 317 bool GetData(DataType* data) { |
| 328 return impl_->GetData(data); | 318 return impl_->GetData(data); |
| 329 } | 319 } |
| 330 | 320 |
| 331 private: | 321 private: |
| 332 // Private constructor and destructor, callers access singleton through | 322 // Private constructor and destructor, callers access singleton through |
| 333 // Register and Unregister. | 323 // Register and Unregister. |
| 334 DeviceDataProvider() { | 324 DeviceDataProvider() : count_(0) { |
| 335 assert(factory_function_); | 325 assert(factory_function_); |
| 336 impl_.reset((*factory_function_)()); | 326 impl_.reset((*factory_function_)()); |
| 337 impl_->SetContainer(this); | 327 impl_->SetContainer(this); |
| 328 bool started = impl_->StartDataProvider(); |
| 329 assert(started); |
| 338 } | 330 } |
| 339 virtual ~DeviceDataProvider() {} | 331 virtual ~DeviceDataProvider() {} |
| 340 | 332 |
| 341 void Ref() { | 333 void Ref() { |
| 342 count_.Ref(); | 334 ++count_; |
| 343 } | 335 } |
| 344 // Returns true when the ref count transitions from 1 to 0. | 336 // Returns true when the ref count transitions from 1 to 0. |
| 345 bool Unref() { | 337 bool Unref() { |
| 346 return count_.Unref(); | 338 --count_; |
| 339 return count_ == 0; |
| 347 } | 340 } |
| 348 | 341 |
| 349 void AddListener(ListenerInterface *listener) { | 342 void AddListener(ListenerInterface* listener) { |
| 350 impl_->AddListener(listener); | 343 impl_->AddListener(listener); |
| 351 } | 344 } |
| 352 | 345 |
| 353 bool RemoveListener(ListenerInterface *listener) { | 346 bool RemoveListener(ListenerInterface* listener) { |
| 354 return impl_->RemoveListener(listener); | 347 return impl_->RemoveListener(listener); |
| 355 } | 348 } |
| 356 | 349 |
| 357 static DeviceDataProviderImplBase<DataType> *DefaultFactoryFunction(); | 350 static DeviceDataProviderImplBase<DataType>* DefaultFactoryFunction(); |
| 358 | 351 |
| 359 // The singleton instance of this class and its mutex. | 352 // The singleton instance of this class and its mutex. |
| 360 static DeviceDataProvider *instance_; | 353 static DeviceDataProvider* instance_; |
| 361 static Mutex instance_mutex_; | 354 static Lock instance_mutex_; |
| 362 | 355 |
| 363 // The factory function used to create the singleton instance. | 356 // The factory function used to create the singleton instance. |
| 364 static ImplFactoryFunction factory_function_; | 357 static ImplFactoryFunction factory_function_; |
| 365 | 358 |
| 366 // The internal implementation. | 359 // The internal implementation. |
| 367 scoped_ptr<DeviceDataProviderImplBase<DataType> > impl_; | 360 scoped_ptr<DeviceDataProviderImplBase<DataType> > impl_; |
| 368 | 361 |
| 369 RefCount count_; | 362 int count_; |
| 370 | 363 |
| 371 DISALLOW_EVIL_CONSTRUCTORS(DeviceDataProvider); | 364 DISALLOW_EVIL_CONSTRUCTORS(DeviceDataProvider); |
| 372 }; | 365 }; |
| 373 | 366 |
| 374 // static | 367 // static |
| 375 template<typename DataType> | 368 template<typename DataType> |
| 376 Mutex DeviceDataProvider<DataType>::instance_mutex_; | 369 Lock DeviceDataProvider<DataType>::instance_mutex_; |
| 377 | 370 |
| 378 // static | 371 // static |
| 379 template<typename DataType> | 372 template<typename DataType> |
| 380 DeviceDataProvider<DataType> *DeviceDataProvider<DataType>::instance_ = | 373 DeviceDataProvider<DataType>* DeviceDataProvider<DataType>::instance_ = NULL; |
| 381 NULL; | |
| 382 | 374 |
| 383 // static | 375 // static |
| 384 template<typename DataType> | 376 template<typename DataType> |
| 385 typename DeviceDataProvider<DataType>::ImplFactoryFunction | 377 typename DeviceDataProvider<DataType>::ImplFactoryFunction |
| 386 DeviceDataProvider<DataType>::factory_function_ = DefaultFactoryFunction; | 378 DeviceDataProvider<DataType>::factory_function_ = DefaultFactoryFunction; |
| 387 | 379 |
| 388 typedef DeviceDataProvider<RadioData> RadioDataProvider; | 380 typedef DeviceDataProvider<RadioData> RadioDataProvider; |
| 389 typedef DeviceDataProvider<WifiData> WifiDataProvider; | 381 typedef DeviceDataProvider<WifiData> WifiDataProvider; |
| 390 | 382 |
| 391 #endif // GEARS_GEOLOCATION_DEVICE_DATA_PROVIDER_H__ | 383 #endif // CHROME_BROWSER_GEOLOCATION_DEVICE_DATA_PROVIDER_H_ |
| OLD | NEW |