Chromium Code Reviews| Index: chromeos/network/network_state_handler_impl.cc |
| diff --git a/chromeos/network/network_state_handler_impl.cc b/chromeos/network/network_state_handler_impl.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..e905fc8d18b6eb04e8ce685dcf503480be2c3511 |
| --- /dev/null |
| +++ b/chromeos/network/network_state_handler_impl.cc |
| @@ -0,0 +1,254 @@ |
| +// 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_impl.h" |
| + |
| +#include "base/bind.h" |
| +#include "base/stl_util.h" |
| +#include "base/string_util.h" |
| +#include "base/values.h" |
| +#include "chromeos/dbus/dbus_thread_manager.h" |
| +#include "chromeos/dbus/shill_device_client.h" |
| +#include "chromeos/dbus/shill_ipconfig_client.h" |
| +#include "chromeos/dbus/shill_manager_client.h" |
| +#include "chromeos/dbus/shill_service_client.h" |
| +#include "chromeos/network/network_state_handler.h" |
| +#include "chromeos/network/shill_service_observer.h" |
| +#include "dbus/object_path.h" |
| +#include "third_party/cros_system_api/dbus/service_constants.h" |
| + |
| +namespace { |
| + |
| +void ErrorCallbackFunction(const std::string& error_name, |
| + const std::string& error_message) { |
| + // TODO(stevenjb): Add error logging. |
| + LOG(ERROR) << "Shill Error: " << error_name << " : " << error_message; |
| +} |
| + |
| +const base::ListValue* GetListValue(const std::string& key, |
| + const base::Value& value) { |
| + const base::ListValue* vlist = NULL; |
| + if (!value.GetAsList(&vlist)) { |
| + LOG(ERROR) << "Error parsing key as list: " << key; |
| + return NULL; |
| + } |
| + return vlist; |
| +} |
| + |
| +} // namespace |
| + |
| +namespace chromeos { |
| +namespace internal { |
| + |
| +NetworkStateHandlerImpl::NetworkStateHandlerImpl(NetworkStateHandler* base) |
| + : base_(base), |
| + shill_manager_(DBusThreadManager::Get()->GetShillManagerClient()), |
| + weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { |
| +} |
| + |
| +NetworkStateHandlerImpl::~NetworkStateHandlerImpl() { |
| + // Delete network service observers. |
| + STLDeleteContainerPairSecondPointers( |
| + observed_networks_.begin(), observed_networks_.end()); |
| + CHECK(shill_manager_ == DBusThreadManager::Get()->GetShillManagerClient()); |
| + shill_manager_->RemovePropertyChangedObserver(this); |
| +} |
| + |
| +void NetworkStateHandlerImpl::Init() { |
| + shill_manager_->GetProperties( |
| + base::Bind(&NetworkStateHandlerImpl::ManagerPropertiesCallback, |
| + weak_ptr_factory_.GetWeakPtr())); |
| + shill_manager_->AddPropertyChangedObserver(this); |
| +} |
| + |
| +void NetworkStateHandlerImpl::SetTechnologyEnabled( |
| + const std::string& technology, |
| + bool enabled) { |
| + if (enabled) { |
| + shill_manager_->EnableTechnology(technology, |
| + base::Bind(&base::DoNothing), |
| + base::Bind(&ErrorCallbackFunction)); |
| + } else { |
| + shill_manager_->DisableTechnology(technology, |
| + base::Bind(&base::DoNothing), |
| + base::Bind(&ErrorCallbackFunction)); |
| + } |
| +} |
| + |
| +void NetworkStateHandlerImpl::RequestScan() const { |
| + shill_manager_->RequestScan("", |
| + base::Bind(&base::DoNothing), |
| + base::Bind(&ErrorCallbackFunction)); |
| +} |
| + |
| +void NetworkStateHandlerImpl::RequestProperties(ManagedState::ManagedType type, |
| + const std::string& path) { |
| + ++pending_updates_[type]; |
|
pneubeck (no reviews)
2012/10/29 20:27:49
Shill/DBus guarantees x answers to x requests for
stevenjb
2012/10/30 00:40:25
Yes. Even if there is a timeout or an error the ca
|
| + if (type == ManagedState::MANAGED_TYPE_NETWORK) { |
| + DBusThreadManager::Get()->GetShillServiceClient()->GetProperties( |
| + dbus::ObjectPath(path), |
| + base::Bind(&NetworkStateHandlerImpl::GetPropertiesCallback, |
| + weak_ptr_factory_.GetWeakPtr(), type, path)); |
| + } else if (type == ManagedState::MANAGED_TYPE_DEVICE) { |
| + DBusThreadManager::Get()->GetShillDeviceClient()->GetProperties( |
| + dbus::ObjectPath(path), |
| + base::Bind(&NetworkStateHandlerImpl::GetPropertiesCallback, |
| + weak_ptr_factory_.GetWeakPtr(), type, path)); |
| + } else { |
| + NOTREACHED(); |
| + } |
| +} |
| + |
| +void NetworkStateHandlerImpl::RequestIPConfig( |
| + const std::string& service_path, |
| + const std::string& ip_config_path) { |
| + DBusThreadManager::Get()->GetShillIPConfigClient()->GetProperties( |
| + dbus::ObjectPath(ip_config_path), |
| + base::Bind(&NetworkStateHandlerImpl::GetIPConfigCallback, |
| + weak_ptr_factory_.GetWeakPtr(), |
| + service_path)); |
| +} |
| + |
| + |
| +void NetworkStateHandlerImpl::OnPropertyChanged(const std::string& key, |
| + const base::Value& value) { |
| + if (ManagerPropertyChanged(key, value)) |
| + base_->NotifyManagerChanged(); |
| +} |
| + |
| +//------------------------------------------------------------------------------ |
| +// Private methods |
| + |
| +void NetworkStateHandlerImpl::ManagerPropertiesCallback( |
| + DBusMethodCallStatus call_status, |
| + const base::DictionaryValue& properties) { |
| + if (call_status != DBUS_METHOD_CALL_SUCCESS) { |
| + LOG(ERROR) << "Failed to get Manager properties:" << call_status; |
| + return; |
| + } |
| + bool notify = false; |
| + for (base::DictionaryValue::Iterator iter(properties); |
| + iter.HasNext(); iter.Advance()) { |
| + notify |= ManagerPropertyChanged(iter.key(), iter.value()); |
| + } |
| + if (notify) |
| + base_->NotifyManagerChanged(); |
| +} |
| + |
| +bool NetworkStateHandlerImpl::ManagerPropertyChanged(const std::string& key, |
| + const base::Value& value) { |
| + bool notify_manager_changed = false; |
| + if (key == flimflam::kServicesProperty) { |
| + const base::ListValue* vlist = GetListValue(key, value); |
| + if (vlist) { |
| + base_->UpdateManagedList(ManagedState::MANAGED_TYPE_NETWORK, *vlist); |
| + // Do not send an UpdateManagerChanged notification to observers. |
| + // An UpdateNetworkList notification will be sent when the service list |
| + // updates have completed. |
| + } |
| + } else if (key == flimflam::kServiceWatchListProperty) { |
| + const base::ListValue* vlist = GetListValue(key, value); |
| + if (vlist) { |
| + UpdateObservedNetworkServices(*vlist); |
| + // No notification. |
| + } |
| + } else if (key == flimflam::kDevicesProperty) { |
| + const ListValue* vlist = GetListValue(key, value); |
| + if (vlist) { |
| + base_->UpdateManagedList(ManagedState::MANAGED_TYPE_DEVICE, *vlist); |
| + notify_manager_changed = true; |
| + } |
| + } else if (key == flimflam::kAvailableTechnologiesProperty) { |
| + const base::ListValue* vlist = GetListValue(key, value); |
| + if (vlist ) { |
| + base_->SetAvailableTechnologies(*vlist); |
| + notify_manager_changed = true; |
| + } |
| + } else if (key == flimflam::kEnabledTechnologiesProperty) { |
| + const base::ListValue* vlist = GetListValue(key, value); |
| + if (vlist) { |
| + base_->SetEnabledTechnologies(*vlist); |
| + notify_manager_changed = true; |
| + } |
| + } |
| + return notify_manager_changed; |
| +} |
| + |
| +void NetworkStateHandlerImpl::UpdateObservedNetworkServices( |
| + const base::ListValue& entries) { |
| + // Watch all networks in the watch list. |
| + ShillServiceObserverMap new_observed; |
| + for (base::ListValue::const_iterator iter = entries.begin(); |
| + iter != entries.end(); ++iter) { |
| + std::string path; |
| + (*iter)->GetAsString(&path); |
| + if (path.empty()) |
| + continue; |
| + ShillServiceObserverMap::iterator iter = observed_networks_.find(path); |
| + if (iter != observed_networks_.end()) { |
| + new_observed[path] = observed_networks_[path]; |
| + } else { |
| + new_observed[path] = new ShillServiceObserver( |
| + path, base::Bind( |
| + &NetworkStateHandlerImpl::NetworkServicePropertyChangedCallback, |
| + weak_ptr_factory_.GetWeakPtr())); |
| + // Request an update for newly watched services. |
| + RequestProperties(ManagedState::MANAGED_TYPE_NETWORK, path); |
| + } |
| + observed_networks_.erase(path); |
| + } |
| + VLOG(2) << "UpdateObservedNetworkServices, new observed: " |
| + << new_observed.size(); |
| + // Delete network service observers still in observed_networks_. |
| + STLDeleteContainerPairSecondPointers( |
| + observed_networks_.begin(), observed_networks_.end()); |
| + observed_networks_.swap(new_observed); |
| +} |
| + |
| +void NetworkStateHandlerImpl::GetPropertiesCallback( |
| + ManagedState::ManagedType type, |
| + const std::string& path, |
| + DBusMethodCallStatus call_status, |
| + const base::DictionaryValue& properties) { |
| + VLOG(2) << "GetPropertiesCallback: " << type << " : " << path; |
| + --pending_updates_[type]; |
| + if (call_status != DBUS_METHOD_CALL_SUCCESS) { |
| + LOG(ERROR) << "Failed to get properties for: " << path |
| + << ": " << call_status; |
| + return; |
| + } |
| + base_->ParseProperties(type, path, properties); |
|
pneubeck (no reviews)
2012/10/29 20:27:49
"Parse" is not informative. Perhaps rename it to S
stevenjb
2012/10/30 00:40:25
Well, it is parsing the dictionary, not blindly se
|
| + // Notify observers only when all updates for that type have completed. |
| + if (type == ManagedState::MANAGED_TYPE_NETWORK && |
| + pending_updates_[type] == 0) { |
|
pneubeck (no reviews)
2012/10/29 20:27:49
Maybe, moving pending_updates_ back to NetworkStat
stevenjb
2012/10/30 00:40:25
See previous comment. Renamed the function and cha
|
| + base_->NotifyNetworkServiceObservers(); |
| + } |
| +} |
| + |
| +void NetworkStateHandlerImpl::NetworkServicePropertyChangedCallback( |
| + const std::string& path, |
| + const std::string& key, |
| + const base::Value& value) { |
| + base_->NetworkServicePropertyChanged(path, key, value); |
| +} |
| + |
| +void NetworkStateHandlerImpl::GetIPConfigCallback( |
| + const std::string& service_path, |
| + DBusMethodCallStatus call_status, |
| + const base::DictionaryValue& properties) { |
| + if (call_status != DBUS_METHOD_CALL_SUCCESS) { |
| + LOG(ERROR) << "Failed to get IP properties for: " << service_path; |
| + return; |
| + } |
| + std::string ip_address; |
| + if (!properties.GetStringWithoutPathExpansion(flimflam::kAddressProperty, |
| + &ip_address)) { |
| + LOG(ERROR) << "Failed to get IP Address property for: " << service_path; |
| + return; |
| + } |
| + base_->SetServiceIPAddress(service_path, ip_address); |
| +} |
| + |
| +} // namespace internal |
| +} // namespace chromeos |