Index: chromeos/network/connection_change_notifier.cc |
diff --git a/chromeos/network/connection_change_notifier.cc b/chromeos/network/connection_change_notifier.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..50497d37d4af9e63967494d84b695b4a9f2af722 |
--- /dev/null |
+++ b/chromeos/network/connection_change_notifier.cc |
@@ -0,0 +1,178 @@ |
+// Copyright (c) 2012 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. |
+ |
+#include <string> |
+ |
+#include "base/basictypes.h" |
+#include "base/bind.h" |
+#include "chromeos/network/connection_change_notifier.h" |
+#include "chromeos/network/network_state.h" |
+#include "chromeos/network/network_state_handler.h" |
+#include "content/public/browser/browser_thread.h" |
+#include "net/base/network_change_notifier.h" |
+#include "third_party/cros_system_api/dbus/service_constants.h" |
+ |
+using content::BrowserThread; |
+ |
+namespace chromeos { |
+ |
+ConnectionChangeNotifier::ConnectionChangeNotifier() |
+ : connection_type_(CONNECTION_NONE) { |
+} |
+ |
+ConnectionChangeNotifier::~ConnectionChangeNotifier() { |
+} |
+ |
+void ConnectionChangeNotifier::Initialize() { |
+ chromeos::NetworkStateHandler::Get()->AddObserver(this); |
+ |
+ dns_config_service_.reset(new DnsConfigServiceChromeos()); |
+ dns_config_service_->WatchConfig( |
+ base::Bind(NetworkChangeNotifier::SetDnsConfig)); |
+ |
+ // Update initial connection state. |
+ ActiveNetworkChanged(chromeos::NetworkStateHandler::Get()->ActiveNetwork()); |
+} |
+ |
+void ConnectionChangeNotifier::Shutdown() { |
+ dns_config_service_.reset(); |
+ if(chromeos::NetworkStateHandler::Get()) |
+ chromeos::NetworkStateHandler::Get()->RemoveObserver(this); |
+} |
+ |
+net::NetworkChangeNotifier::ConnectionType |
+ConnectionChangeNotifier::GetCurrentConnectionType() const { |
+ return connection_type_; |
+} |
+ |
+void ConnectionChangeNotifier::ActiveNetworkChanged( |
+ const chromeos::NetworkState* active_network) { |
+ bool connection_type_changed = false, ip_address_changed = false, |
+ dns_changed = false; |
+ |
+ UpdateActiveNetwork(active_network, &connection_type_changed, |
+ &ip_address_changed, &dns_changed); |
+ |
+ if (connection_type_changed) |
+ ReportConnectionTypeChanged(); |
+ if (ip_address_changed) |
+ ReportIPAddressChanged(); |
+ if (dns_changed) |
+ dns_config_service_->OnNetworkChange(); |
+} |
+ |
+void ConnectionChangeNotifier::ActiveNetworkStateChanged( |
+ const chromeos::NetworkState* active_network) { |
+ ActiveNetworkChanged(active_network); |
+} |
+ |
+ConnectionChangeNotifier::DnsConfigServiceChromeos::DnsConfigServiceChromeos() |
+{} |
+ |
+ConnectionChangeNotifier::DnsConfigServiceChromeos::~DnsConfigServiceChromeos() |
+{} |
+ |
+bool ConnectionChangeNotifier::DnsConfigServiceChromeos::StartWatching() { |
+ // DNS config changes are handled and notified by the network state handlers. |
+ return true; |
+} |
+ |
+void ConnectionChangeNotifier::DnsConfigServiceChromeos::OnNetworkChange() { |
+ InvalidateConfig(); |
+ InvalidateHosts(); |
+ ReadNow(); |
+} |
+ |
+// static |
+net::NetworkChangeNotifier::ConnectionType |
+ConnectionChangeNotifier::ConnectionTypeFromShill( |
+ const std::string& type, const std::string& technology) { |
+ if (type == flimflam::kTypeEthernet) |
+ return CONNECTION_ETHERNET; |
+ else if (type == flimflam::kTypeWifi) |
+ return CONNECTION_WIFI; |
+ else if (type == flimflam::kTypeWimax) |
+ return CONNECTION_4G; |
+ |
+ if (type != flimflam::kTypeCellular) |
+ return CONNECTION_UNKNOWN; |
+ |
+ // For cellular types, mapping depends on the technology. |
+ if (technology == flimflam::kNetworkTechnologyEvdo || |
+ technology == flimflam::kNetworkTechnologyGsm || |
+ technology == flimflam::kNetworkTechnologyUmts || |
+ technology == flimflam::kNetworkTechnologyHspa) |
+ return CONNECTION_3G; |
+ else if (technology == flimflam::kNetworkTechnologyHspaPlus || |
+ technology == flimflam::kNetworkTechnologyLte || |
+ technology == flimflam::kNetworkTechnologyLteAdvanced) |
+ return CONNECTION_4G; |
+ else |
+ return CONNECTION_2G; // Default cellular type is 2G. |
+} |
+ |
+void ConnectionChangeNotifier::UpdateActiveNetwork( |
+ const chromeos::NetworkState* active_network, |
+ bool* connection_type_changed, |
+ bool* ip_address_changed, |
+ bool* dns_changed) { |
+ *connection_type_changed = *ip_address_changed = *dns_changed = false; |
+ // TODO(gauravsh): DNS changes will be detected once ip config |
+ // support is hooked into NetworkStateHandler. For now, |
+ // we report a DNS change on changes to the active network (including |
+ // loss). |
+ if (!active_network || !active_network->IsConnectedState()) { |
+ // If we lost an active network, we must update our state and notify |
+ // observers, otherwise we have nothing do. (Under normal circumstances, |
+ // we should never ever get duplicate no active network notifications). |
+ if (connection_type_ != CONNECTION_NONE) { |
+ *ip_address_changed = *dns_changed = *connection_type_changed = true; |
+ connection_type_ = CONNECTION_NONE; |
+ service_path_.clear(); |
+ ip_address_.clear(); |
+ } |
+ } else { |
+ // We do have an active network and it is connected. |
+ net::NetworkChangeNotifier::ConnectionType new_connection_type = |
+ ConnectionTypeFromShill(active_network->type(), |
+ active_network->technology()); |
+ if (new_connection_type != connection_type_) { |
+ VLOG(1) << "Connection type changed from " << connection_type_ << " -> " |
+ << new_connection_type; |
+ *connection_type_changed = *dns_changed = true; |
+ } |
+ if (active_network->path() != service_path_ || |
+ active_network->ip_address() != ip_address_) { |
+ VLOG(1) << "Service path changed from " << service_path_ << " -> " |
+ << active_network->path(); |
+ VLOG(1) << "IP Address changed from " << ip_address_ << " -> " |
+ << active_network->ip_address(); |
+ *ip_address_changed = *dns_changed = true; |
+ } |
+ connection_type_ = new_connection_type; |
+ service_path_ = active_network->path(); |
+ ip_address_ = active_network->ip_address(); |
+ } |
+} |
+ |
+void ConnectionChangeNotifier::ReportConnectionTypeChanged() { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ |
+ BrowserThread::PostTask( |
+ BrowserThread::IO, FROM_HERE, |
+ base::Bind(&ConnectionChangeNotifier:: |
+ NotifyObserversOfConnectionTypeChange)); |
+} |
+ |
+void ConnectionChangeNotifier::ReportIPAddressChanged() { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ |
+ BrowserThread::PostTask( |
+ BrowserThread::IO, FROM_HERE, |
+ base::Bind(&ConnectionChangeNotifier:: |
+ NotifyObserversOfIPAddressChange)); |
+} |
+ |
+} // namespace chromeos |
+ |