blob: 9521a413e368b302ab6fd0c50a8e6541cc18e872 [file] [log] [blame]
// 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.
#ifndef CHROME_BROWSER_CHROMEOS_CROS_NETWORK_LIBRARY_H_
#define CHROME_BROWSER_CHROMEOS_CROS_NETWORK_LIBRARY_H_
#include <string>
#include <vector>
#include "base/observer_list.h"
#include "base/platform_thread.h"
#include "base/singleton.h"
#include "base/string16.h"
#include "base/timer.h"
#include "net/url_request/url_request_job_tracker.h"
#include "cros/chromeos_network.h"
namespace chromeos {
class Network {
public:
const std::string& service_path() const { return service_path_; }
const std::string& device_path() const { return device_path_; }
const std::string& ip_address() const { return ip_address_; }
ConnectionType type() const { return type_; }
bool connecting() const { return state_ == STATE_ASSOCIATION ||
state_ == STATE_CONFIGURATION || state_ == STATE_CARRIER; }
bool connected() const { return state_ == STATE_READY; }
bool connecting_or_connected() const { return connecting() || connected(); }
bool failed() const { return state_ == STATE_FAILURE; }
ConnectionError error() const { return error_; }
void set_connecting(bool connecting) { state_ = (connecting ?
STATE_ASSOCIATION : STATE_IDLE); }
void set_connected(bool connected) { state_ = (connected ?
STATE_READY : STATE_IDLE); }
// Clear the fields.
virtual void Clear();
// Configure the Network from a ServiceInfo object.
virtual void ConfigureFromService(const ServiceInfo& service);
// Return a string representation of the state code.
// This not translated and should be only used for debugging purposes.
std::string GetStateString();
// Return a string representation of the error code.
// This not translated and should be only used for debugging purposes.
std::string GetErrorString();
protected:
Network()
: type_(TYPE_UNKNOWN),
state_(STATE_UNKNOWN),
error_(ERROR_UNKNOWN) {}
virtual ~Network() {}
std::string service_path_;
std::string device_path_;
std::string ip_address_;
ConnectionType type_;
int state_;
ConnectionError error_;
};
class EthernetNetwork : public Network {
public:
EthernetNetwork() : Network() {}
};
class WirelessNetwork : public Network {
public:
// WirelessNetwork are sorted by name.
bool operator< (const WirelessNetwork& other) const {
return name_ < other.name();
}
// We frequently want to compare networks by service path.
struct ServicePathEq {
explicit ServicePathEq(const std::string& path_in) : path(path_in) {}
bool operator()(const WirelessNetwork& a) {
return a.service_path().compare(path) == 0;
}
const std::string& path;
};
const std::string& name() const { return name_; }
int strength() const { return strength_; }
bool auto_connect() const { return auto_connect_; }
void set_name(const std::string& name) { name_ = name; }
void set_auto_connect(bool auto_connect) { auto_connect_ = auto_connect; }
// Network overrides.
virtual void Clear();
virtual void ConfigureFromService(const ServiceInfo& service);
protected:
WirelessNetwork()
: Network(),
strength_(0),
auto_connect_(false) {}
std::string name_;
int strength_;
bool auto_connect_;
};
class CellularNetwork : public WirelessNetwork {
public:
CellularNetwork() : WirelessNetwork() {}
explicit CellularNetwork(const ServiceInfo& service)
: WirelessNetwork() {
ConfigureFromService(service);
}
// WirelessNetwork overrides.
virtual void Clear();
virtual void ConfigureFromService(const ServiceInfo& service);
};
class WifiNetwork : public WirelessNetwork {
public:
WifiNetwork()
: WirelessNetwork(),
encryption_(SECURITY_NONE) {}
explicit WifiNetwork(const ServiceInfo& service)
: WirelessNetwork() {
ConfigureFromService(service);
}
bool encrypted() const { return encryption_ != SECURITY_NONE; }
ConnectionSecurity encryption() const { return encryption_; }
const std::string& passphrase() const { return passphrase_; }
const std::string& identity() const { return identity_; }
const std::string& cert_path() const { return cert_path_; }
void set_encryption(ConnectionSecurity encryption) {
encryption_ = encryption;
}
void set_passphrase(const std::string& passphrase) {
passphrase_ = passphrase;
}
void set_identity(const std::string& identity) {
identity_ = identity;
}
void set_cert_path(const std::string& cert_path) {
cert_path_ = cert_path;
}
// WirelessNetwork overrides.
virtual void Clear();
virtual void ConfigureFromService(const ServiceInfo& service);
// Return a string representation of the encryption code.
// This not translated and should be only used for debugging purposes.
std::string GetEncryptionString();
protected:
ConnectionSecurity encryption_;
std::string passphrase_;
std::string identity_;
std::string cert_path_;
};
typedef std::vector<WifiNetwork> WifiNetworkVector;
typedef std::vector<CellularNetwork> CellularNetworkVector;
struct CellTower {
enum RadioType {
RADIOTYPE_GSM,
RADIOTYPE_CDMA,
RADIOTYPE_WCDMA,
} radio_type; // GSM/WCDMA CDMA
int mobile_country_code; // MCC MCC
int mobile_network_code; // MNC SID
int location_area_code; // LAC NID
int cell_id; // CID BID
base::Time timestamp; // Timestamp when this cell was primary
int signal_strength; // Radio signal strength measured in dBm.
int timing_advance; // Represents the distance from the cell tower. Each
// unit is roughly 550 meters.
};
struct WifiAccessPoint {
std::string mac_address; // The mac address of the WiFi node.
std::string name; // The SSID of the WiFi node.
base::Time timestamp; // Timestamp when this AP was detected.
int signal_strength; // Radio signal strength measured in dBm.
int signal_to_noise; // Current signal to noise ratio measured in dB.
int channel; // Wifi channel number.
};
typedef std::vector<CellTower> CellTowerVector;
typedef std::vector<WifiAccessPoint> WifiAccessPointVector;
struct NetworkIPConfig {
NetworkIPConfig(const std::string& device_path, IPConfigType type,
const std::string& address, const std::string& netmask,
const std::string& gateway, const std::string& name_servers)
: device_path(device_path),
type(type),
address(address),
netmask(netmask),
gateway(gateway),
name_servers(name_servers) {}
// NetworkIPConfigs are sorted by tyoe.
bool operator< (const NetworkIPConfig& other) const {
return type < other.type;
}
std::string device_path;
IPConfigType type;
std::string address;
std::string netmask;
std::string gateway;
std::string name_servers;
};
typedef std::vector<NetworkIPConfig> NetworkIPConfigVector;
class NetworkLibrary {
public:
class Observer {
public:
// A bitfield mask for traffic types.
enum TrafficTypes {
TRAFFIC_DOWNLOAD = 0x1,
TRAFFIC_UPLOAD = 0x2,
} TrafficTypeMasks;
// Called when the network has changed. (wifi networks, and ethernet)
virtual void NetworkChanged(NetworkLibrary* obj) = 0;
// Called when network traffic has been detected.
// Takes a bitfield of TrafficTypeMasks.
virtual void NetworkTraffic(NetworkLibrary* obj, int traffic_type) = 0;
};
virtual ~NetworkLibrary() {}
virtual void AddObserver(Observer* observer) = 0;
virtual void RemoveObserver(Observer* observer) = 0;
virtual const EthernetNetwork& ethernet_network() const = 0;
virtual bool ethernet_connecting() const = 0;
virtual bool ethernet_connected() const = 0;
virtual const std::string& wifi_name() const = 0;
virtual bool wifi_connecting() const = 0;
virtual bool wifi_connected() const = 0;
virtual int wifi_strength() const = 0;
virtual const std::string& cellular_name() const = 0;
virtual bool cellular_connecting() const = 0;
virtual bool cellular_connected() const = 0;
virtual int cellular_strength() const = 0;
// Return true if any network is currently connected.
virtual bool Connected() const = 0;
// Return true if any network is currently connecting.
virtual bool Connecting() const = 0;
// Returns the current IP address if connected. If not, returns empty string.
virtual const std::string& IPAddress() const = 0;
// Returns the current list of wifi networks.
virtual const WifiNetworkVector& wifi_networks() const = 0;
// Returns the list of remembered wifi networks.
virtual const WifiNetworkVector& remembered_wifi_networks() const = 0;
// Returns the current list of cellular networks.
virtual const CellularNetworkVector& cellular_networks() const = 0;
// Returns the list of remembered cellular networks.
virtual const CellularNetworkVector& remembered_cellular_networks() const = 0;
// Search the current list of networks by path and if the network
// is available, copy the result and return true.
virtual bool FindWifiNetworkByPath(const std::string& path,
WifiNetwork* result) const = 0;
virtual bool FindCellularNetworkByPath(const std::string& path,
CellularNetwork* result) const = 0;
// Request a scan for new wifi networks.
virtual void RequestWifiScan() = 0;
// Reads out the results of the last wifi scan. These results are not
// pre-cached in the library, so the call may block whilst the results are
// read over IPC.
// Returns false if an error occurred in reading the results. Note that
// a true return code only indicates the result set was successfully read,
// it does not imply a scan has successfully completed yet.
virtual bool GetWifiAccessPoints(WifiAccessPointVector* result) = 0;
// TODO(joth): Add GetCellTowers to retrieve a CellTowerVector.
// Force an update of the system info.
virtual void UpdateSystemInfo() = 0;
// Attempt to connect to the preferred network if available and it is set up.
// This call will return true if connection is started.
// If the preferred network is not available or not setup, returns false.
// Note: For dogfood purposes, we hardcode the preferred network to Google-A.
virtual bool ConnectToPreferredNetworkIfAvailable() = 0;
// Returns true if we are currently connected to the preferred network.
virtual bool PreferredNetworkConnected() = 0;
// Returns true if we failed to connect to the preferred network.
virtual bool PreferredNetworkFailed() = 0;
// Connect to the specified wireless network with password.
virtual void ConnectToWifiNetwork(WifiNetwork network,
const std::string& password,
const std::string& identity,
const std::string& certpath) = 0;
// Connect to the specified wifi ssid with password.
virtual void ConnectToWifiNetwork(const std::string& ssid,
const std::string& password,
const std::string& identity,
const std::string& certpath,
bool auto_connect) = 0;
// Connect to the specified cellular network.
virtual void ConnectToCellularNetwork(CellularNetwork network) = 0;
// Disconnect from the specified wireless (either cellular or wifi) network.
virtual void DisconnectFromWirelessNetwork(
const WirelessNetwork& network) = 0;
// Save network information including passwords (wifi) and auto-connect.
virtual void SaveCellularNetwork(const CellularNetwork& network) = 0;
virtual void SaveWifiNetwork(const WifiNetwork& network) = 0;
// Forget the passed in wireless (either cellular or wifi) network.
virtual void ForgetWirelessNetwork(const WirelessNetwork& network) = 0;
virtual bool ethernet_available() const = 0;
virtual bool wifi_available() const = 0;
virtual bool cellular_available() const = 0;
virtual bool ethernet_enabled() const = 0;
virtual bool wifi_enabled() const = 0;
virtual bool cellular_enabled() const = 0;
virtual bool offline_mode() const = 0;
// Enables/disables the ethernet network device.
virtual void EnableEthernetNetworkDevice(bool enable) = 0;
// Enables/disables the wifi network device.
virtual void EnableWifiNetworkDevice(bool enable) = 0;
// Enables/disables the cellular network device.
virtual void EnableCellularNetworkDevice(bool enable) = 0;
// Enables/disables offline mode.
virtual void EnableOfflineMode(bool enable) = 0;
// Fetches IP configs for a given device_path
virtual NetworkIPConfigVector GetIPConfigs(
const std::string& device_path) = 0;
// Fetches debug network info for display in about:network.
// The page will have a meta refresh of |refresh| seconds if |refresh| > 0.
virtual std::string GetHtmlInfo(int refresh) = 0;
};
// This class handles the interaction with the ChromeOS network library APIs.
// Classes can add themselves as observers. Users can get an instance of this
// library class like this: NetworkLibrary::Get()
class NetworkLibraryImpl : public NetworkLibrary,
public URLRequestJobTracker::JobObserver {
public:
NetworkLibraryImpl();
virtual ~NetworkLibraryImpl();
// URLRequestJobTracker::JobObserver methods (called on the IO thread):
virtual void OnJobAdded(URLRequestJob* job);
virtual void OnJobRemoved(URLRequestJob* job);
virtual void OnJobDone(URLRequestJob* job, const URLRequestStatus& status);
virtual void OnJobRedirect(URLRequestJob* job, const GURL& location,
int status_code);
virtual void OnBytesRead(URLRequestJob* job, const char* buf, int byte_count);
// NetworkLibrary overrides.
virtual void AddObserver(Observer* observer);
virtual void RemoveObserver(Observer* observer);
virtual const EthernetNetwork& ethernet_network() const { return ethernet_; }
virtual bool ethernet_connecting() const { return ethernet_.connecting(); }
virtual bool ethernet_connected() const { return ethernet_.connected(); }
virtual const std::string& wifi_name() const { return wifi_.name(); }
virtual bool wifi_connecting() const { return wifi_.connecting(); }
virtual bool wifi_connected() const { return wifi_.connected(); }
virtual int wifi_strength() const { return wifi_.strength(); }
virtual const std::string& cellular_name() const { return cellular_.name(); }
virtual bool cellular_connecting() const { return cellular_.connecting(); }
virtual bool cellular_connected() const { return cellular_.connected(); }
virtual int cellular_strength() const { return cellular_.strength(); }
virtual bool Connected() const;
virtual bool Connecting() const;
virtual const std::string& IPAddress() const;
virtual const WifiNetworkVector& wifi_networks() const {
return wifi_networks_;
}
virtual const WifiNetworkVector& remembered_wifi_networks() const {
return remembered_wifi_networks_;
}
virtual const CellularNetworkVector& cellular_networks() const {
return cellular_networks_;
}
virtual const CellularNetworkVector& remembered_cellular_networks() const {
return remembered_cellular_networks_;
}
virtual bool FindWifiNetworkByPath(const std::string& path,
WifiNetwork* network) const;
virtual bool FindCellularNetworkByPath(const std::string& path,
CellularNetwork* network) const;
virtual void RequestWifiScan();
virtual bool GetWifiAccessPoints(WifiAccessPointVector* result);
virtual bool ConnectToPreferredNetworkIfAvailable();
virtual bool PreferredNetworkConnected();
virtual bool PreferredNetworkFailed();
virtual void ConnectToWifiNetwork(WifiNetwork network,
const std::string& password,
const std::string& identity,
const std::string& certpath);
virtual void ConnectToWifiNetwork(const std::string& ssid,
const std::string& password,
const std::string& identity,
const std::string& certpath,
bool auto_connect);
virtual void ConnectToCellularNetwork(CellularNetwork network);
virtual void DisconnectFromWirelessNetwork(const WirelessNetwork& network);
virtual void SaveCellularNetwork(const CellularNetwork& network);
virtual void SaveWifiNetwork(const WifiNetwork& network);
virtual void ForgetWirelessNetwork(const WirelessNetwork& network);
virtual bool ethernet_available() const {
return available_devices_ & (1 << TYPE_ETHERNET);
}
virtual bool wifi_available() const {
return available_devices_ & (1 << TYPE_WIFI);
}
virtual bool cellular_available() const {
return available_devices_ & (1 << TYPE_CELLULAR);
}
virtual bool ethernet_enabled() const {
return enabled_devices_ & (1 << TYPE_ETHERNET);
}
virtual bool wifi_enabled() const {
return enabled_devices_ & (1 << TYPE_WIFI);
}
virtual bool cellular_enabled() const {
return enabled_devices_ & (1 << TYPE_CELLULAR);
}
virtual bool offline_mode() const { return offline_mode_; }
virtual void EnableEthernetNetworkDevice(bool enable);
virtual void EnableWifiNetworkDevice(bool enable);
virtual void EnableCellularNetworkDevice(bool enable);
virtual void EnableOfflineMode(bool enable);
virtual NetworkIPConfigVector GetIPConfigs(const std::string& device_path);
virtual std::string GetHtmlInfo(int refresh);
virtual void UpdateSystemInfo();
private:
// This method is called when there's a change in network status.
// This method is called on a background thread.
static void NetworkStatusChangedHandler(void* object);
// This parses SystemInfo into:
// - an EthernetNetwork
// - a WifiNetworkVector of wifi networks
// - a CellularNetworkVector of cellular networks.
// - a WifiNetworkVector of remembered wifi networks
// - a CellularNetworkVector of remembered cellular networks.
static void ParseSystem(SystemInfo* system,
EthernetNetwork* ethernet,
WifiNetworkVector* wifi_networks,
CellularNetworkVector* ceullular_networks,
WifiNetworkVector* remembered_wifi_networks,
CellularNetworkVector* remembered_ceullular_networks);
// This methods loads the initial list of networks on startup and starts the
// monitoring of network changes.
void Init();
// Returns the preferred wifi network.
WifiNetwork* GetPreferredNetwork();
// Gets the WifiNetwork with the given name. Returns NULL if not found.
// Only used by GetPreferredNetwork() to lookup "Google" and "GoogleA" (hack)
WifiNetwork* GetWifiNetworkByName(const std::string& name);
// Gets the WirelessNetwork (WifiNetwork or CellularNetwork) by path
template<typename T>
T* GetWirelessNetworkByPath(std::vector<T>& networks,
const std::string& path);
template<typename T>
const T* GetWirelessNetworkByPath(const std::vector<T>& networks,
const std::string& path) const;
// Enables/disables the specified network device.
void EnableNetworkDeviceType(ConnectionType device, bool enable);
// Update the cached network status.
// This will notify all the Observers.
void UpdateNetworkStatus();
// Checks network traffic to see if there is any uploading.
// If there is download traffic, then true is passed in for download.
// If there is network traffic then start timer that invokes
// NetworkTrafficTimerFired.
void CheckNetworkTraffic(bool download);
// Called when the timer fires and we need to send out NetworkTraffic
// notifications.
void NetworkTrafficTimerFired();
// This is a helper method to notify the observers on the UI thread.
void NotifyNetworkTraffic(int traffic_type);
// This will notify all obeservers on the UI thread.
void NotifyObservers();
ObserverList<Observer> observers_;
// The amount of time to wait between each NetworkTraffic notifications.
static const int kNetworkTrafficeTimerSecs;
// Timer for sending NetworkTraffic notification every
// kNetworkTrafficeTimerSecs seconds.
base::OneShotTimer<NetworkLibraryImpl> timer_;
// The current traffic type that will be sent out for the next NetworkTraffic
// notification. This is a bitfield of TrafficTypeMasks.
int traffic_type_;
// The network status connection for monitoring network status changes.
MonitorNetworkConnection network_status_connection_;
// The ethernet network.
EthernetNetwork ethernet_;
// The list of available wifi networks.
WifiNetworkVector wifi_networks_;
// The current connected (or connecting) wifi network.
WifiNetwork wifi_;
// The remembered wifi networks.
WifiNetworkVector remembered_wifi_networks_;
// The list of available cellular networks.
CellularNetworkVector cellular_networks_;
// The current connected (or connecting) cellular network.
CellularNetwork cellular_;
// The remembered cellular networks.
CellularNetworkVector remembered_cellular_networks_;
// The current available network devices. Bitwise flag of ConnectionTypes.
int available_devices_;
// The current enabled network devices. Bitwise flag of ConnectionTypes.
int enabled_devices_;
// The current connected network devices. Bitwise flag of ConnectionTypes.
int connected_devices_;
bool offline_mode_;
DISALLOW_COPY_AND_ASSIGN(NetworkLibraryImpl);
};
} // namespace chromeos
#endif // CHROME_BROWSER_CHROMEOS_CROS_NETWORK_LIBRARY_H_