Index: chromeos/network/network_state_handler.cc |
diff --git a/chromeos/network/network_state_handler.cc b/chromeos/network/network_state_handler.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..6e98a7adfc43bed6d8d5964b3b6ab60a3eb1f7d3 |
--- /dev/null |
+++ b/chromeos/network/network_state_handler.cc |
@@ -0,0 +1,393 @@ |
+// 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 "chromeos/network/network_state_handler.h" |
+ |
+#include "base/stl_util.h" |
+#include "base/string_util.h" |
+#include "base/values.h" |
+#include "chromeos/network/device_state.h" |
+#include "chromeos/network/managed_state.h" |
+#include "chromeos/network/network_state.h" |
+#include "chromeos/network/network_state_handler_observer.h" |
+#include "chromeos/network/shill_property_handler.h" |
+#include "third_party/cros_system_api/dbus/service_constants.h" |
+ |
+namespace chromeos { |
+ |
+NetworkStateHandler::NetworkStateHandler() { |
+} |
+ |
+NetworkStateHandler::~NetworkStateHandler() { |
+ STLDeleteContainerPointers(network_list_.begin(), network_list_.end()); |
+ STLDeleteContainerPointers(device_list_.begin(), device_list_.end()); |
+} |
+ |
+void NetworkStateHandler::Init() { |
+ shill_property_handler_.reset(new internal::ShillPropertyHandler(this)); |
+ shill_property_handler_->Init(); |
+} |
+ |
+void NetworkStateHandler::AddObserver(NetworkStateHandlerObserver* observer) { |
+ observers_.AddObserver(observer); |
+} |
+ |
+void NetworkStateHandler::RemoveObserver( |
+ NetworkStateHandlerObserver* observer) { |
+ observers_.RemoveObserver(observer); |
+} |
+ |
+bool NetworkStateHandler::TechnologyAvailable( |
+ const std::string& technology) const { |
+ return available_technologies_.find(technology) != |
+ available_technologies_.end(); |
+} |
+ |
+bool NetworkStateHandler::TechnologyEnabled( |
+ const std::string& technology) const { |
+ return enabled_technologies_.find(technology) != enabled_technologies_.end(); |
+} |
+ |
+void NetworkStateHandler::SetTechnologyEnabled(const std::string& technology, |
+ bool enabled) { |
+ shill_property_handler_->SetTechnologyEnabled(technology, enabled); |
+} |
+ |
+const DeviceState* NetworkStateHandler::GetDeviceState( |
+ const std::string& device_path) const { |
+ return GetModifiableDeviceState(device_path); |
+} |
+ |
+const DeviceState* NetworkStateHandler::GetDeviceStateByType( |
+ const std::string& type) const { |
+ for (ManagedStateList::const_iterator iter = device_list_.begin(); |
+ iter != device_list_.end(); ++iter) { |
+ ManagedState* device = *iter; |
+ if (device->type() == type) |
+ return device->AsDeviceState(); |
+ } |
+ return NULL; |
+} |
+ |
+const NetworkState* NetworkStateHandler::GetNetworkState( |
+ const std::string& service_path) const { |
+ return GetModifiableNetworkState(service_path); |
+} |
+ |
+const NetworkState* NetworkStateHandler::ActiveNetwork() const { |
+ if (network_list_.empty()) |
+ return NULL; |
+ const NetworkState* network = network_list_.front()->AsNetworkState(); |
+ DCHECK(network); |
+ if (!network->IsConnectedState()) |
+ return NULL; |
+ return network; |
+} |
+ |
+const NetworkState* NetworkStateHandler::ConnectedNetworkByType( |
+ const std::string& type) const { |
+ for (ManagedStateList::const_iterator iter = network_list_.begin(); |
+ iter != network_list_.end(); ++iter) { |
+ const NetworkState* network = (*iter)->AsNetworkState(); |
+ DCHECK(network); |
+ if (!network->IsConnectedState()) |
+ break; // Connected networks are listed first. |
+ if (network->type() == type) |
+ return network; |
+ } |
+ return NULL; |
+} |
+ |
+const NetworkState* NetworkStateHandler::ConnectingNetworkByType( |
+ const std::string& type) const { |
+ for (ManagedStateList::const_iterator iter = network_list_.begin(); |
+ iter != network_list_.end(); ++iter) { |
+ const NetworkState* network = (*iter)->AsNetworkState(); |
+ DCHECK(network); |
+ if (network->IsConnectedState()) |
+ continue; |
+ if (!network->IsConnectingState()) |
+ break; // Connected and connecting networks are listed first. |
+ if (network->type() == type || |
+ (type.empty() && type != flimflam::kTypeEthernet)) { |
+ return network; |
+ } |
+ } |
+ return NULL; |
+} |
+ |
+std::string NetworkStateHandler::HardwareAddressForType( |
+ const std::string& type) const { |
+ std::string result; |
+ const NetworkState* network = ConnectedNetworkByType(type); |
+ if (network) { |
+ const DeviceState* device = GetDeviceState(network->device_path()); |
+ if (device) |
+ result = device->mac_address(); |
+ } |
+ StringToUpperASCII(&result); |
+ return result; |
+} |
+ |
+std::string NetworkStateHandler::FormattedHardwareAddressForType( |
+ const std::string& type) const { |
+ std::string address = HardwareAddressForType(type); |
+ if (address.size() % 2 != 0) |
+ return address; |
+ std::string result; |
+ for (size_t i = 0; i < address.size(); ++i) { |
+ if ((i != 0) && (i % 2 == 0)) |
+ result.push_back(':'); |
+ result.push_back(address[i]); |
+ } |
+ return result; |
+} |
+ |
+void NetworkStateHandler::GetNetworkList(NetworkStateList* list) const { |
+ DCHECK(list); |
+ shill_property_handler_->RequestScan(); |
+ NetworkStateList result; |
+ list->clear(); |
+ for (ManagedStateList::const_iterator iter = network_list_.begin(); |
+ iter != network_list_.end(); ++iter) { |
+ const NetworkState* network = (*iter)->AsNetworkState(); |
+ DCHECK(network); |
+ list->push_back(network); |
+ } |
+} |
+ |
+//------------------------------------------------------------------------------ |
+// ShillPropertyHandler::Delegate overrides |
+ |
+void NetworkStateHandler::UpdateManagedList(ManagedState::ManagedType type, |
+ const base::ListValue& entries) { |
+ ManagedStateList* managed_list = GetManagedList(type); |
+ VLOG(2) << "UpdateManagedList: " << type; |
+ // Create a map of existing entries. |
+ std::map<std::string, ManagedState*> managed_map; |
+ for (ManagedStateList::iterator iter = managed_list->begin(); |
+ iter != managed_list->end(); ++iter) { |
+ ManagedState* managed = *iter; |
+ managed_map[managed->path()] = managed; |
+ } |
+ // Clear the list (pointers are owned by managed_map). |
+ managed_list->clear(); |
+ // Updates managed_list and request updates for new entries. |
+ for (base::ListValue::const_iterator iter = entries.begin(); |
+ iter != entries.end(); ++iter) { |
+ std::string path; |
+ (*iter)->GetAsString(&path); |
+ if (path.empty()) |
gauravsh
2012/11/06 01:56:59
This ignores an error in GetAsString() or having a
stevenjb
2012/11/06 03:17:03
Shouldn't happen, changed to DCHECK
pneubeck (no reviews)
2012/11/06 09:18:19
A general question about the usage of DCHECK/NOTRE
|
+ continue; |
+ std::map<std::string, ManagedState*>::iterator found = |
+ managed_map.find(path); |
+ bool request_properties = false; |
+ ManagedState* managed; |
+ bool is_observing = shill_property_handler_->IsObservingNetwork(path); |
+ if (found == managed_map.end()) { |
+ request_properties = true; |
+ managed = ManagedState::Create(type, path); |
+ managed_list->push_back(managed); |
+ } else { |
+ managed = found->second; |
+ managed_list->push_back(managed); |
+ managed_map.erase(found); |
+ if (!managed->is_observed() && is_observing) |
+ request_properties = true; |
+ } |
+ if (is_observing) |
+ managed->set_is_observed(true); |
+ if (request_properties) |
+ shill_property_handler_->RequestProperties(type, path); |
+ } |
+ // Delete any remaning entries in managed_map. |
+ STLDeleteContainerPairSecondPointers(managed_map.begin(), managed_map.end()); |
+} |
+ |
+void NetworkStateHandler::UpdateAvailableTechnologies( |
+ const base::ListValue& technologies) { |
+ available_technologies_.clear(); |
+ for (base::ListValue::const_iterator iter = technologies.begin(); |
+ iter != technologies.end(); ++iter) { |
+ std::string technology; |
+ (*iter)->GetAsString(&technology); |
+ DCHECK(!technology.empty()); |
+ available_technologies_.insert(technology); |
+ } |
+} |
+ |
+void NetworkStateHandler::UpdateEnabledTechnologies( |
+ const base::ListValue& technologies) { |
+ enabled_technologies_.clear(); |
+ for (base::ListValue::const_iterator iter = technologies.begin(); |
+ iter != technologies.end(); ++iter) { |
+ std::string technology; |
+ (*iter)->GetAsString(&technology); |
gauravsh
2012/11/06 01:56:59
See my comment in UpdateManagedList. Why is it ok
stevenjb
2012/11/06 03:17:03
Should never happen which is why it's a DCHECK.
|
+ DCHECK(!technology.empty()); |
+ enabled_technologies_.insert(technology); |
+ } |
+} |
+ |
+void NetworkStateHandler::UpdateManagedStateProperties( |
+ ManagedState::ManagedType type, |
+ const std::string& path, |
+ const base::DictionaryValue& properties) { |
+ ManagedState* managed = GetModifiableManagedState(GetManagedList(type), path); |
+ if (!managed) { |
+ LOG(ERROR) << "GetPropertiesCallback: " << path << " Not found!"; |
+ return; |
+ } |
+ bool property_changed = false; |
+ for (base::DictionaryValue::Iterator iter(properties); |
+ iter.HasNext(); iter.Advance()) { |
+ if (type == ManagedState::MANAGED_TYPE_NETWORK) { |
+ if (ParseNetworkServiceProperty(managed->AsNetworkState(), |
+ iter.key(), iter.value())) |
+ property_changed = true; |
+ } else { |
+ if (managed->PropertyChanged(iter.key(), iter.value())) |
+ property_changed = true; |
gauravsh
2012/11/06 01:56:59
Since MANAGED_TYPE_DEVICE type never causes observ
stevenjb
2012/11/06 03:17:03
Renamed
|
+ } |
+ } |
+ // Notify observers. |
+ if (property_changed && type == ManagedState::MANAGED_TYPE_NETWORK) { |
+ NetworkState* network = managed->AsNetworkState(); |
+ DCHECK(network); |
+ FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_, |
+ NetworkServiceChanged(network)); |
+ } |
+} |
+ |
+void NetworkStateHandler::UpdateNetworkServiceProperty( |
+ const std::string& service_path, |
+ const std::string& key, |
+ const base::Value& value) { |
+ NetworkState* network = GetModifiableNetworkState(service_path); |
+ if (!network) |
+ return; |
+ if (ParseNetworkServiceProperty(network, key, value)) { |
+ FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_, |
+ NetworkServiceChanged(network)); |
+ } |
+} |
+ |
+void NetworkStateHandler::UpdateNetworkServiceIPAddress( |
+ const std::string& service_path, |
+ const std::string& ip_address) { |
+ NetworkState* network = GetModifiableNetworkState(service_path); |
+ if (!network) |
+ return; |
+ network->set_ip_address(ip_address); |
+ FOR_EACH_OBSERVER( |
+ NetworkStateHandlerObserver, observers_, |
+ NetworkServiceChanged(network)); |
+} |
+ |
+void NetworkStateHandler::ManagerPropertyChanged() { |
+ FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_, |
+ NetworkManagerChanged()); |
+} |
+ |
+void NetworkStateHandler::ManagedStateListChanged( |
+ ManagedState::ManagedType type) { |
+ if (type == ManagedState::MANAGED_TYPE_NETWORK) { |
+ // Notify observers that the list of networks has changed. |
+ NetworkStateList network_list; |
+ GetNetworkList(&network_list); |
+ FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_, |
+ NetworkListChanged(network_list)); |
+ // Update the active network and notify observers if it has changed. |
+ NetworkState* new_active_network = |
+ network_list_.empty() ? NULL : network_list_.front()->AsNetworkState(); |
+ std::string new_active_network_path; |
+ if (new_active_network) |
+ new_active_network_path = new_active_network->path(); |
+ if (new_active_network_path != active_network_path_) { |
+ active_network_path_ = new_active_network_path; |
+ FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_, |
+ ActiveNetworkChanged(new_active_network)); |
+ } |
+ } else if (type == ManagedState::MANAGED_TYPE_DEVICE) { |
+ FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_, |
+ DeviceListChanged()); |
+ } else { |
+ NOTREACHED(); |
+ } |
+} |
+ |
+//------------------------------------------------------------------------------ |
+// Private methods |
+ |
+DeviceState* NetworkStateHandler::GetModifiableDeviceState( |
+ const std::string& device_path) const { |
+ ManagedState* managed = GetModifiableManagedState(&device_list_, device_path); |
+ if (!managed) |
+ return NULL; |
+ return managed->AsDeviceState(); |
+} |
+ |
+NetworkState* NetworkStateHandler::GetModifiableNetworkState( |
+ const std::string& service_path) const { |
+ ManagedState* managed = |
+ GetModifiableManagedState(&network_list_, service_path); |
+ if (!managed) |
+ return NULL; |
+ return managed->AsNetworkState(); |
+} |
+ |
+ManagedState* NetworkStateHandler::GetModifiableManagedState( |
+ const ManagedStateList* managed_list, |
+ const std::string& path) const { |
+ for (ManagedStateList::const_iterator iter = managed_list->begin(); |
+ iter != managed_list->end(); ++iter) { |
+ ManagedState* managed = *iter; |
+ if (managed->path() == path) |
+ return managed; |
+ } |
+ return NULL; |
+} |
+ |
+NetworkStateHandler::ManagedStateList* NetworkStateHandler::GetManagedList( |
+ ManagedState::ManagedType type) { |
+ switch(type) { |
+ case ManagedState::MANAGED_TYPE_NETWORK: |
+ return &network_list_; |
+ case ManagedState::MANAGED_TYPE_DEVICE: |
+ return &device_list_; |
+ } |
+ NOTREACHED(); |
+ return NULL; |
+} |
+ |
+bool NetworkStateHandler::ParseNetworkServiceProperty( |
+ NetworkState* network, |
+ const std::string& key, |
+ const base::Value& value) { |
+ DCHECK(network); |
+ bool property_changed = false; |
+ // Handle IPConfig here since it requires additional complexity that is |
+ // better handled here than in NetworkState::PropertyChanged (e.g. |
+ // observer notification). |
+ if (key == shill::kIPConfigProperty) { |
gauravsh
2012/11/06 01:56:59
Is this something that should be re-factored at so
stevenjb
2012/11/06 03:17:03
Moved the comment inside the if() and clarified it
|
+ std::string ip_config_path; |
+ if (value.GetAsString(&ip_config_path)) { |
+ property_changed = true; |
+ shill_property_handler_->RequestIPConfig(network->path(), ip_config_path); |
+ } else { |
+ NOTREACHED(); |
+ } |
+ } else { |
+ if (network->PropertyChanged(key, value)) { |
+ property_changed = true; |
+ if (network->path() == active_network_path_ && |
+ key == flimflam::kStateProperty) { |
+ FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_, |
+ ActiveNetworkStateChanged(network)); |
+ } |
+ } |
+ } |
+ return property_changed; |
+} |
+ |
+} // namespace chromeos |