| Index: content/browser/geolocation/device_data_provider.h | 
| =================================================================== | 
| --- content/browser/geolocation/device_data_provider.h	(revision 76230) | 
| +++ content/browser/geolocation/device_data_provider.h	(working copy) | 
| @@ -1,402 +0,0 @@ | 
| -// Copyright (c) 2010 The Chromium Authors. All rights reserved. | 
| -// Use of this source code is governed by a BSD-style license that can be | 
| -// found in the LICENSE file. | 
| - | 
| -// A device data provider provides data from the device that is used by a | 
| -// NetworkLocationProvider to obtain a position fix. This data may be either | 
| -// cell radio data or wifi data. For a given type of data, we use a singleton | 
| -// instance of the device data provider, which is used by multiple | 
| -// NetworkLocationProvider objects. | 
| -// | 
| -// This file providers DeviceDataProvider, which provides static methods to | 
| -// access the singleton instance. The singleton instance uses a private | 
| -// implementation to abstract across platforms and also to allow mock providers | 
| -// to be used for testing. | 
| -// | 
| -// This file also provides DeviceDataProviderImplBase, a base class which | 
| -// provides commom functionality for the private implementations. | 
| -// | 
| -// This file also declares the data structures used to represent cell radio data | 
| -// and wifi data. | 
| - | 
| -#ifndef CONTENT_BROWSER_GEOLOCATION_DEVICE_DATA_PROVIDER_H_ | 
| -#define CONTENT_BROWSER_GEOLOCATION_DEVICE_DATA_PROVIDER_H_ | 
| -#pragma once | 
| - | 
| -#include <algorithm> | 
| -#include <set> | 
| -#include <vector> | 
| - | 
| -#include "base/basictypes.h" | 
| -#include "base/message_loop.h" | 
| -#include "base/ref_counted.h" | 
| -#include "base/string16.h" | 
| -#include "base/string_util.h" | 
| -#include "base/task.h" | 
| -#include "base/threading/non_thread_safe.h" | 
| - | 
| -// The following data structures are used to store cell radio data and wifi | 
| -// data. See the Geolocation API design document at | 
| -// http://code.google.com/p/google-gears/wiki/LocationAPI for a more complete | 
| -// description. | 
| -// | 
| -// For all integer fields, we use kint32min to represent unknown values. | 
| - | 
| -// Cell radio data relating to a single cell tower. | 
| -struct CellData { | 
| -  CellData(); | 
| -  bool Matches(const CellData &other) const { | 
| -    // Ignore radio_signal_strength when matching. | 
| -    return cell_id == other.cell_id && | 
| -           location_area_code == other.location_area_code && | 
| -           mobile_network_code == other.mobile_network_code && | 
| -           mobile_country_code == other.mobile_country_code && | 
| -           timing_advance == other.timing_advance; | 
| -  } | 
| - | 
| -  int cell_id;                // Unique identifier of the cell | 
| -  int location_area_code;     // For current location area | 
| -  int mobile_network_code;    // For current cell | 
| -  int mobile_country_code;    // For current cell | 
| -  int radio_signal_strength;  // Measured in dBm. | 
| -  int timing_advance;         // Timing advance representing the distance from | 
| -                              // the cell tower. Each unit is roughly 550 | 
| -                              // meters. | 
| -}; | 
| - | 
| -enum RadioType { | 
| -  RADIO_TYPE_UNKNOWN, | 
| -  RADIO_TYPE_GSM, | 
| -  RADIO_TYPE_CDMA, | 
| -  RADIO_TYPE_WCDMA, | 
| -}; | 
| - | 
| -// All data for the cell radio. | 
| -struct RadioData { | 
| -  RadioData(); | 
| -  ~RadioData(); | 
| - | 
| -  bool Matches(const RadioData &other) const; | 
| - | 
| -  // Determines whether a new set of radio data differs significantly from this. | 
| -  bool DiffersSignificantly(const RadioData &other) const { | 
| -    // This is required by MockDeviceDataProviderImpl. | 
| -    // TODO(steveblock): Implement properly. | 
| -    return !Matches(other); | 
| -  } | 
| - | 
| -  string16 device_id; | 
| -  std::vector<CellData> cell_data; | 
| -  int home_mobile_network_code;  // For the device's home network. | 
| -  int home_mobile_country_code;  // For the device's home network. | 
| -  RadioType radio_type;          // Mobile radio type. | 
| -  string16 carrier;              // Carrier name. | 
| -}; | 
| - | 
| -// Wifi data relating to a single access point. | 
| -struct AccessPointData { | 
| -  AccessPointData(); | 
| -  ~AccessPointData(); | 
| - | 
| -  // MAC address, formatted as per MacAddressAsString16. | 
| -  string16 mac_address; | 
| -  int radio_signal_strength;  // Measured in dBm | 
| -  int channel; | 
| -  int signal_to_noise;  // Ratio in dB | 
| -  string16 ssid;   // Network identifier | 
| -}; | 
| - | 
| -// This is to allow AccessPointData to be used in std::set. We order | 
| -// lexicographically by MAC address. | 
| -struct AccessPointDataLess { | 
| -  bool operator()(const AccessPointData& data1, | 
| -                  const AccessPointData& data2) const { | 
| -    return data1.mac_address < data2.mac_address; | 
| -  } | 
| -}; | 
| - | 
| -// All data for wifi. | 
| -struct WifiData { | 
| -  WifiData(); | 
| -  ~WifiData(); | 
| - | 
| -  // Determines whether a new set of WiFi data differs significantly from this. | 
| -  bool DiffersSignificantly(const WifiData& other) const; | 
| - | 
| -  // Store access points as a set, sorted by MAC address. This allows quick | 
| -  // comparison of sets for detecting changes and for caching. | 
| -  typedef std::set<AccessPointData, AccessPointDataLess> AccessPointDataSet; | 
| -  AccessPointDataSet access_point_data; | 
| -}; | 
| - | 
| -// Gateway data relating to a single router. | 
| -struct RouterData { | 
| -  // MAC address, formatted as per MacAddressAsString16. | 
| -  string16 mac_address; | 
| -}; | 
| - | 
| -// This is to allow RouterData to be used in std::set. We order | 
| -// lexicographically by MAC address. | 
| -struct RouterDataLess { | 
| -  bool operator()(const RouterData& data1, | 
| -                  const RouterData& data2) const { | 
| -    return data1.mac_address < data2.mac_address; | 
| -  } | 
| -}; | 
| - | 
| -// All gateway data for routers. | 
| -struct GatewayData { | 
| -  GatewayData(); | 
| -  ~GatewayData(); | 
| - | 
| -  // Determines whether a new set of gateway data differs significantly | 
| -  // from this. | 
| -  bool DiffersSignificantly(const GatewayData& other) const; | 
| - | 
| -  // Store routers as a set, sorted by MAC address. This allows quick | 
| -  // comparison of sets for detecting changes and for caching. | 
| -  typedef std::set<RouterData, RouterDataLess> RouterDataSet; | 
| -  RouterDataSet router_data; | 
| -}; | 
| - | 
| -template<typename DataType> | 
| -class DeviceDataProvider; | 
| - | 
| -// This class just exists to work-around MSVC2005 not being able to have a | 
| -// template class implement RefCountedThreadSafe | 
| -class DeviceDataProviderImplBaseHack | 
| -    : public base::RefCountedThreadSafe<DeviceDataProviderImplBaseHack> { | 
| - protected: | 
| -  friend class base::RefCountedThreadSafe<DeviceDataProviderImplBaseHack>; | 
| -  virtual ~DeviceDataProviderImplBaseHack() {} | 
| -}; | 
| - | 
| -// See class DeviceDataProvider for the public client API. | 
| -// DeviceDataProvider uses containment to hide platform-specific implementation | 
| -// details from common code. This class provides common functionality for these | 
| -// contained implementation classes. This is a modified pimpl pattern: this | 
| -// class needs to be in the public header due to use of templating. | 
| -template<typename DataType> | 
| -class DeviceDataProviderImplBase : public DeviceDataProviderImplBaseHack { | 
| - public: | 
| -  DeviceDataProviderImplBase() | 
| -      : container_(NULL), client_loop_(MessageLoop::current()) { | 
| -    DCHECK(client_loop_); | 
| -  } | 
| - | 
| -  virtual bool StartDataProvider() = 0; | 
| -  virtual void StopDataProvider() = 0; | 
| -  virtual bool GetData(DataType* data) = 0; | 
| - | 
| -  // Sets the container of this class, which is of type DeviceDataProvider. | 
| -  // This is required to pass as a parameter when making the callback to | 
| -  // listeners. | 
| -  void SetContainer(DeviceDataProvider<DataType>* container) { | 
| -    DCHECK(CalledOnClientThread()); | 
| -    container_ = container; | 
| -  } | 
| - | 
| -  typedef typename DeviceDataProvider<DataType>::ListenerInterface | 
| -          ListenerInterface; | 
| -  void AddListener(ListenerInterface* listener) { | 
| -    DCHECK(CalledOnClientThread()); | 
| -    listeners_.insert(listener); | 
| -  } | 
| -  bool RemoveListener(ListenerInterface* listener) { | 
| -    DCHECK(CalledOnClientThread()); | 
| -    return listeners_.erase(listener) == 1; | 
| -  } | 
| - | 
| -  bool has_listeners() const { | 
| -    DCHECK(CalledOnClientThread()); | 
| -    return !listeners_.empty(); | 
| -  } | 
| - | 
| - protected: | 
| -  virtual ~DeviceDataProviderImplBase() { | 
| -    DCHECK(CalledOnClientThread()); | 
| -  } | 
| - | 
| -  // Calls DeviceDataUpdateAvailable() on all registered listeners. | 
| -  typedef std::set<ListenerInterface*> ListenersSet; | 
| -  void NotifyListeners() { | 
| -    // Always make the nitofy callback via a posted task, se we can unwind | 
| -    // callstack here and make callback without causing client re-entrancy. | 
| -    client_loop_->PostTask(FROM_HERE, NewRunnableMethod(this, | 
| -        &DeviceDataProviderImplBase<DataType>::NotifyListenersInClientLoop)); | 
| -  } | 
| - | 
| -  bool CalledOnClientThread() const { | 
| -    return MessageLoop::current() == this->client_loop_; | 
| -  } | 
| - | 
| - private: | 
| -  void NotifyListenersInClientLoop() { | 
| -    DCHECK(CalledOnClientThread()); | 
| -    // It's possible that all the listeners (and the container) went away | 
| -    // whilst this task was pending. This is fine; the loop will be a no-op. | 
| -    typename ListenersSet::const_iterator iter = listeners_.begin(); | 
| -    while (iter != listeners_.end()) { | 
| -      ListenerInterface* listener = *iter; | 
| -      ++iter;  // Advance iter before callback, in case listener unregisters. | 
| -      listener->DeviceDataUpdateAvailable(container_); | 
| -    } | 
| -  } | 
| - | 
| -  DeviceDataProvider<DataType>* container_; | 
| - | 
| -  // Reference to the client's message loop, all callbacks and access to | 
| -  // the listeners_ member should happen in this context. | 
| -  MessageLoop* client_loop_; | 
| - | 
| -  ListenersSet listeners_; | 
| - | 
| -  DISALLOW_COPY_AND_ASSIGN(DeviceDataProviderImplBase); | 
| -}; | 
| - | 
| -typedef DeviceDataProviderImplBase<GatewayData> GatewayDataProviderImplBase; | 
| -typedef DeviceDataProviderImplBase<RadioData> RadioDataProviderImplBase; | 
| -typedef DeviceDataProviderImplBase<WifiData> WifiDataProviderImplBase; | 
| - | 
| -// A device data provider | 
| -// | 
| -// We use a singleton instance of this class which is shared by multiple network | 
| -// location providers. These location providers access the instance through the | 
| -// Register and Unregister methods. | 
| -template<typename DataType> | 
| -class DeviceDataProvider : public base::NonThreadSafe { | 
| - public: | 
| -  // Interface to be implemented by listeners to a device data provider. | 
| -  class ListenerInterface { | 
| -   public: | 
| -    // Will be called in the context of the thread that called Register(). | 
| -    virtual void DeviceDataUpdateAvailable( | 
| -        DeviceDataProvider<DataType>* provider) = 0; | 
| -    virtual ~ListenerInterface() {} | 
| -  }; | 
| - | 
| -  // Sets the factory function which will be used by Register to create the | 
| -  // implementation used by the singleton instance. This factory approach is | 
| -  // used to abastract accross both platform-specific implementation and to | 
| -  // inject mock implementations for testing. | 
| -  typedef DeviceDataProviderImplBase<DataType>* (*ImplFactoryFunction)(void); | 
| -  static void SetFactory(ImplFactoryFunction factory_function_in) { | 
| -    factory_function_ = factory_function_in; | 
| -  } | 
| - | 
| -  static void ResetFactory() { | 
| -    factory_function_ = DefaultFactoryFunction; | 
| -  } | 
| - | 
| -  // Adds a listener, which will be called back with DeviceDataUpdateAvailable | 
| -  // whenever new data is available. Returns the singleton instance. | 
| -  static DeviceDataProvider* Register(ListenerInterface* listener) { | 
| -    bool need_to_start_thread = false; | 
| -    if (!instance_) { | 
| -      instance_ = new DeviceDataProvider(); | 
| -      need_to_start_thread = true; | 
| -    } | 
| -    DCHECK(instance_); | 
| -    DCHECK(instance_->CalledOnValidThread()); | 
| -    instance_->AddListener(listener); | 
| -    // Start the provider after adding the listener, to avoid any race in | 
| -    // it receiving an early callback. | 
| -    if (need_to_start_thread) { | 
| -      bool started = instance_->StartDataProvider(); | 
| -      DCHECK(started); | 
| -    } | 
| -    return instance_; | 
| -  } | 
| - | 
| -  // Removes a listener. If this is the last listener, deletes the singleton | 
| -  // instance. Return value indicates success. | 
| -  static bool Unregister(ListenerInterface* listener) { | 
| -    DCHECK(instance_); | 
| -    DCHECK(instance_->CalledOnValidThread()); | 
| -    DCHECK(instance_->has_listeners()); | 
| -    if (!instance_->RemoveListener(listener)) { | 
| -      return false; | 
| -    } | 
| -    if (!instance_->has_listeners()) { | 
| -      // Must stop the provider (and any implementation threads) before | 
| -      // destroying to avoid any race conditions in access to the provider in | 
| -      // the destructor chain. | 
| -      instance_->StopDataProvider(); | 
| -      delete instance_; | 
| -      instance_ = NULL; | 
| -    } | 
| -    return true; | 
| -  } | 
| - | 
| -  // Provides whatever data the provider has, which may be nothing. Return | 
| -  // value indicates whether this is all the data the provider could ever | 
| -  // obtain. | 
| -  bool GetData(DataType* data) { | 
| -    DCHECK(this->CalledOnValidThread()); | 
| -    return impl_->GetData(data); | 
| -  } | 
| - | 
| - private: | 
| -  // Private constructor and destructor, callers access singleton through | 
| -  // Register and Unregister. | 
| -  DeviceDataProvider() { | 
| -    DCHECK(factory_function_); | 
| -    impl_ = (*factory_function_)(); | 
| -    DCHECK(impl_); | 
| -    impl_->SetContainer(this); | 
| -  } | 
| -  virtual ~DeviceDataProvider() { | 
| -    DCHECK(impl_); | 
| -    impl_->SetContainer(NULL); | 
| -  } | 
| - | 
| -  void AddListener(ListenerInterface* listener) { | 
| -    impl_->AddListener(listener); | 
| -  } | 
| - | 
| -  bool RemoveListener(ListenerInterface* listener) { | 
| -    return impl_->RemoveListener(listener); | 
| -  } | 
| - | 
| -  bool has_listeners() const { | 
| -    return impl_->has_listeners(); | 
| -  } | 
| - | 
| -  bool StartDataProvider() { | 
| -    return impl_->StartDataProvider(); | 
| -  } | 
| - | 
| -  void StopDataProvider() { | 
| -    impl_->StopDataProvider(); | 
| -  } | 
| - | 
| -  static DeviceDataProviderImplBase<DataType>* DefaultFactoryFunction(); | 
| - | 
| -  // The singleton-like instance of this class. (Not 'true' singleton, as it | 
| -  // may go through multiple create/destroy/create cycles per process instance, | 
| -  // e.g. when under test). | 
| -  static DeviceDataProvider* instance_; | 
| - | 
| -  // The factory function used to create the singleton instance. | 
| -  static ImplFactoryFunction factory_function_; | 
| - | 
| -  // The internal implementation. | 
| -  scoped_refptr<DeviceDataProviderImplBase<DataType> > impl_; | 
| - | 
| -  DISALLOW_COPY_AND_ASSIGN(DeviceDataProvider); | 
| -}; | 
| - | 
| -// static | 
| -template<typename DataType> | 
| -DeviceDataProvider<DataType>* DeviceDataProvider<DataType>::instance_ = NULL; | 
| - | 
| -// static | 
| -template<typename DataType> | 
| -typename DeviceDataProvider<DataType>::ImplFactoryFunction | 
| -    DeviceDataProvider<DataType>::factory_function_ = DefaultFactoryFunction; | 
| - | 
| -typedef DeviceDataProvider<GatewayData> GatewayDataProvider; | 
| -typedef DeviceDataProvider<RadioData> RadioDataProvider; | 
| -typedef DeviceDataProvider<WifiData> WifiDataProvider; | 
| - | 
| -#endif  // CONTENT_BROWSER_GEOLOCATION_DEVICE_DATA_PROVIDER_H_ | 
|  |