Chromium Code Reviews| 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 "chromeos/network/network_state_handler_impl.h" | |
| 6 | |
| 7 #include "base/bind.h" | |
| 8 #include "base/stl_util.h" | |
| 9 #include "base/string_util.h" | |
| 10 #include "base/values.h" | |
| 11 #include "chromeos/dbus/dbus_thread_manager.h" | |
| 12 #include "chromeos/dbus/shill_device_client.h" | |
| 13 #include "chromeos/dbus/shill_ipconfig_client.h" | |
| 14 #include "chromeos/dbus/shill_manager_client.h" | |
| 15 #include "chromeos/dbus/shill_service_client.h" | |
| 16 #include "chromeos/network/network_state_handler.h" | |
| 17 #include "chromeos/network/shill_service_observer.h" | |
| 18 #include "dbus/object_path.h" | |
| 19 #include "third_party/cros_system_api/dbus/service_constants.h" | |
| 20 | |
| 21 namespace { | |
| 22 | |
| 23 void ErrorCallbackFunction(const std::string& error_name, | |
| 24 const std::string& error_message) { | |
| 25 // TODO(stevenjb): Add error logging. | |
| 26 LOG(ERROR) << "Shill Error: " << error_name << " : " << error_message; | |
| 27 } | |
| 28 | |
| 29 const base::ListValue* GetListValue(const std::string& key, | |
| 30 const base::Value& value) { | |
| 31 const base::ListValue* vlist = NULL; | |
| 32 if (!value.GetAsList(&vlist)) { | |
| 33 LOG(ERROR) << "Error parsing key as list: " << key; | |
| 34 return NULL; | |
| 35 } | |
| 36 return vlist; | |
| 37 } | |
| 38 | |
| 39 } // namespace | |
| 40 | |
| 41 namespace chromeos { | |
| 42 namespace internal { | |
| 43 | |
| 44 NetworkStateHandlerImpl::NetworkStateHandlerImpl(NetworkStateHandler* base) | |
| 45 : base_(base), | |
| 46 shill_manager_(DBusThreadManager::Get()->GetShillManagerClient()), | |
| 47 weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { | |
| 48 } | |
| 49 | |
| 50 NetworkStateHandlerImpl::~NetworkStateHandlerImpl() { | |
| 51 // Delete network service observers. | |
| 52 STLDeleteContainerPairSecondPointers( | |
| 53 observed_networks_.begin(), observed_networks_.end()); | |
| 54 CHECK(shill_manager_ == DBusThreadManager::Get()->GetShillManagerClient()); | |
| 55 shill_manager_->RemovePropertyChangedObserver(this); | |
| 56 } | |
| 57 | |
| 58 void NetworkStateHandlerImpl::Init() { | |
| 59 shill_manager_->GetProperties( | |
| 60 base::Bind(&NetworkStateHandlerImpl::ManagerPropertiesCallback, | |
| 61 weak_ptr_factory_.GetWeakPtr())); | |
| 62 shill_manager_->AddPropertyChangedObserver(this); | |
| 63 } | |
| 64 | |
| 65 void NetworkStateHandlerImpl::SetTechnologyEnabled( | |
| 66 const std::string& technology, | |
| 67 bool enabled) { | |
| 68 if (enabled) { | |
| 69 shill_manager_->EnableTechnology(technology, | |
| 70 base::Bind(&base::DoNothing), | |
| 71 base::Bind(&ErrorCallbackFunction)); | |
| 72 } else { | |
| 73 shill_manager_->DisableTechnology(technology, | |
| 74 base::Bind(&base::DoNothing), | |
| 75 base::Bind(&ErrorCallbackFunction)); | |
| 76 } | |
| 77 } | |
| 78 | |
| 79 void NetworkStateHandlerImpl::RequestScan() const { | |
| 80 shill_manager_->RequestScan("", | |
| 81 base::Bind(&base::DoNothing), | |
| 82 base::Bind(&ErrorCallbackFunction)); | |
| 83 } | |
| 84 | |
| 85 void NetworkStateHandlerImpl::RequestProperties(ManagedState::ManagedType type, | |
| 86 const std::string& path) { | |
| 87 ++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
| |
| 88 if (type == ManagedState::MANAGED_TYPE_NETWORK) { | |
| 89 DBusThreadManager::Get()->GetShillServiceClient()->GetProperties( | |
| 90 dbus::ObjectPath(path), | |
| 91 base::Bind(&NetworkStateHandlerImpl::GetPropertiesCallback, | |
| 92 weak_ptr_factory_.GetWeakPtr(), type, path)); | |
| 93 } else if (type == ManagedState::MANAGED_TYPE_DEVICE) { | |
| 94 DBusThreadManager::Get()->GetShillDeviceClient()->GetProperties( | |
| 95 dbus::ObjectPath(path), | |
| 96 base::Bind(&NetworkStateHandlerImpl::GetPropertiesCallback, | |
| 97 weak_ptr_factory_.GetWeakPtr(), type, path)); | |
| 98 } else { | |
| 99 NOTREACHED(); | |
| 100 } | |
| 101 } | |
| 102 | |
| 103 void NetworkStateHandlerImpl::RequestIPConfig( | |
| 104 const std::string& service_path, | |
| 105 const std::string& ip_config_path) { | |
| 106 DBusThreadManager::Get()->GetShillIPConfigClient()->GetProperties( | |
| 107 dbus::ObjectPath(ip_config_path), | |
| 108 base::Bind(&NetworkStateHandlerImpl::GetIPConfigCallback, | |
| 109 weak_ptr_factory_.GetWeakPtr(), | |
| 110 service_path)); | |
| 111 } | |
| 112 | |
| 113 | |
| 114 void NetworkStateHandlerImpl::OnPropertyChanged(const std::string& key, | |
| 115 const base::Value& value) { | |
| 116 if (ManagerPropertyChanged(key, value)) | |
| 117 base_->NotifyManagerChanged(); | |
| 118 } | |
| 119 | |
| 120 //------------------------------------------------------------------------------ | |
| 121 // Private methods | |
| 122 | |
| 123 void NetworkStateHandlerImpl::ManagerPropertiesCallback( | |
| 124 DBusMethodCallStatus call_status, | |
| 125 const base::DictionaryValue& properties) { | |
| 126 if (call_status != DBUS_METHOD_CALL_SUCCESS) { | |
| 127 LOG(ERROR) << "Failed to get Manager properties:" << call_status; | |
| 128 return; | |
| 129 } | |
| 130 bool notify = false; | |
| 131 for (base::DictionaryValue::Iterator iter(properties); | |
| 132 iter.HasNext(); iter.Advance()) { | |
| 133 notify |= ManagerPropertyChanged(iter.key(), iter.value()); | |
| 134 } | |
| 135 if (notify) | |
| 136 base_->NotifyManagerChanged(); | |
| 137 } | |
| 138 | |
| 139 bool NetworkStateHandlerImpl::ManagerPropertyChanged(const std::string& key, | |
| 140 const base::Value& value) { | |
| 141 bool notify_manager_changed = false; | |
| 142 if (key == flimflam::kServicesProperty) { | |
| 143 const base::ListValue* vlist = GetListValue(key, value); | |
| 144 if (vlist) { | |
| 145 base_->UpdateManagedList(ManagedState::MANAGED_TYPE_NETWORK, *vlist); | |
| 146 // Do not send an UpdateManagerChanged notification to observers. | |
| 147 // An UpdateNetworkList notification will be sent when the service list | |
| 148 // updates have completed. | |
| 149 } | |
| 150 } else if (key == flimflam::kServiceWatchListProperty) { | |
| 151 const base::ListValue* vlist = GetListValue(key, value); | |
| 152 if (vlist) { | |
| 153 UpdateObservedNetworkServices(*vlist); | |
| 154 // No notification. | |
| 155 } | |
| 156 } else if (key == flimflam::kDevicesProperty) { | |
| 157 const ListValue* vlist = GetListValue(key, value); | |
| 158 if (vlist) { | |
| 159 base_->UpdateManagedList(ManagedState::MANAGED_TYPE_DEVICE, *vlist); | |
| 160 notify_manager_changed = true; | |
| 161 } | |
| 162 } else if (key == flimflam::kAvailableTechnologiesProperty) { | |
| 163 const base::ListValue* vlist = GetListValue(key, value); | |
| 164 if (vlist ) { | |
| 165 base_->SetAvailableTechnologies(*vlist); | |
| 166 notify_manager_changed = true; | |
| 167 } | |
| 168 } else if (key == flimflam::kEnabledTechnologiesProperty) { | |
| 169 const base::ListValue* vlist = GetListValue(key, value); | |
| 170 if (vlist) { | |
| 171 base_->SetEnabledTechnologies(*vlist); | |
| 172 notify_manager_changed = true; | |
| 173 } | |
| 174 } | |
| 175 return notify_manager_changed; | |
| 176 } | |
| 177 | |
| 178 void NetworkStateHandlerImpl::UpdateObservedNetworkServices( | |
| 179 const base::ListValue& entries) { | |
| 180 // Watch all networks in the watch list. | |
| 181 ShillServiceObserverMap new_observed; | |
| 182 for (base::ListValue::const_iterator iter = entries.begin(); | |
| 183 iter != entries.end(); ++iter) { | |
| 184 std::string path; | |
| 185 (*iter)->GetAsString(&path); | |
| 186 if (path.empty()) | |
| 187 continue; | |
| 188 ShillServiceObserverMap::iterator iter = observed_networks_.find(path); | |
| 189 if (iter != observed_networks_.end()) { | |
| 190 new_observed[path] = observed_networks_[path]; | |
| 191 } else { | |
| 192 new_observed[path] = new ShillServiceObserver( | |
| 193 path, base::Bind( | |
| 194 &NetworkStateHandlerImpl::NetworkServicePropertyChangedCallback, | |
| 195 weak_ptr_factory_.GetWeakPtr())); | |
| 196 // Request an update for newly watched services. | |
| 197 RequestProperties(ManagedState::MANAGED_TYPE_NETWORK, path); | |
| 198 } | |
| 199 observed_networks_.erase(path); | |
| 200 } | |
| 201 VLOG(2) << "UpdateObservedNetworkServices, new observed: " | |
| 202 << new_observed.size(); | |
| 203 // Delete network service observers still in observed_networks_. | |
| 204 STLDeleteContainerPairSecondPointers( | |
| 205 observed_networks_.begin(), observed_networks_.end()); | |
| 206 observed_networks_.swap(new_observed); | |
| 207 } | |
| 208 | |
| 209 void NetworkStateHandlerImpl::GetPropertiesCallback( | |
| 210 ManagedState::ManagedType type, | |
| 211 const std::string& path, | |
| 212 DBusMethodCallStatus call_status, | |
| 213 const base::DictionaryValue& properties) { | |
| 214 VLOG(2) << "GetPropertiesCallback: " << type << " : " << path; | |
| 215 --pending_updates_[type]; | |
| 216 if (call_status != DBUS_METHOD_CALL_SUCCESS) { | |
| 217 LOG(ERROR) << "Failed to get properties for: " << path | |
| 218 << ": " << call_status; | |
| 219 return; | |
| 220 } | |
| 221 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
| |
| 222 // Notify observers only when all updates for that type have completed. | |
| 223 if (type == ManagedState::MANAGED_TYPE_NETWORK && | |
| 224 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
| |
| 225 base_->NotifyNetworkServiceObservers(); | |
| 226 } | |
| 227 } | |
| 228 | |
| 229 void NetworkStateHandlerImpl::NetworkServicePropertyChangedCallback( | |
| 230 const std::string& path, | |
| 231 const std::string& key, | |
| 232 const base::Value& value) { | |
| 233 base_->NetworkServicePropertyChanged(path, key, value); | |
| 234 } | |
| 235 | |
| 236 void NetworkStateHandlerImpl::GetIPConfigCallback( | |
| 237 const std::string& service_path, | |
| 238 DBusMethodCallStatus call_status, | |
| 239 const base::DictionaryValue& properties) { | |
| 240 if (call_status != DBUS_METHOD_CALL_SUCCESS) { | |
| 241 LOG(ERROR) << "Failed to get IP properties for: " << service_path; | |
| 242 return; | |
| 243 } | |
| 244 std::string ip_address; | |
| 245 if (!properties.GetStringWithoutPathExpansion(flimflam::kAddressProperty, | |
| 246 &ip_address)) { | |
| 247 LOG(ERROR) << "Failed to get IP Address property for: " << service_path; | |
| 248 return; | |
| 249 } | |
| 250 base_->SetServiceIPAddress(service_path, ip_address); | |
| 251 } | |
| 252 | |
| 253 } // namespace internal | |
| 254 } // namespace chromeos | |
| OLD | NEW |