OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include <string> |
| 6 |
| 7 #include "base/basictypes.h" |
| 8 #include "base/bind.h" |
| 9 #include "chromeos/network/network_change_notifier_chromeos.h" |
| 10 #include "chromeos/network/network_state.h" |
| 11 #include "chromeos/network/network_state_handler.h" |
| 12 #include "net/base/network_change_notifier.h" |
| 13 #include "net/dns/dns_config_service_posix.h" |
| 14 #include "third_party/cros_system_api/dbus/service_constants.h" |
| 15 |
| 16 namespace chromeos { |
| 17 |
| 18 // DNS config services on Chrome OS are signalled by the network state handler |
| 19 // rather than relying on watching files in /etc. |
| 20 class NetworkChangeNotifierChromeos::DnsConfigService |
| 21 : public net::internal::DnsConfigServicePosix { |
| 22 public: |
| 23 DnsConfigService(); |
| 24 virtual ~DnsConfigService(); |
| 25 |
| 26 // net::internal::DnsConfigService() overrides. |
| 27 virtual bool StartWatching() OVERRIDE; |
| 28 |
| 29 virtual void OnNetworkChange(); |
| 30 }; |
| 31 |
| 32 NetworkChangeNotifierChromeos::DnsConfigService::DnsConfigService() {} |
| 33 |
| 34 NetworkChangeNotifierChromeos::DnsConfigService::~DnsConfigService() {} |
| 35 |
| 36 bool NetworkChangeNotifierChromeos::DnsConfigService::StartWatching() { |
| 37 // DNS config changes are handled and notified by the network state handlers. |
| 38 return true; |
| 39 } |
| 40 |
| 41 void NetworkChangeNotifierChromeos::DnsConfigService::OnNetworkChange() { |
| 42 InvalidateConfig(); |
| 43 InvalidateHosts(); |
| 44 ReadNow(); |
| 45 } |
| 46 |
| 47 NetworkChangeNotifierChromeos::NetworkChangeNotifierChromeos() |
| 48 : NetworkChangeNotifier(NetworkChangeCalculatorParamsChromeos()), |
| 49 connection_type_(CONNECTION_NONE) { |
| 50 } |
| 51 |
| 52 NetworkChangeNotifierChromeos::~NetworkChangeNotifierChromeos() { |
| 53 } |
| 54 |
| 55 void NetworkChangeNotifierChromeos::Initialize() { |
| 56 NetworkStateHandler::Get()->AddObserver(this); |
| 57 |
| 58 dns_config_service_.reset(new DnsConfigService()); |
| 59 dns_config_service_->WatchConfig( |
| 60 base::Bind(net::NetworkChangeNotifier::SetDnsConfig)); |
| 61 |
| 62 // Update initial connection state. |
| 63 ActiveNetworkChanged(NetworkStateHandler::Get()->ActiveNetwork()); |
| 64 } |
| 65 |
| 66 void NetworkChangeNotifierChromeos::Shutdown() { |
| 67 dns_config_service_.reset(); |
| 68 if (NetworkStateHandler::Get()) |
| 69 NetworkStateHandler::Get()->RemoveObserver(this); |
| 70 } |
| 71 |
| 72 net::NetworkChangeNotifier::ConnectionType |
| 73 NetworkChangeNotifierChromeos::GetCurrentConnectionType() const { |
| 74 return connection_type_; |
| 75 } |
| 76 |
| 77 void NetworkChangeNotifierChromeos::ActiveNetworkChanged( |
| 78 const chromeos::NetworkState* active_network) { |
| 79 bool connection_type_changed = false; |
| 80 bool ip_address_changed = false; |
| 81 bool dns_changed = false; |
| 82 |
| 83 UpdateState(active_network, &connection_type_changed, |
| 84 &ip_address_changed, &dns_changed); |
| 85 |
| 86 if (connection_type_changed) |
| 87 NetworkChangeNotifierChromeos:: NotifyObserversOfConnectionTypeChange(); |
| 88 if (ip_address_changed) |
| 89 NetworkChangeNotifierChromeos::NotifyObserversOfIPAddressChange(); |
| 90 if (dns_changed) |
| 91 dns_config_service_->OnNetworkChange(); |
| 92 } |
| 93 |
| 94 void NetworkChangeNotifierChromeos::ActiveNetworkStateChanged( |
| 95 const chromeos::NetworkState* active_network) { |
| 96 ActiveNetworkChanged(active_network); |
| 97 } |
| 98 |
| 99 void NetworkChangeNotifierChromeos::UpdateState( |
| 100 const chromeos::NetworkState* active_network, |
| 101 bool* connection_type_changed, |
| 102 bool* ip_address_changed, |
| 103 bool* dns_changed) { |
| 104 *connection_type_changed = false; |
| 105 *ip_address_changed = false; |
| 106 *dns_changed = false; |
| 107 // TODO(gauravsh): DNS changes will be detected once ip config |
| 108 // support is hooked into NetworkStateHandler. For now, |
| 109 // we report a DNS change on changes to the active network (including |
| 110 // loss). |
| 111 if (!active_network || !active_network->IsConnectedState()) { |
| 112 // If we lost an active network, we must update our state and notify |
| 113 // observers, otherwise we have nothing do. (Under normal circumstances, |
| 114 // we should never ever get duplicate no active network notifications). |
| 115 if (connection_type_ != CONNECTION_NONE) { |
| 116 *ip_address_changed = true; |
| 117 *dns_changed = true; |
| 118 *connection_type_changed = true; |
| 119 connection_type_ = CONNECTION_NONE; |
| 120 service_path_.clear(); |
| 121 ip_address_.clear(); |
| 122 } |
| 123 } else { |
| 124 // We do have an active network and it is connected. |
| 125 net::NetworkChangeNotifier::ConnectionType new_connection_type = |
| 126 ConnectionTypeFromShill(active_network->type(), |
| 127 active_network->technology()); |
| 128 if (new_connection_type != connection_type_) { |
| 129 VLOG(1) << "Connection type changed from " << connection_type_ << " -> " |
| 130 << new_connection_type; |
| 131 *connection_type_changed = true; |
| 132 *dns_changed = true; |
| 133 } |
| 134 if (active_network->path() != service_path_ || |
| 135 active_network->ip_address() != ip_address_) { |
| 136 VLOG(1) << "Service path changed from " << service_path_ << " -> " |
| 137 << active_network->path(); |
| 138 VLOG(1) << "IP Address changed from " << ip_address_ << " -> " |
| 139 << active_network->ip_address(); |
| 140 *ip_address_changed = true; |
| 141 *dns_changed = true; |
| 142 } |
| 143 connection_type_ = new_connection_type; |
| 144 service_path_ = active_network->path(); |
| 145 ip_address_ = active_network->ip_address(); |
| 146 } |
| 147 } |
| 148 |
| 149 // static |
| 150 net::NetworkChangeNotifier::ConnectionType |
| 151 NetworkChangeNotifierChromeos::ConnectionTypeFromShill( |
| 152 const std::string& type, const std::string& technology) { |
| 153 if (type == flimflam::kTypeEthernet) |
| 154 return CONNECTION_ETHERNET; |
| 155 else if (type == flimflam::kTypeWifi) |
| 156 return CONNECTION_WIFI; |
| 157 else if (type == flimflam::kTypeWimax) |
| 158 return CONNECTION_4G; |
| 159 |
| 160 if (type != flimflam::kTypeCellular) |
| 161 return CONNECTION_UNKNOWN; |
| 162 |
| 163 // For cellular types, mapping depends on the technology. |
| 164 if (technology == flimflam::kNetworkTechnologyEvdo || |
| 165 technology == flimflam::kNetworkTechnologyGsm || |
| 166 technology == flimflam::kNetworkTechnologyUmts || |
| 167 technology == flimflam::kNetworkTechnologyHspa) { |
| 168 return CONNECTION_3G; |
| 169 } else if (technology == flimflam::kNetworkTechnologyHspaPlus || |
| 170 technology == flimflam::kNetworkTechnologyLte || |
| 171 technology == flimflam::kNetworkTechnologyLteAdvanced) { |
| 172 return CONNECTION_4G; |
| 173 } else { |
| 174 return CONNECTION_2G; // Default cellular type is 2G. |
| 175 } |
| 176 } |
| 177 |
| 178 // static |
| 179 net::NetworkChangeNotifier::NetworkChangeCalculatorParams |
| 180 NetworkChangeNotifierChromeos::NetworkChangeCalculatorParamsChromeos() { |
| 181 NetworkChangeCalculatorParams params; |
| 182 // Delay values arrived at by simple experimentation and adjusted so as to |
| 183 // produce a single signal when switching between network connections. |
| 184 params.ip_address_offline_delay_ = base::TimeDelta::FromMilliseconds(4000); |
| 185 params.ip_address_online_delay_ = base::TimeDelta::FromMilliseconds(1000); |
| 186 params.connection_type_offline_delay_ = |
| 187 base::TimeDelta::FromMilliseconds(500); |
| 188 params.connection_type_online_delay_ = base::TimeDelta::FromMilliseconds(500); |
| 189 return params; |
| 190 } |
| 191 |
| 192 } // namespace chromeos |
| 193 |
OLD | NEW |