diff options
| author | Ben Murdoch <benm@google.com> | 2010-11-18 18:32:45 +0000 |
|---|---|---|
| committer | Ben Murdoch <benm@google.com> | 2010-11-18 18:38:07 +0000 |
| commit | 513209b27ff55e2841eac0e4120199c23acce758 (patch) | |
| tree | aeba30bb08c5f47c57003544e378a377c297eee6 /chrome/browser/chromeos/cros/network_library.cc | |
| parent | 164f7496de0fbee436b385a79ead9e3cb81a50c1 (diff) | |
| download | external_chromium-513209b27ff55e2841eac0e4120199c23acce758.zip external_chromium-513209b27ff55e2841eac0e4120199c23acce758.tar.gz external_chromium-513209b27ff55e2841eac0e4120199c23acce758.tar.bz2 | |
Merge Chromium at r65505: Initial merge by git.
Change-Id: I31d8f1d8cd33caaf7f47ffa7350aef42d5fbdb45
Diffstat (limited to 'chrome/browser/chromeos/cros/network_library.cc')
| -rw-r--r-- | chrome/browser/chromeos/cros/network_library.cc | 1290 |
1 files changed, 850 insertions, 440 deletions
diff --git a/chrome/browser/chromeos/cros/network_library.cc b/chrome/browser/chromeos/cros/network_library.cc index 896f35c..7e878dd 100644 --- a/chrome/browser/chromeos/cros/network_library.cc +++ b/chrome/browser/chromeos/cros/network_library.cc @@ -5,17 +5,145 @@ #include "chrome/browser/chromeos/cros/network_library.h" #include <algorithm> +#include <map> #include "app/l10n_util.h" +#include "base/stl_util-inl.h" #include "base/string_number_conversions.h" #include "base/string_util.h" #include "base/utf_string_conversions.h" +#include "base/values.h" #include "chrome/browser/browser_thread.h" #include "chrome/browser/chromeos/cros/cros_library.h" #include "grit/generated_resources.h" +namespace { + +// FlimFlam may send multiple notifications for single network change. +// We wait small amount of time before retrieving the status to +// avoid send multiple sync request to flim flam. +const int kNetworkUpdateDelayMs = 50; + +} // namespace + namespace chromeos { +namespace { +// TODO(ers) These string constants and Parse functions are copied +// straight out of libcros:chromeos_network.cc. Fix this by moving +// all handling of properties into libcros. +// Network service properties we are interested in monitoring +static const char* kIsActiveProperty = "IsActive"; +static const char* kStateProperty = "State"; +static const char* kSignalStrengthProperty = "Strength"; +static const char* kActivationStateProperty = "Cellular.ActivationState"; +static const char* kNetworkTechnologyProperty = "Cellular.NetworkTechnology"; +static const char* kPaymentURLProperty = "Cellular.OlpUrl"; +static const char* kRestrictedPoolProperty = "Cellular.RestrictedPool"; +static const char* kRoamingStateProperty = "Cellular.RoamingState"; + +// Connman state options. +static const char* kStateIdle = "idle"; +static const char* kStateCarrier = "carrier"; +static const char* kStateAssociation = "association"; +static const char* kStateConfiguration = "configuration"; +static const char* kStateReady = "ready"; +static const char* kStateDisconnect = "disconnect"; +static const char* kStateFailure = "failure"; +static const char* kStateActivationFailure = "activation-failure"; + +// Connman activation state options +static const char* kActivationStateActivated = "activated"; +static const char* kActivationStateActivating = "activating"; +static const char* kActivationStateNotActivated = "not-activated"; +static const char* kActivationStatePartiallyActivated = "partially-activated"; +static const char* kActivationStateUnknown = "unknown"; + +// Connman network technology options. +static const char* kNetworkTechnology1Xrtt = "1xRTT"; +static const char* kNetworkTechnologyEvdo = "EVDO"; +static const char* kNetworkTechnologyGprs = "GPRS"; +static const char* kNetworkTechnologyEdge = "EDGE"; +static const char* kNetworkTechnologyUmts = "UMTS"; +static const char* kNetworkTechnologyHspa = "HSPA"; +static const char* kNetworkTechnologyHspaPlus = "HSPA+"; +static const char* kNetworkTechnologyLte = "LTE"; +static const char* kNetworkTechnologyLteAdvanced = "LTE Advanced"; + +// Connman roaming state options +static const char* kRoamingStateHome = "home"; +static const char* kRoamingStateRoaming = "roaming"; +static const char* kRoamingStateUnknown = "unknown"; + +static ConnectionState ParseState(const std::string& state) { + if (state == kStateIdle) + return STATE_IDLE; + if (state == kStateCarrier) + return STATE_CARRIER; + if (state == kStateAssociation) + return STATE_ASSOCIATION; + if (state == kStateConfiguration) + return STATE_CONFIGURATION; + if (state == kStateReady) + return STATE_READY; + if (state == kStateDisconnect) + return STATE_DISCONNECT; + if (state == kStateFailure) + return STATE_FAILURE; + if (state == kStateActivationFailure) + return STATE_ACTIVATION_FAILURE; + return STATE_UNKNOWN; +} + +static ActivationState ParseActivationState( + const std::string& activation_state) { + if (activation_state == kActivationStateActivated) + return ACTIVATION_STATE_ACTIVATED; + if (activation_state == kActivationStateActivating) + return ACTIVATION_STATE_ACTIVATING; + if (activation_state == kActivationStateNotActivated) + return ACTIVATION_STATE_NOT_ACTIVATED; + if (activation_state == kActivationStateUnknown) + return ACTIVATION_STATE_UNKNOWN; + if (activation_state == kActivationStatePartiallyActivated) + return ACTIVATION_STATE_PARTIALLY_ACTIVATED; + return ACTIVATION_STATE_UNKNOWN; +} + +static NetworkTechnology ParseNetworkTechnology( + const std::string& technology) { + if (technology == kNetworkTechnology1Xrtt) + return NETWORK_TECHNOLOGY_1XRTT; + if (technology == kNetworkTechnologyEvdo) + return NETWORK_TECHNOLOGY_EVDO; + if (technology == kNetworkTechnologyGprs) + return NETWORK_TECHNOLOGY_GPRS; + if (technology == kNetworkTechnologyEdge) + return NETWORK_TECHNOLOGY_EDGE; + if (technology == kNetworkTechnologyUmts) + return NETWORK_TECHNOLOGY_UMTS; + if (technology == kNetworkTechnologyHspa) + return NETWORK_TECHNOLOGY_HSPA; + if (technology == kNetworkTechnologyHspaPlus) + return NETWORK_TECHNOLOGY_HSPA_PLUS; + if (technology == kNetworkTechnologyLte) + return NETWORK_TECHNOLOGY_LTE; + if (technology == kNetworkTechnologyLteAdvanced) + return NETWORK_TECHNOLOGY_LTE_ADVANCED; + return NETWORK_TECHNOLOGY_UNKNOWN; +} +static NetworkRoamingState ParseRoamingState( + const std::string& roaming_state) { + if (roaming_state == kRoamingStateHome) + return ROAMING_STATE_HOME; + if (roaming_state == kRoamingStateRoaming) + return ROAMING_STATE_ROAMING; + if (roaming_state == kRoamingStateUnknown) + return ROAMING_STATE_UNKNOWN; + return ROAMING_STATE_UNKNOWN; +} +} + // Helper function to wrap Html with <th> tag. static std::string WrapWithTH(std::string text) { return "<th>" + text + "</th>"; @@ -82,24 +210,35 @@ static bool EnsureCrosLoaded() { //////////////////////////////////////////////////////////////////////////////// // Network +Network::Network(const Network& network) { + service_path_ = network.service_path(); + device_path_ = network.device_path(); + ip_address_ = network.ip_address(); + type_ = network.type(); + state_ = network.state(); + error_ = network.error(); +} + void Network::Clear() { state_ = STATE_UNKNOWN; error_ = ERROR_UNKNOWN; service_path_.clear(); device_path_.clear(); ip_address_.clear(); + is_active_ = false; } -void Network::ConfigureFromService(const ServiceInfo& service) { - type_ = service.type; - state_ = service.state; - error_ = service.error; - service_path_ = SafeString(service.service_path); - device_path_ = SafeString(service.device_path); +Network::Network(const ServiceInfo* service) { + type_ = service->type; + state_ = service->state; + error_ = service->error; + service_path_ = SafeString(service->service_path); + device_path_ = SafeString(service->device_path); + is_active_ = service->is_active; ip_address_.clear(); // If connected, get ip config. - if (EnsureCrosLoaded() && connected() && service.device_path) { - IPConfigStatus* ipconfig_status = ListIPConfigs(service.device_path); + if (EnsureCrosLoaded() && connected() && service->device_path) { + IPConfigStatus* ipconfig_status = ListIPConfigs(service->device_path); if (ipconfig_status) { for (int i = 0; i < ipconfig_status->size; i++) { IPConfig ipconfig = ipconfig_status->ips[i]; @@ -179,6 +318,21 @@ std::string Network::GetErrorString() const { //////////////////////////////////////////////////////////////////////////////// // WirelessNetwork +WirelessNetwork::WirelessNetwork(const WirelessNetwork& network) + : Network(network) { + name_ = network.name(); + strength_ = network.strength(); + auto_connect_ = network.auto_connect(); + favorite_ = network.favorite(); +} + +WirelessNetwork::WirelessNetwork(const ServiceInfo* service) + : Network(service) { + name_ = SafeString(service->name); + strength_ = service->strength; + auto_connect_ = service->auto_connect; + favorite_ = service->favorite; +} void WirelessNetwork::Clear() { Network::Clear(); @@ -188,14 +342,6 @@ void WirelessNetwork::Clear() { favorite_ = false; } -void WirelessNetwork::ConfigureFromService(const ServiceInfo& service) { - Network::ConfigureFromService(service); - name_ = SafeString(service.name); - strength_ = service.strength; - auto_connect_ = service.auto_connect; - favorite_ = service.favorite; -} - //////////////////////////////////////////////////////////////////////////////// // CellularNetwork @@ -210,6 +356,65 @@ CellularNetwork::CellularNetwork() type_ = TYPE_CELLULAR; } +CellularNetwork::CellularNetwork(const CellularNetwork& network) + : WirelessNetwork(network) { + activation_state_ = network.activation_state(); + network_technology_ = network.network_technology(); + roaming_state_ = network.roaming_state(); + restricted_pool_ = network.restricted_pool(); + service_name_ = network.service_name(); + operator_name_ = network.operator_name(); + operator_code_ = network.operator_code(); + payment_url_ = network.payment_url(); + meid_ = network.meid(); + imei_ = network.imei(); + imsi_ = network.imsi(); + esn_ = network.esn(); + mdn_ = network.mdn(); + min_ = network.min(); + model_id_ = network.model_id(); + manufacturer_ = network.manufacturer(); + firmware_revision_ = network.firmware_revision(); + hardware_revision_ = network.hardware_revision(); + last_update_ = network.last_update(); + prl_version_ = network.prl_version(); + type_ = TYPE_CELLULAR; +} + +CellularNetwork::CellularNetwork(const ServiceInfo* service) + : WirelessNetwork(service) { + service_name_ = SafeString(service->name); + activation_state_ = service->activation_state; + network_technology_ = service->network_technology; + roaming_state_ = service->roaming_state; + restricted_pool_ = service->restricted_pool; + // Carrier Info + if (service->carrier_info) { + operator_name_ = SafeString(service->carrier_info->operator_name); + operator_code_ = SafeString(service->carrier_info->operator_code); + payment_url_ = SafeString(service->carrier_info->payment_url); + } + // Device Info + if (service->device_info) { + meid_ = SafeString(service->device_info->MEID); + imei_ = SafeString(service->device_info->IMEI); + imsi_ = SafeString(service->device_info->IMSI); + esn_ = SafeString(service->device_info->ESN); + mdn_ = SafeString(service->device_info->MDN); + min_ = SafeString(service->device_info->MIN); + model_id_ = SafeString(service->device_info->model_id); + manufacturer_ = SafeString(service->device_info->manufacturer); + firmware_revision_ = SafeString(service->device_info->firmware_revision); + hardware_revision_ = SafeString(service->device_info->hardware_revision); + last_update_ = SafeString(service->device_info->last_update); + prl_version_ = service->device_info->PRL_version; + } + type_ = TYPE_CELLULAR; +} + +CellularNetwork::~CellularNetwork() { +} + bool CellularNetwork::StartActivation() const { if (!EnsureCrosLoaded()) return false; @@ -240,36 +445,6 @@ void CellularNetwork::Clear() { prl_version_ = 0; } -void CellularNetwork::ConfigureFromService(const ServiceInfo& service) { - WirelessNetwork::ConfigureFromService(service); - service_name_ = SafeString(service.name); - activation_state_ = service.activation_state; - network_technology_ = service.network_technology; - roaming_state_ = service.roaming_state; - restricted_pool_ = service.restricted_pool; - // Carrier Info - if (service.carrier_info) { - operator_name_ = SafeString(service.carrier_info->operator_name); - operator_code_ = SafeString(service.carrier_info->operator_code); - payment_url_ = SafeString(service.carrier_info->payment_url); - } - // Device Info - if (service.device_info) { - meid_ = SafeString(service.device_info->MEID); - imei_ = SafeString(service.device_info->IMEI); - imsi_ = SafeString(service.device_info->IMSI); - esn_ = SafeString(service.device_info->ESN); - mdn_ = SafeString(service.device_info->MDN); - min_ = SafeString(service.device_info->MIN); - model_id_ = SafeString(service.device_info->model_id); - manufacturer_ = SafeString(service.device_info->manufacturer); - firmware_revision_ = SafeString(service.device_info->firmware_revision); - hardware_revision_ = SafeString(service.device_info->hardware_revision); - last_update_ = SafeString(service.device_info->last_update); - prl_version_ = service.device_info->PRL_version; - } -} - bool CellularNetwork::is_gsm() const { return network_technology_ != NETWORK_TECHNOLOGY_EVDO && network_technology_ != NETWORK_TECHNOLOGY_1XRTT && @@ -279,14 +454,15 @@ bool CellularNetwork::is_gsm() const { CellularNetwork::DataLeft CellularNetwork::data_left() const { if (data_plans_.empty()) return DATA_NORMAL; - CellularDataPlan plan = data_plans_[0]; + const CellularDataPlan& plan(data_plans_[0]); if (plan.plan_type == CELLULAR_DATA_PLAN_UNLIMITED) { - int64 remaining = plan.plan_end_time - plan.update_time; - if (remaining <= 0) + base::TimeDelta remaining = plan.plan_end_time - plan.update_time; + if (remaining <= base::TimeDelta::FromSeconds(0)) return DATA_NONE; - else if (remaining <= kCellularDataVeryLowSecs) + else if (remaining <= + base::TimeDelta::FromSeconds(kCellularDataVeryLowSecs)) return DATA_VERY_LOW; - else if (remaining <= kCellularDataLowSecs) + else if (remaining <= base::TimeDelta::FromSeconds(kCellularDataLowSecs)) return DATA_LOW; else return DATA_NORMAL; @@ -342,8 +518,9 @@ std::string CellularNetwork::GetNetworkTechnologyString() const { } } -std::string CellularNetwork::GetActivationStateString() const { - switch (this->activation_state_) { +std::string CellularNetwork::ActivationStateToString( + ActivationState activation_state) { + switch (activation_state) { case ACTIVATION_STATE_ACTIVATED: return l10n_util::GetStringUTF8( IDS_CHROMEOS_NETWORK_ACTIVATION_STATE_ACTIVATED); @@ -367,6 +544,10 @@ std::string CellularNetwork::GetActivationStateString() const { } } +std::string CellularNetwork::GetActivationStateString() const { + return ActivationStateToString(this->activation_state_); +} + std::string CellularNetwork::GetRoamingStateString() const { switch (this->roaming_state_) { case ROAMING_STATE_HOME: @@ -394,8 +575,28 @@ WifiNetwork::WifiNetwork() type_ = TYPE_WIFI; } -WifiNetwork::WifiNetwork(const ServiceInfo& service) : WirelessNetwork() { - ConfigureFromService(service); +WifiNetwork::WifiNetwork(const WifiNetwork& network) + : WirelessNetwork(network) { + encryption_ = network.encryption(); + passphrase_ = network.passphrase(); + passphrase_required_ = network.passphrase_required(); + identity_ = network.identity(); + cert_path_ = network.cert_path(); +} + +WifiNetwork::WifiNetwork(const ServiceInfo* service) + : WirelessNetwork(service) { + encryption_ = service->security; + passphrase_ = SafeString(service->passphrase); + // TODO(stevenjb): Remove this once flimflam is setting passphrase_required + // correctly: http://crosbug.com/8830. + if (service->state == chromeos::STATE_FAILURE && + service->security != chromeos::SECURITY_NONE) + passphrase_required_ = true; + else + passphrase_required_ = service->passphrase_required; + identity_ = SafeString(service->identity); + cert_path_ = SafeString(service->cert_path); type_ = TYPE_WIFI; } @@ -407,14 +608,6 @@ void WifiNetwork::Clear() { cert_path_.clear(); } -void WifiNetwork::ConfigureFromService(const ServiceInfo& service) { - WirelessNetwork::ConfigureFromService(service); - encryption_ = service.security; - passphrase_ = SafeString(service.passphrase); - identity_ = SafeString(service.identity); - cert_path_ = SafeString(service.cert_path); -} - std::string WifiNetwork::GetEncryptionString() { switch (encryption_) { case SECURITY_UNKNOWN: @@ -457,47 +650,145 @@ bool WifiNetwork::IsCertificateLoaded() const { class NetworkLibraryImpl : public NetworkLibrary { public: NetworkLibraryImpl() - : network_status_connection_(NULL), + : network_manager_monitor_(NULL), data_plan_monitor_(NULL), + ethernet_(NULL), + wifi_(NULL), + cellular_(NULL), available_devices_(0), enabled_devices_(0), connected_devices_(0), - offline_mode_(false) { + offline_mode_(false), + update_task_(NULL) { if (EnsureCrosLoaded()) { Init(); + network_manager_monitor_ = + MonitorNetworkManager(&NetworkManagerStatusChangedHandler, + this); + data_plan_monitor_ = MonitorCellularDataPlan(&DataPlanUpdateHandler, + this); } else { InitTestData(); } } ~NetworkLibraryImpl() { - if (network_status_connection_) { - DisconnectMonitorNetwork(network_status_connection_); - } - if (data_plan_monitor_) { + network_manager_observers_.Clear(); + if (network_manager_monitor_) + DisconnectPropertyChangeMonitor(network_manager_monitor_); + data_plan_observers_.Clear(); + if (data_plan_monitor_) DisconnectDataPlanUpdateMonitor(data_plan_monitor_); + STLDeleteValues(&network_observers_); + ClearNetworks(); + } + + virtual void AddNetworkManagerObserver(NetworkManagerObserver* observer) { + if (!network_manager_observers_.HasObserver(observer)) + network_manager_observers_.AddObserver(observer); + } + + void NetworkStatusChanged() { + CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + if (update_task_) { + update_task_->Cancel(); + } + update_task_ = + NewRunnableMethod(this, + &NetworkLibraryImpl::UpdateNetworkManagerStatus); + BrowserThread::PostDelayedTask( + BrowserThread::UI, FROM_HERE, update_task_, + kNetworkUpdateDelayMs); + } + + virtual void RemoveNetworkManagerObserver(NetworkManagerObserver* observer) { + network_manager_observers_.RemoveObserver(observer); + } + + virtual void AddNetworkObserver(const std::string& service_path, + NetworkObserver* observer) { + DCHECK(observer); + if (!EnsureCrosLoaded()) + return; + // First, add the observer to the callback map. + NetworkObserverMap::iterator iter = network_observers_.find(service_path); + NetworkObserverList* oblist; + if (iter != network_observers_.end()) { + oblist = iter->second; + } else { + std::pair<NetworkObserverMap::iterator, bool> inserted = + network_observers_.insert( + std::make_pair<std::string, NetworkObserverList*>( + service_path, + new NetworkObserverList(this, service_path))); + oblist = inserted.first->second; + } + if (!oblist->HasObserver(observer)) + oblist->AddObserver(observer); + } + + virtual void RemoveNetworkObserver(const std::string& service_path, + NetworkObserver* observer) { + DCHECK(observer); + DCHECK(service_path.size()); + NetworkObserverMap::iterator map_iter = + network_observers_.find(service_path); + if (map_iter != network_observers_.end()) { + map_iter->second->RemoveObserver(observer); + if (!map_iter->second->size()) { + delete map_iter->second; + network_observers_.erase(map_iter++); + } } } - void AddObserver(Observer* observer) { - observers_.AddObserver(observer); + virtual void RemoveObserverForAllNetworks(NetworkObserver* observer) { + DCHECK(observer); + NetworkObserverMap::iterator map_iter = network_observers_.begin(); + while (map_iter != network_observers_.end()) { + map_iter->second->RemoveObserver(observer); + if (!map_iter->second->size()) { + delete map_iter->second; + network_observers_.erase(map_iter++); + } else { + ++map_iter; + } + } } - void RemoveObserver(Observer* observer) { - observers_.RemoveObserver(observer); + virtual void AddCellularDataPlanObserver(CellularDataPlanObserver* observer) { + if (!data_plan_observers_.HasObserver(observer)) + data_plan_observers_.AddObserver(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 void RemoveCellularDataPlanObserver( + CellularDataPlanObserver* observer) { + data_plan_observers_.RemoveObserver(observer); + } - virtual const WifiNetwork& wifi_network() const { return wifi_; } - virtual bool wifi_connecting() const { return wifi_.connecting(); } - virtual bool wifi_connected() const { return wifi_.connected(); } + virtual EthernetNetwork* ethernet_network() { return ethernet_; } + virtual bool ethernet_connecting() const { + return ethernet_ ? ethernet_->connecting() : false; + } + virtual bool ethernet_connected() const { + return ethernet_ ? ethernet_->connected() : false; + } - virtual const CellularNetwork& cellular_network() const { return cellular_; } - virtual bool cellular_connecting() const { return cellular_.connecting(); } - virtual bool cellular_connected() const { return cellular_.connected(); } + virtual WifiNetwork* wifi_network() { return wifi_; } + virtual bool wifi_connecting() const { + return wifi_ ? wifi_->connecting() : false; + } + virtual bool wifi_connected() const { + return wifi_ ? wifi_->connected() : false; + } + + virtual CellularNetwork* cellular_network() { return cellular_; } + virtual bool cellular_connecting() const { + return cellular_ ? cellular_->connecting() : false; + } + virtual bool cellular_connected() const { + return cellular_ ? cellular_->connected() : false; + } bool Connected() const { return ethernet_connected() || wifi_connected() || cellular_connected(); @@ -508,14 +799,14 @@ class NetworkLibraryImpl : public NetworkLibrary { } const std::string& IPAddress() const { - // Returns highest priority IP address. - if (ethernet_connected()) - return ethernet_.ip_address(); - if (wifi_connected()) - return wifi_.ip_address(); - if (cellular_connected()) - return cellular_.ip_address(); - return ethernet_.ip_address(); + // Returns IP address for the active network. + const Network* active = active_network(); + if (active != NULL) + return active->ip_address(); + if (ethernet_) + return ethernet_->ip_address(); + static std::string null_address("0.0.0.0"); + return null_address; } virtual const WifiNetworkVector& wifi_networks() const { @@ -530,34 +821,16 @@ class NetworkLibraryImpl : public NetworkLibrary { return cellular_networks_; } - virtual const CellularNetworkVector& remembered_cellular_networks() const { - return remembered_cellular_networks_; - } - ///////////////////////////////////////////////////////////////////////////// - virtual bool FindWifiNetworkByPath( - const std::string& path, WifiNetwork* result) const { - const WifiNetwork* wifi = - GetWirelessNetworkByPath(wifi_networks_, path); - if (wifi) { - if (result) - *result = *wifi; - return true; - } - return false; + virtual WifiNetwork* FindWifiNetworkByPath( + const std::string& path) { + return GetWirelessNetworkByPath(wifi_networks_, path); } - virtual bool FindCellularNetworkByPath( - const std::string& path, CellularNetwork* result) const { - const CellularNetwork* cellular = - GetWirelessNetworkByPath(cellular_networks_, path); - if (cellular) { - if (result) - *result = *cellular; - return true; - } - return false; + virtual CellularNetwork* FindCellularNetworkByPath( + const std::string& path) { + return GetWirelessNetworkByPath(cellular_networks_, path); } virtual void RequestWifiScan() { @@ -591,148 +864,158 @@ class NetworkLibraryImpl : public NetworkLibrary { return true; } - virtual void ConnectToWifiNetwork(WifiNetwork network, + virtual bool ConnectToWifiNetwork(const WifiNetwork* network, const std::string& password, const std::string& identity, const std::string& certpath) { - if (EnsureCrosLoaded()) { - if (ConnectToNetworkWithCertInfo(network.service_path().c_str(), - password.empty() ? NULL : password.c_str(), - identity.empty() ? NULL : identity.c_str(), - certpath.empty() ? NULL : certpath.c_str())) { - // Update local cache and notify listeners. - WifiNetwork* wifi = GetWirelessNetworkByPath( - wifi_networks_, network.service_path()); - if (wifi) { - wifi->set_passphrase(password); - wifi->set_identity(identity); - wifi->set_cert_path(certpath); - wifi->set_connecting(true); - wifi_ = *wifi; - } - NotifyNetworkChanged(); + DCHECK(network); + if (!EnsureCrosLoaded()) + return true; // No library loaded, don't trigger a retry attempt. + // TODO(ers) make wifi the highest priority service type + if (ConnectToNetworkWithCertInfo(network->service_path().c_str(), + password.empty() ? NULL : password.c_str(), + identity.empty() ? NULL : identity.c_str(), + certpath.empty() ? NULL : certpath.c_str())) { + // Update local cache and notify listeners. + WifiNetwork* wifi = GetWirelessNetworkByPath( + wifi_networks_, network->service_path()); + if (wifi) { + wifi->set_passphrase(password); + wifi->set_identity(identity); + wifi->set_cert_path(certpath); + wifi->set_connecting(true); + wifi_ = wifi; } + NotifyNetworkManagerChanged(); + return true; + } else { + return false; // Immediate failure. } } - virtual void ConnectToWifiNetwork(const std::string& ssid, + virtual bool ConnectToWifiNetwork(ConnectionSecurity security, + const std::string& ssid, const std::string& password, const std::string& identity, const std::string& certpath, bool auto_connect) { - if (EnsureCrosLoaded()) { - // First create a service from hidden network. - ServiceInfo* service = GetWifiService(ssid.c_str(), - SECURITY_UNKNOWN); - if (service) { - // Set auto-connect. - SetAutoConnect(service->service_path, auto_connect); - // Now connect to that service. - ConnectToNetworkWithCertInfo(service->service_path, - password.empty() ? NULL : password.c_str(), - identity.empty() ? NULL : identity.c_str(), - certpath.empty() ? NULL : certpath.c_str()); - - // Clean up ServiceInfo object. - FreeServiceInfo(service); - } else { - LOG(WARNING) << "Cannot find hidden network: " << ssid; - // TODO(chocobo): Show error message. - } + if (!EnsureCrosLoaded()) + return true; // No library loaded, don't trigger a retry attempt. + // First create a service from hidden network. + ServiceInfo* service = GetWifiService(ssid.c_str(), security); + if (service) { + // Set auto-connect. + SetAutoConnect(service->service_path, auto_connect); + // Now connect to that service. + // TODO(ers) make wifi the highest priority service type + bool res = ConnectToNetworkWithCertInfo( + service->service_path, + password.empty() ? NULL : password.c_str(), + identity.empty() ? NULL : identity.c_str(), + certpath.empty() ? NULL : certpath.c_str()); + + // Clean up ServiceInfo object. + FreeServiceInfo(service); + return res; + } else { + LOG(WARNING) << "Cannot find hidden network: " << ssid; + // TODO(chocobo): Show error message. + return false; // Immediate failure. } } - virtual void ConnectToCellularNetwork(CellularNetwork network) { - if (EnsureCrosLoaded()) { - if (ConnectToNetwork(network.service_path().c_str(), NULL)) { - // Update local cache and notify listeners. - CellularNetwork* cellular = GetWirelessNetworkByPath( - cellular_networks_, network.service_path()); - if (cellular) { - cellular->set_connecting(true); - cellular_ = *cellular; - } - NotifyNetworkChanged(); + virtual bool ConnectToCellularNetwork(const CellularNetwork* network) { + DCHECK(network); + if (!EnsureCrosLoaded()) + return true; // No library loaded, don't trigger a retry attempt. + // TODO(ers) make cellular the highest priority service type + if (network && ConnectToNetwork(network->service_path().c_str(), NULL)) { + // Update local cache and notify listeners. + CellularNetwork* cellular = GetWirelessNetworkByPath( + cellular_networks_, network->service_path()); + if (cellular) { + cellular->set_connecting(true); + cellular_ = cellular; } + NotifyNetworkManagerChanged(); + return true; + } else { + return false; // Immediate failure. } } - virtual void RefreshCellularDataPlans(const CellularNetwork& network) { - if (!EnsureCrosLoaded()) + virtual void RefreshCellularDataPlans(const CellularNetwork* network) { + DCHECK(network); + if (!EnsureCrosLoaded() || !network) return; - RequestCellularDataPlanUpdate(network.service_path().c_str()); + RequestCellularDataPlanUpdate(network->service_path().c_str()); } - virtual void DisconnectFromWirelessNetwork(const WirelessNetwork& network) { - if (EnsureCrosLoaded()) { - if (DisconnectFromNetwork(network.service_path().c_str())) { - // Update local cache and notify listeners. - if (network.type() == TYPE_WIFI) { - WifiNetwork* wifi = GetWirelessNetworkByPath( - wifi_networks_, network.service_path()); - if (wifi) { - wifi->set_connected(false); - wifi_ = WifiNetwork(); - } - } else if (network.type() == TYPE_CELLULAR) { - CellularNetwork* cellular = GetWirelessNetworkByPath( - cellular_networks_, network.service_path()); - if (cellular) { - cellular->set_connected(false); - cellular_ = CellularNetwork(); - } + virtual void DisconnectFromWirelessNetwork(const WirelessNetwork* network) { + DCHECK(network); + if (!EnsureCrosLoaded() || !network) + return; + // TODO(ers) restore default service type priority ordering? + if (DisconnectFromNetwork(network->service_path().c_str())) { + // Update local cache and notify listeners. + if (network->type() == TYPE_WIFI) { + WifiNetwork* wifi = GetWirelessNetworkByPath( + wifi_networks_, network->service_path()); + if (wifi) { + wifi->set_connected(false); + wifi_ = NULL; + } + } else if (network->type() == TYPE_CELLULAR) { + CellularNetwork* cellular = GetWirelessNetworkByPath( + cellular_networks_, network->service_path()); + if (cellular) { + cellular->set_connected(false); + cellular_ = NULL; } - NotifyNetworkChanged(); } + NotifyNetworkManagerChanged(); } } - virtual void SaveCellularNetwork(const CellularNetwork& network) { - // Update the wifi network in the local cache. - CellularNetwork* cellular = GetWirelessNetworkByPath( - cellular_networks_, network.service_path()); - if (cellular) - *cellular = network; - + virtual void SaveCellularNetwork(const CellularNetwork* network) { + DCHECK(network); // Update the cellular network with libcros. - if (EnsureCrosLoaded()) { - SetAutoConnect(network.service_path().c_str(), network.auto_connect()); - } - } + if (!EnsureCrosLoaded() || !network) + return; - virtual void SaveWifiNetwork(const WifiNetwork& network) { - // Update the wifi network in the local cache. - WifiNetwork* wifi = GetWirelessNetworkByPath( - wifi_networks_, network.service_path()); - if (wifi) - *wifi = network; + SetAutoConnect(network->service_path().c_str(), network->auto_connect()); + } + virtual void SaveWifiNetwork(const WifiNetwork* network) { + DCHECK(network); // Update the wifi network with libcros. - if (EnsureCrosLoaded()) { - SetPassphrase( - network.service_path().c_str(), network.passphrase().c_str()); - SetIdentity(network.service_path().c_str(), network.identity().c_str()); - SetCertPath(network.service_path().c_str(), network.cert_path().c_str()); - SetAutoConnect(network.service_path().c_str(), network.auto_connect()); - } + if (!EnsureCrosLoaded() || !network) + return; + SetPassphrase( + network->service_path().c_str(), network->passphrase().c_str()); + SetIdentity(network->service_path().c_str(), + network->identity().c_str()); + SetCertPath(network->service_path().c_str(), + network->cert_path().c_str()); + SetAutoConnect(network->service_path().c_str(), network->auto_connect()); } - virtual void ForgetWirelessNetwork(const std::string& service_path) { - if (EnsureCrosLoaded()) { - if (DeleteRememberedService(service_path.c_str())) { - // Update local cache and notify listeners. - remembered_wifi_networks_.erase( - std::remove_if(remembered_wifi_networks_.begin(), - remembered_wifi_networks_.end(), - WirelessNetwork::ServicePathEq(service_path)), - remembered_wifi_networks_.end()); - remembered_cellular_networks_.erase( - std::remove_if(remembered_cellular_networks_.begin(), - remembered_cellular_networks_.end(), - WirelessNetwork::ServicePathEq(service_path)), - remembered_cellular_networks_.end()); - NotifyNetworkChanged(); + virtual void ForgetWifiNetwork(const std::string& service_path) { + if (!EnsureCrosLoaded()) + return; + if (DeleteRememberedService(service_path.c_str())) { + // Update local cache and notify listeners. + for (WifiNetworkVector::iterator iter = + remembered_wifi_networks_.begin(); + iter != remembered_wifi_networks_.end(); + ++iter) { + if ((*iter)->service_path() == service_path) { + delete (*iter); + remembered_wifi_networks_.erase(iter); + break; + } } + NotifyNetworkManagerChanged(); } } @@ -758,6 +1041,16 @@ class NetworkLibraryImpl : public NetworkLibrary { virtual bool offline_mode() const { return offline_mode_; } + virtual const Network* active_network() const { + if (ethernet_ && ethernet_->is_active()) + return ethernet_; + if (wifi_ && wifi_->is_active()) + return wifi_; + if (cellular_ && cellular_->is_active()) + return cellular_; + return NULL; + } + virtual void EnableEthernetNetworkDevice(bool enable) { EnableNetworkDeviceType(TYPE_ETHERNET, enable); } @@ -776,12 +1069,11 @@ class NetworkLibraryImpl : public NetworkLibrary { // If network device is already enabled/disabled, then don't do anything. if (enable && offline_mode_) { - LOG(INFO) << "Trying to enable offline mode when it's already enabled. "; + VLOG(1) << "Trying to enable offline mode when it's already enabled."; return; } if (!enable && !offline_mode_) { - LOG(INFO) << - "Trying to disable offline mode when it's already disabled. "; + VLOG(1) << "Trying to disable offline mode when it's already disabled."; return; } @@ -828,42 +1120,33 @@ class NetworkLibraryImpl : public NetworkLibrary { } output.append("<h3>Ethernet:</h3><table border=1>"); - if (ethernet_enabled()) { - output.append("<tr>" + ToHtmlTableHeader(ðernet_) + "</tr>"); - output.append("<tr>" + ToHtmlTableRow(ðernet_) + "</tr>"); + if (ethernet_ && ethernet_enabled()) { + output.append("<tr>" + ToHtmlTableHeader(ethernet_) + "</tr>"); + output.append("<tr>" + ToHtmlTableRow(ethernet_) + "</tr>"); } output.append("</table><h3>Wifi:</h3><table border=1>"); for (size_t i = 0; i < wifi_networks_.size(); ++i) { if (i == 0) - output.append("<tr>" + ToHtmlTableHeader(&wifi_networks_[i]) + "</tr>"); - output.append("<tr>" + ToHtmlTableRow(&wifi_networks_[i]) + "</tr>"); + output.append("<tr>" + ToHtmlTableHeader(wifi_networks_[i]) + "</tr>"); + output.append("<tr>" + ToHtmlTableRow(wifi_networks_[i]) + "</tr>"); } output.append("</table><h3>Cellular:</h3><table border=1>"); for (size_t i = 0; i < cellular_networks_.size(); ++i) { if (i == 0) - output.append("<tr>" + ToHtmlTableHeader(&cellular_networks_[i]) + + output.append("<tr>" + ToHtmlTableHeader(cellular_networks_[i]) + "</tr>"); - output.append("<tr>" + ToHtmlTableRow(&cellular_networks_[i]) + "</tr>"); + output.append("<tr>" + ToHtmlTableRow(cellular_networks_[i]) + "</tr>"); } output.append("</table><h3>Remembered Wifi:</h3><table border=1>"); for (size_t i = 0; i < remembered_wifi_networks_.size(); ++i) { if (i == 0) output.append( - "<tr>" + ToHtmlTableHeader(&remembered_wifi_networks_[i]) + + "<tr>" + ToHtmlTableHeader(remembered_wifi_networks_[i]) + "</tr>"); - output.append("<tr>" + ToHtmlTableRow(&remembered_wifi_networks_[i]) + - "</tr>"); - } - - output.append("</table><h3>Remembered Cellular:</h3><table border=1>"); - for (size_t i = 0; i < remembered_cellular_networks_.size(); ++i) { - if (i == 0) - output.append("<tr>" + - ToHtmlTableHeader(&remembered_cellular_networks_[i]) + "</tr>"); - output.append("<tr>" + ToHtmlTableRow(&remembered_cellular_networks_[i]) + + output.append("<tr>" + ToHtmlTableRow(remembered_wifi_networks_[i]) + "</tr>"); } @@ -872,157 +1155,175 @@ class NetworkLibraryImpl : public NetworkLibrary { } private: - static void NetworkStatusChangedHandler(void* object) { - NetworkLibraryImpl* network = static_cast<NetworkLibraryImpl*>(object); - DCHECK(network); - network->UpdateNetworkStatus(); + + class NetworkObserverList : public ObserverList<NetworkObserver> { + public: + NetworkObserverList(NetworkLibraryImpl* library, + const std::string& service_path) { + network_monitor_ = MonitorNetworkService(&NetworkStatusChangedHandler, + service_path.c_str(), + library); + } + + virtual ~NetworkObserverList() { + if (network_monitor_) + DisconnectPropertyChangeMonitor(network_monitor_); + } + + private: + static void NetworkStatusChangedHandler(void* object, + const char* path, + const char* key, + const Value* value) { + NetworkLibraryImpl* networklib = static_cast<NetworkLibraryImpl*>(object); + DCHECK(networklib); + networklib->UpdateNetworkStatus(path, key, value); + } + PropertyChangeMonitor network_monitor_; + }; + + typedef std::map<std::string, NetworkObserverList*> NetworkObserverMap; + + static void NetworkManagerStatusChangedHandler(void* object, + const char* path, + const char* key, + const Value* value) { + NetworkLibraryImpl* networklib = static_cast<NetworkLibraryImpl*>(object); + DCHECK(networklib); + networklib->NetworkStatusChanged(); } static void DataPlanUpdateHandler(void* object, const char* modem_service_path, const CellularDataPlanList* dataplan) { - NetworkLibraryImpl* network = static_cast<NetworkLibraryImpl*>(object); - DCHECK(network); + NetworkLibraryImpl* networklib = static_cast<NetworkLibraryImpl*>(object); + if (!networklib || !networklib->cellular_network()) { + // This might happen if an update is received as we are shutting down. + return; + } // Store data plan for currently connected cellular network. - if (network->cellular_network().service_path() + if (networklib->cellular_network()->service_path() .compare(modem_service_path) == 0) { if (dataplan != NULL) { - network->UpdateCellularDataPlan(*dataplan); + networklib->UpdateCellularDataPlan(dataplan); } } } static void ParseSystem(SystemInfo* system, - EthernetNetwork* ethernet, + EthernetNetwork** ethernet, WifiNetworkVector* wifi_networks, CellularNetworkVector* cellular_networks, - WifiNetworkVector* remembered_wifi_networks, - CellularNetworkVector* remembered_cellular_networks) { - DLOG(INFO) << "ParseSystem:"; - ethernet->Clear(); + WifiNetworkVector* remembered_wifi_networks) { + DVLOG(1) << "ParseSystem:"; + DCHECK(!(*ethernet)); for (int i = 0; i < system->service_size; i++) { - const ServiceInfo service = *system->GetServiceInfo(i); - DLOG(INFO) << " (" << service.type << - ") " << service.name << - " mode=" << service.mode << - " state=" << service.state << - " sec=" << service.security << - " req=" << service.passphrase_required << - " pass=" << service.passphrase << - " id=" << service.identity << - " certpath=" << service.cert_path << - " str=" << service.strength << - " fav=" << service.favorite << - " auto=" << service.auto_connect << - " error=" << service.error; + const ServiceInfo* service = system->GetServiceInfo(i); + DVLOG(1) << " (" << service->type << ") " << service->name + << " mode=" << service->mode + << " state=" << service->state + << " sec=" << service->security + << " req=" << service->passphrase_required + << " pass=" << service->passphrase + << " id=" << service->identity + << " certpath=" << service->cert_path + << " str=" << service->strength + << " fav=" << service->favorite + << " auto=" << service->auto_connect + << " is_active=" << service->is_active + << " error=" << service->error; // Once a connected ethernet service is found, disregard other ethernet // services that are also found - if (service.type == TYPE_ETHERNET && !(ethernet->connected())) - ethernet->ConfigureFromService(service); - else if (service.type == TYPE_WIFI) - wifi_networks->push_back(WifiNetwork(service)); - else if (service.type == TYPE_CELLULAR) - cellular_networks->push_back(CellularNetwork(service)); + if (service->type == TYPE_ETHERNET) + (*ethernet) = new EthernetNetwork(service); + else if (service->type == TYPE_WIFI) { + wifi_networks->push_back(new WifiNetwork(service)); + } else if (service->type == TYPE_CELLULAR) { + cellular_networks->push_back(new CellularNetwork(service)); + } } - DLOG(INFO) << "Remembered networks:"; + + // Create placeholder network for ethernet even if the service is not + // detected at this moment. + if (!(*ethernet)) + (*ethernet) = new EthernetNetwork(); + + DVLOG(1) << "Remembered networks:"; for (int i = 0; i < system->remembered_service_size; i++) { - const ServiceInfo& service = *system->GetRememberedServiceInfo(i); - // Only serices marked as auto_connect are considered remembered networks. + const ServiceInfo* service = system->GetRememberedServiceInfo(i); + // Only services marked as auto_connect are considered remembered + // networks. // TODO(chocobo): Don't add to remembered service if currently available. - if (service.auto_connect) { - DLOG(INFO) << " (" << service.type << - ") " << service.name << - " mode=" << service.mode << - " sec=" << service.security << - " pass=" << service.passphrase << - " id=" << service.identity << - " certpath=" << service.cert_path << - " auto=" << service.auto_connect; - if (service.type == TYPE_WIFI) - remembered_wifi_networks->push_back(WifiNetwork(service)); - else if (service.type == TYPE_CELLULAR) - remembered_cellular_networks->push_back(CellularNetwork(service)); + if (service->auto_connect) { + DVLOG(1) << " (" << service->type << ") " << service->name + << " mode=" << service->mode + << " sec=" << service->security + << " pass=" << service->passphrase + << " id=" << service->identity + << " certpath=" << service->cert_path + << " auto=" << service->auto_connect; + if (service->type == TYPE_WIFI) { + remembered_wifi_networks->push_back(new WifiNetwork(service)); + } } } } void Init() { - // First, get the currently available networks. This data is cached + // First, get the currently available networks. This data is cached // on the connman side, so the call should be quick. - LOG(INFO) << "Getting initial CrOS network info."; + VLOG(1) << "Getting initial CrOS network info."; UpdateSystemInfo(); - - LOG(INFO) << "Registering for network status updates."; - // Now, register to receive updates on network status. - network_status_connection_ = MonitorNetwork(&NetworkStatusChangedHandler, - this); - LOG(INFO) << "Registering for cellular data plan updates."; - data_plan_monitor_ = MonitorCellularDataPlan(&DataPlanUpdateHandler, this); } void InitTestData() { - ethernet_.Clear(); - ethernet_.set_connected(true); - ethernet_.set_service_path("eth1"); + ethernet_ = new EthernetNetwork(); + ethernet_->set_connected(true); + ethernet_->set_service_path("eth1"); + STLDeleteElements(&wifi_networks_); wifi_networks_.clear(); - WifiNetwork wifi1 = WifiNetwork(); - wifi1.set_service_path("fw1"); - wifi1.set_name("Fake Wifi 1"); - wifi1.set_strength(90); - wifi1.set_connected(false); - wifi1.set_encryption(SECURITY_NONE); + WifiNetwork* wifi1 = new WifiNetwork(); + wifi1->set_service_path("fw1"); + wifi1->set_name("Fake Wifi 1"); + wifi1->set_strength(90); + wifi1->set_connected(false); + wifi1->set_encryption(SECURITY_NONE); wifi_networks_.push_back(wifi1); - WifiNetwork wifi2 = WifiNetwork(); - wifi2.set_service_path("fw2"); - wifi2.set_name("Fake Wifi 2"); - wifi2.set_strength(70); - wifi2.set_connected(true); - wifi2.set_encryption(SECURITY_WEP); + WifiNetwork* wifi2 = new WifiNetwork(); + wifi2->set_service_path("fw2"); + wifi2->set_name("Fake Wifi 2"); + wifi2->set_strength(70); + wifi2->set_connected(true); + wifi2->set_encryption(SECURITY_WEP); wifi_networks_.push_back(wifi2); - WifiNetwork wifi3 = WifiNetwork(); - wifi3.set_service_path("fw3"); - wifi3.set_name("Fake Wifi 3"); - wifi3.set_strength(50); - wifi3.set_connected(false); - wifi3.set_encryption(SECURITY_WEP); + WifiNetwork* wifi3 = new WifiNetwork(); + wifi3->set_service_path("fw3"); + wifi3->set_name("Fake Wifi 3"); + wifi3->set_strength(50); + wifi3->set_connected(false); + wifi3->set_encryption(SECURITY_WEP); wifi_networks_.push_back(wifi3); wifi_ = wifi2; + STLDeleteElements(&cellular_networks_); cellular_networks_.clear(); - cellular_networks_.clear(); - CellularNetwork cellular1 = CellularNetwork(); - cellular1.set_service_path("fc1"); - cellular1.set_name("Fake Cellular 1"); - cellular1.set_strength(90); - cellular1.set_connected(false); + CellularNetwork* cellular1 = new CellularNetwork(); + cellular1->set_service_path("fc1"); + cellular1->set_name("Fake Cellular 1"); + cellular1->set_strength(70); + cellular1->set_connected(true); + cellular1->set_activation_state(ACTIVATION_STATE_PARTIALLY_ACTIVATED); + cellular1->set_payment_url(std::string("http://www.google.com")); cellular_networks_.push_back(cellular1); - - CellularNetwork cellular2 = CellularNetwork(); - cellular2.set_service_path("fc2"); - cellular2.set_name("Fake Cellular 2"); - cellular2.set_strength(70); - cellular2.set_connected(true); - cellular_networks_.push_back(cellular2); - - CellularNetwork cellular3 = CellularNetwork(); - cellular3.set_service_path("fc3"); - cellular3.set_name("Fake Cellular 3"); - cellular3.set_strength(50); - cellular3.set_connected(false); - cellular_networks_.push_back(cellular3); - - cellular_ = cellular2; + cellular_ = cellular1; remembered_wifi_networks_.clear(); - remembered_wifi_networks_.push_back(wifi2); - - remembered_cellular_networks_.clear(); - remembered_cellular_networks_.push_back(cellular2); + remembered_wifi_networks_.push_back(new WifiNetwork(*wifi2)); int devices = (1 << TYPE_ETHERNET) | (1 << TYPE_WIFI) | (1 << TYPE_CELLULAR); @@ -1030,55 +1331,38 @@ class NetworkLibraryImpl : public NetworkLibrary { enabled_devices_ = devices; connected_devices_ = devices; offline_mode_ = false; - - chromeos::CellularDataPlan test_plan; - test_plan.plan_name = "Fake plan"; - test_plan.data_bytes_used = 5LL * 1024LL * 1024LL * 1024LL; - test_plan.plan_start_time = - (base::Time::Now() - base::TimeDelta::FromDays(15)).ToInternalValue() / - base::Time::kMicrosecondsPerSecond; - test_plan.plan_end_time = - (base::Time::Now() + base::TimeDelta::FromDays(12)).ToInternalValue() / - base::Time::kMicrosecondsPerSecond; - test_plan.plan_data_bytes = 20LL * 1024LL * 1024LL * 1024LL; - test_plan.plan_type = CELLULAR_DATA_PLAN_METERED_PAID; - test_plan.update_time = base::Time::Now().ToInternalValue() / - base::Time::kMicrosecondsPerSecond; - chromeos::CellularDataPlanList test_plans; - test_plans.push_back(test_plan); - cellular_.SetDataPlans(test_plans); } void UpdateSystemInfo() { if (EnsureCrosLoaded()) { - UpdateNetworkStatus(); + UpdateNetworkManagerStatus(); } } WifiNetwork* GetWifiNetworkByName(const std::string& name) { for (size_t i = 0; i < wifi_networks_.size(); ++i) { - if (wifi_networks_[i].name().compare(name) == 0) { - return &wifi_networks_[i]; + if (wifi_networks_[i]->name().compare(name) == 0) { + return wifi_networks_[i]; } } return NULL; } - template<typename T> T* GetWirelessNetworkByPath( + template<typename T> T GetWirelessNetworkByPath( std::vector<T>& networks, const std::string& path) { typedef typename std::vector<T>::iterator iter_t; iter_t iter = std::find_if(networks.begin(), networks.end(), WirelessNetwork::ServicePathEq(path)); - return (iter != networks.end()) ? &(*iter) : NULL; + return (iter != networks.end()) ? *iter : NULL; } // const version - template<typename T> const T* GetWirelessNetworkByPath( + template<typename T> const T GetWirelessNetworkByPath( const std::vector<T>& networks, const std::string& path) const { typedef typename std::vector<T>::const_iterator iter_t; iter_t iter = std::find_if(networks.begin(), networks.end(), WirelessNetwork::ServicePathEq(path)); - return (iter != networks.end()) ? &(*iter) : NULL; + return (iter != networks.end()) ? *iter : NULL; } void EnableNetworkDeviceType(ConnectionType device, bool enable) { @@ -1100,53 +1384,68 @@ class NetworkLibraryImpl : public NetworkLibrary { EnableNetworkDevice(device, enable); } - void NotifyNetworkChanged() { - FOR_EACH_OBSERVER(Observer, observers_, NetworkChanged(this)); + void NotifyNetworkManagerChanged() { + FOR_EACH_OBSERVER(NetworkManagerObserver, + network_manager_observers_, + OnNetworkManagerChanged(this)); + } + + void NotifyNetworkChanged(Network* network) { + DCHECK(network); + NetworkObserverMap::const_iterator iter = network_observers_.find( + network->service_path()); + if (iter != network_observers_.end()) { + FOR_EACH_OBSERVER(NetworkObserver, + *(iter->second), + OnNetworkChanged(this, network)); + } else { + NOTREACHED() << + "There weren't supposed to be any property change observers of " << + network->service_path(); + } } void NotifyCellularDataPlanChanged() { - FOR_EACH_OBSERVER(Observer, observers_, CellularDataPlanChanged(this)); + FOR_EACH_OBSERVER(CellularDataPlanObserver, + data_plan_observers_, + OnCellularDataPlanChanged(this)); } - void UpdateNetworkStatus() { + void UpdateNetworkManagerStatus() { // Make sure we run on UI thread. - if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - NewRunnableMethod(this, - &NetworkLibraryImpl::UpdateNetworkStatus)); - return; - } + CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + + update_task_ = NULL; + VLOG(1) << "Updating Network Status"; SystemInfo* system = GetSystemInfo(); if (!system) return; - wifi_networks_.clear(); - cellular_networks_.clear(); - remembered_wifi_networks_.clear(); - remembered_cellular_networks_.clear(); + std::string prev_cellular_service_path = cellular_ ? + cellular_->service_path() : std::string(); + + ClearNetworks(); + ParseSystem(system, ðernet_, &wifi_networks_, &cellular_networks_, - &remembered_wifi_networks_, &remembered_cellular_networks_); + &remembered_wifi_networks_); - wifi_ = WifiNetwork(); + wifi_ = NULL; for (size_t i = 0; i < wifi_networks_.size(); i++) { - if (wifi_networks_[i].connecting_or_connected()) { + if (wifi_networks_[i]->connecting_or_connected()) { wifi_ = wifi_networks_[i]; break; // There is only one connected or connecting wifi network. } } - std::string prev_service_path = cellular_.service_path(); - cellular_ = CellularNetwork(); + cellular_ = NULL; for (size_t i = 0; i < cellular_networks_.size(); i++) { - if (cellular_networks_[i].connecting_or_connected()) { - // If new cellular, then update data plan list. - if (cellular_networks_[i].service_path() != prev_service_path) { - CellularDataPlanList list; - RetrieveCellularDataPlans(cellular_.service_path().c_str(), &list); - UpdateCellularDataPlan(list); - } + if (cellular_networks_[i]->connecting_or_connected()) { cellular_ = cellular_networks_[i]; + // If new cellular, then request update of the data plan list. + if (cellular_networks_[i]->service_path() != + prev_cellular_service_path) { + RefreshCellularDataPlans(cellular_); + } break; // There is only one connected or connecting cellular network. } } @@ -1156,31 +1455,122 @@ class NetworkLibraryImpl : public NetworkLibrary { connected_devices_ = system->connected_technologies; offline_mode_ = system->offline_mode; - NotifyNetworkChanged(); + NotifyNetworkManagerChanged(); FreeSystemInfo(system); } - void UpdateCellularDataPlan(const CellularDataPlanList& data_plans) { - cellular_.SetDataPlans(data_plans); + void UpdateNetworkStatus(const char* path, + const char* key, + const Value* value) { + if (key == NULL || value == NULL) + return; + // Make sure we run on UI thread. + if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + NewRunnableMethod(this, + &NetworkLibraryImpl::UpdateNetworkStatus, + path, key, value)); + return; + } + + bool boolval = false; + int intval = 0; + std::string stringval; + Network* network; + if (ethernet_->service_path() == path) { + network = ethernet_; + } else { + CellularNetwork* cellular = + GetWirelessNetworkByPath(cellular_networks_, path); + WifiNetwork* wifi = + GetWirelessNetworkByPath(wifi_networks_, path); + if (cellular == NULL && wifi == NULL) + return; + + WirelessNetwork* wireless; + if (wifi != NULL) + wireless = static_cast<WirelessNetwork*>(wifi); + else + wireless = static_cast<WirelessNetwork*>(cellular); + + if (strcmp(key, kSignalStrengthProperty) == 0) { + if (value->GetAsInteger(&intval)) + wireless->set_strength(intval); + } else if (cellular != NULL) { + if (strcmp(key, kRestrictedPoolProperty) == 0) { + if (value->GetAsBoolean(&boolval)) + cellular->set_restricted_pool(boolval); + } else if (strcmp(key, kActivationStateProperty) == 0) { + if (value->GetAsString(&stringval)) + cellular->set_activation_state(ParseActivationState(stringval)); + } else if (strcmp(key, kPaymentURLProperty) == 0) { + if (value->GetAsString(&stringval)) + cellular->set_payment_url(stringval); + } else if (strcmp(key, kNetworkTechnologyProperty) == 0) { + if (value->GetAsString(&stringval)) + cellular->set_network_technology( + ParseNetworkTechnology(stringval)); + } else if (strcmp(key, kRoamingStateProperty) == 0) { + if (value->GetAsString(&stringval)) + cellular->set_roaming_state(ParseRoamingState(stringval)); + } + } + network = wireless; + } + if (strcmp(key, kIsActiveProperty) == 0) { + if (value->GetAsBoolean(&boolval)) + network->set_active(boolval); + } else if (strcmp(key, kStateProperty) == 0) { + if (value->GetAsString(&stringval)) + network->set_state(ParseState(stringval)); + } + NotifyNetworkChanged(network); + } + + void UpdateCellularDataPlan(const CellularDataPlanList* data_plans) { + DCHECK(cellular_); + cellular_->SetDataPlans(data_plans); NotifyCellularDataPlanChanged(); } - ObserverList<Observer> observers_; + void ClearNetworks() { + if (ethernet_) + delete ethernet_; + ethernet_ = NULL; + wifi_ = NULL; + cellular_ = NULL; + STLDeleteElements(&wifi_networks_); + wifi_networks_.clear(); + STLDeleteElements(&cellular_networks_); + cellular_networks_.clear(); + STLDeleteElements(&remembered_wifi_networks_); + remembered_wifi_networks_.clear(); + } + + // Network manager observer list + ObserverList<NetworkManagerObserver> network_manager_observers_; + + // Cellular data plan observer list + ObserverList<CellularDataPlanObserver> data_plan_observers_; - // The network status connection for monitoring network status changes. - MonitorNetworkConnection network_status_connection_; + // Network observer map + NetworkObserverMap network_observers_; + + // For monitoring network manager status changes. + PropertyChangeMonitor network_manager_monitor_; // For monitoring data plan changes to the connected cellular network. DataPlanUpdateMonitor data_plan_monitor_; // The ethernet network. - EthernetNetwork ethernet_; + EthernetNetwork* ethernet_; // The list of available wifi networks. WifiNetworkVector wifi_networks_; // The current connected (or connecting) wifi network. - WifiNetwork wifi_; + WifiNetwork* wifi_; // The remembered wifi networks. WifiNetworkVector remembered_wifi_networks_; @@ -1189,10 +1579,7 @@ class NetworkLibraryImpl : public NetworkLibrary { CellularNetworkVector cellular_networks_; // The current connected (or connecting) cellular network. - CellularNetwork cellular_; - - // The remembered cellular networks. - CellularNetworkVector remembered_cellular_networks_; + CellularNetwork* cellular_; // The current available network devices. Bitwise flag of ConnectionTypes. int available_devices_; @@ -1205,26 +1592,43 @@ class NetworkLibraryImpl : public NetworkLibrary { bool offline_mode_; + // Delayed task to retrieve the network information. + CancelableTask* update_task_; + DISALLOW_COPY_AND_ASSIGN(NetworkLibraryImpl); }; class NetworkLibraryStubImpl : public NetworkLibrary { public: - NetworkLibraryStubImpl() : ip_address_("1.1.1.1") {} - ~NetworkLibraryStubImpl() {} - void AddObserver(Observer* observer) {} - void RemoveObserver(Observer* observer) {} - virtual const EthernetNetwork& ethernet_network() const { + NetworkLibraryStubImpl() + : ip_address_("1.1.1.1"), + ethernet_(new EthernetNetwork()), + wifi_(NULL), + cellular_(NULL) { + } + ~NetworkLibraryStubImpl() { if (ethernet_) delete ethernet_; } + virtual void AddNetworkManagerObserver(NetworkManagerObserver* observer) {} + virtual void RemoveNetworkManagerObserver(NetworkManagerObserver* observer) {} + virtual void AddNetworkObserver(const std::string& service_path, + NetworkObserver* observer) {} + virtual void RemoveNetworkObserver(const std::string& service_path, + NetworkObserver* observer) {} + virtual void RemoveObserverForAllNetworks(NetworkObserver* observer) {} + virtual void AddCellularDataPlanObserver( + CellularDataPlanObserver* observer) {} + virtual void RemoveCellularDataPlanObserver( + CellularDataPlanObserver* observer) {} + virtual EthernetNetwork* ethernet_network() { return ethernet_; } virtual bool ethernet_connecting() const { return false; } virtual bool ethernet_connected() const { return true; } - virtual const WifiNetwork& wifi_network() const { + virtual WifiNetwork* wifi_network() { return wifi_; } virtual bool wifi_connecting() const { return false; } virtual bool wifi_connected() const { return false; } - virtual const CellularNetwork& cellular_network() const { + virtual CellularNetwork* cellular_network() { return cellular_; } virtual bool cellular_connecting() const { return false; } @@ -1242,42 +1646,49 @@ class NetworkLibraryStubImpl : public NetworkLibrary { virtual const CellularNetworkVector& cellular_networks() const { return cellular_networks_; } - virtual const CellularNetworkVector& remembered_cellular_networks() const { - return cellular_networks_; + virtual bool has_cellular_networks() const { + return cellular_networks_.begin() != cellular_networks_.end(); } - ///////////////////////////////////////////////////////////////////////////// - virtual bool FindWifiNetworkByPath( - const std::string& path, WifiNetwork* result) const { return false; } - virtual bool FindCellularNetworkByPath( - const std::string& path, CellularNetwork* result) const { return false; } + virtual WifiNetwork* FindWifiNetworkByPath( + const std::string& path) { return NULL; } + virtual CellularNetwork* FindCellularNetworkByPath( + const std::string& path) { return NULL; } virtual void RequestWifiScan() {} virtual bool GetWifiAccessPoints(WifiAccessPointVector* result) { return false; } - virtual void ConnectToWifiNetwork(WifiNetwork network, + virtual bool ConnectToWifiNetwork(const WifiNetwork* network, const std::string& password, const std::string& identity, - const std::string& certpath) {} - virtual void ConnectToWifiNetwork(const std::string& ssid, + const std::string& certpath) { + return true; + } + virtual bool ConnectToWifiNetwork(ConnectionSecurity security, + 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 RefreshCellularDataPlans(const CellularNetwork& network) {} - virtual void DisconnectFromWirelessNetwork(const WirelessNetwork& network) {} - virtual void SaveCellularNetwork(const CellularNetwork& network) {} - virtual void SaveWifiNetwork(const WifiNetwork& network) {} - virtual void ForgetWirelessNetwork(const std::string& service_path) {} + bool auto_connect) { + return true; + } + virtual bool ConnectToCellularNetwork(const CellularNetwork* network) { + return true; + } + virtual void RefreshCellularDataPlans(const CellularNetwork* network) {} + virtual void DisconnectFromWirelessNetwork(const WirelessNetwork* network) {} + virtual void SaveCellularNetwork(const CellularNetwork* network) {} + virtual void SaveWifiNetwork(const WifiNetwork* network) {} + virtual void ForgetWifiNetwork(const std::string& service_path) {} virtual bool ethernet_available() const { return true; } virtual bool wifi_available() const { return false; } virtual bool cellular_available() const { return false; } virtual bool ethernet_enabled() const { return true; } virtual bool wifi_enabled() const { return false; } virtual bool cellular_enabled() const { return false; } + virtual const Network* active_network() const { return NULL; } virtual bool offline_mode() const { return false; } virtual void EnableEthernetNetworkDevice(bool enable) {} virtual void EnableWifiNetworkDevice(bool enable) {} @@ -1289,13 +1700,12 @@ class NetworkLibraryStubImpl : public NetworkLibrary { return NetworkIPConfigVector(); } virtual std::string GetHtmlInfo(int refresh) { return std::string(); } - virtual void UpdateSystemInfo() {} private: std::string ip_address_; - EthernetNetwork ethernet_; - WifiNetwork wifi_; - CellularNetwork cellular_; + EthernetNetwork* ethernet_; + WifiNetwork* wifi_; + CellularNetwork* cellular_; WifiNetworkVector wifi_networks_; CellularNetworkVector cellular_networks_; }; |
