[content shell] implement testRunner.overridePreference
[chromium-blink-merge.git] / chromeos / network / network_state_handler.cc
blob7b0e0d9e0e084163753335c92e0a0d68995cf95d
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.
5 #include "chromeos/network/network_state_handler.h"
7 #include "base/format_macros.h"
8 #include "base/stl_util.h"
9 #include "base/string_util.h"
10 #include "base/stringprintf.h"
11 #include "base/values.h"
12 #include "chromeos/network/device_state.h"
13 #include "chromeos/network/managed_state.h"
14 #include "chromeos/network/network_event_log.h"
15 #include "chromeos/network/network_state.h"
16 #include "chromeos/network/network_state_handler_observer.h"
17 #include "chromeos/network/shill_property_handler.h"
18 #include "third_party/cros_system_api/dbus/service_constants.h"
20 namespace {
21 const char kLogModule[] = "NetworkPropertyHandler";
24 namespace chromeos {
26 static NetworkStateHandler* g_network_state_handler = NULL;
28 NetworkStateHandler::NetworkStateHandler() {
31 NetworkStateHandler::~NetworkStateHandler() {
32 STLDeleteContainerPointers(network_list_.begin(), network_list_.end());
33 STLDeleteContainerPointers(device_list_.begin(), device_list_.end());
36 void NetworkStateHandler::InitShillPropertyHandler() {
37 shill_property_handler_.reset(new internal::ShillPropertyHandler(this));
38 shill_property_handler_->Init();
41 // static
42 void NetworkStateHandler::Initialize() {
43 CHECK(!g_network_state_handler);
44 g_network_state_handler = new NetworkStateHandler();
45 g_network_state_handler->InitShillPropertyHandler();
48 // static
49 void NetworkStateHandler::Shutdown() {
50 CHECK(g_network_state_handler);
51 delete g_network_state_handler;
52 g_network_state_handler = NULL;
55 // static
56 NetworkStateHandler* NetworkStateHandler::Get() {
57 CHECK(g_network_state_handler)
58 << "NetworkStateHandler::Get() called before Initialize()";
59 return g_network_state_handler;
62 void NetworkStateHandler::AddObserver(NetworkStateHandlerObserver* observer) {
63 observers_.AddObserver(observer);
66 void NetworkStateHandler::RemoveObserver(
67 NetworkStateHandlerObserver* observer) {
68 observers_.RemoveObserver(observer);
71 bool NetworkStateHandler::TechnologyAvailable(
72 const std::string& technology) const {
73 return available_technologies_.find(technology) !=
74 available_technologies_.end();
77 bool NetworkStateHandler::TechnologyEnabled(
78 const std::string& technology) const {
79 return enabled_technologies_.find(technology) != enabled_technologies_.end();
82 void NetworkStateHandler::SetTechnologyEnabled(
83 const std::string& technology,
84 bool enabled,
85 const network_handler::ErrorCallback& error_callback) {
86 shill_property_handler_->SetTechnologyEnabled(
87 technology, enabled, error_callback);
90 const DeviceState* NetworkStateHandler::GetDeviceState(
91 const std::string& device_path) const {
92 return GetModifiableDeviceState(device_path);
95 const DeviceState* NetworkStateHandler::GetDeviceStateByType(
96 const std::string& type) const {
97 for (ManagedStateList::const_iterator iter = device_list_.begin();
98 iter != device_list_.end(); ++iter) {
99 ManagedState* device = *iter;
100 if (device->type() == type)
101 return device->AsDeviceState();
103 return NULL;
106 const NetworkState* NetworkStateHandler::GetNetworkState(
107 const std::string& service_path) const {
108 return GetModifiableNetworkState(service_path);
111 const NetworkState* NetworkStateHandler::ActiveNetwork() const {
112 if (network_list_.empty())
113 return NULL;
114 const NetworkState* network = network_list_.front()->AsNetworkState();
115 DCHECK(network);
116 if (!network->IsConnectedState())
117 return NULL;
118 return network;
121 const NetworkState* NetworkStateHandler::ConnectedNetworkByType(
122 const std::string& type) const {
123 for (ManagedStateList::const_iterator iter = network_list_.begin();
124 iter != network_list_.end(); ++iter) {
125 const NetworkState* network = (*iter)->AsNetworkState();
126 DCHECK(network);
127 if (!network->IsConnectedState())
128 break; // Connected networks are listed first.
129 if (network->type() == type)
130 return network;
132 return NULL;
135 const NetworkState* NetworkStateHandler::ConnectingNetworkByType(
136 const std::string& type) const {
137 for (ManagedStateList::const_iterator iter = network_list_.begin();
138 iter != network_list_.end(); ++iter) {
139 const NetworkState* network = (*iter)->AsNetworkState();
140 DCHECK(network);
141 if (network->IsConnectedState())
142 continue;
143 if (!network->IsConnectingState())
144 break; // Connected and connecting networks are listed first.
145 if (network->type() == type ||
146 (type.empty() && type != flimflam::kTypeEthernet)) {
147 return network;
150 return NULL;
153 std::string NetworkStateHandler::HardwareAddressForType(
154 const std::string& type) const {
155 std::string result;
156 const NetworkState* network = ConnectedNetworkByType(type);
157 if (network) {
158 const DeviceState* device = GetDeviceState(network->device_path());
159 if (device)
160 result = device->mac_address();
162 StringToUpperASCII(&result);
163 return result;
166 std::string NetworkStateHandler::FormattedHardwareAddressForType(
167 const std::string& type) const {
168 std::string address = HardwareAddressForType(type);
169 if (address.size() % 2 != 0)
170 return address;
171 std::string result;
172 for (size_t i = 0; i < address.size(); ++i) {
173 if ((i != 0) && (i % 2 == 0))
174 result.push_back(':');
175 result.push_back(address[i]);
177 return result;
180 void NetworkStateHandler::GetNetworkList(NetworkStateList* list) const {
181 DCHECK(list);
182 NetworkStateList result;
183 list->clear();
184 for (ManagedStateList::const_iterator iter = network_list_.begin();
185 iter != network_list_.end(); ++iter) {
186 const NetworkState* network = (*iter)->AsNetworkState();
187 DCHECK(network);
188 list->push_back(network);
192 bool NetworkStateHandler::RequestWifiScan() const {
193 if (!TechnologyEnabled(flimflam::kTypeWifi))
194 return false;
195 shill_property_handler_->RequestScan();
196 return true;
199 //------------------------------------------------------------------------------
200 // ShillPropertyHandler::Delegate overrides
202 void NetworkStateHandler::UpdateManagedList(ManagedState::ManagedType type,
203 const base::ListValue& entries) {
204 ManagedStateList* managed_list = GetManagedList(type);
205 VLOG(2) << "UpdateManagedList: " << type;
206 // Create a map of existing entries.
207 std::map<std::string, ManagedState*> managed_map;
208 for (ManagedStateList::iterator iter = managed_list->begin();
209 iter != managed_list->end(); ++iter) {
210 ManagedState* managed = *iter;
211 managed_map[managed->path()] = managed;
213 // Clear the list (pointers are owned by managed_map).
214 managed_list->clear();
215 // Updates managed_list and request updates for new entries.
216 for (base::ListValue::const_iterator iter = entries.begin();
217 iter != entries.end(); ++iter) {
218 std::string path;
219 (*iter)->GetAsString(&path);
220 DCHECK(!path.empty());
221 std::map<std::string, ManagedState*>::iterator found =
222 managed_map.find(path);
223 bool request_properties = false;
224 ManagedState* managed;
225 bool is_observing = shill_property_handler_->IsObservingNetwork(path);
226 if (found == managed_map.end()) {
227 request_properties = true;
228 managed = ManagedState::Create(type, path);
229 managed_list->push_back(managed);
230 } else {
231 managed = found->second;
232 managed_list->push_back(managed);
233 managed_map.erase(found);
234 if (!managed->is_observed() && is_observing)
235 request_properties = true;
237 if (is_observing)
238 managed->set_is_observed(true);
239 if (request_properties)
240 shill_property_handler_->RequestProperties(type, path);
242 // Delete any remaning entries in managed_map.
243 STLDeleteContainerPairSecondPointers(managed_map.begin(), managed_map.end());
246 void NetworkStateHandler::UpdateAvailableTechnologies(
247 const base::ListValue& technologies) {
248 available_technologies_.clear();
249 network_event_log::AddEntry(
250 kLogModule, "AvailableTechnologiesChanged",
251 StringPrintf("Size: %"PRIuS, technologies.GetSize()));
252 for (base::ListValue::const_iterator iter = technologies.begin();
253 iter != technologies.end(); ++iter) {
254 std::string technology;
255 (*iter)->GetAsString(&technology);
256 DCHECK(!technology.empty());
257 available_technologies_.insert(technology);
261 void NetworkStateHandler::UpdateEnabledTechnologies(
262 const base::ListValue& technologies) {
263 bool wifi_was_enabled = TechnologyEnabled(flimflam::kTypeWifi);
264 enabled_technologies_.clear();
265 network_event_log::AddEntry(
266 kLogModule, "EnabledTechnologiesChanged",
267 StringPrintf("Size: %"PRIuS, technologies.GetSize()));
268 for (base::ListValue::const_iterator iter = technologies.begin();
269 iter != technologies.end(); ++iter) {
270 std::string technology;
271 (*iter)->GetAsString(&technology);
272 DCHECK(!technology.empty());
273 enabled_technologies_.insert(technology);
275 if (!wifi_was_enabled && TechnologyEnabled(flimflam::kTypeWifi))
276 RequestWifiScan();
279 void NetworkStateHandler::UpdateManagedStateProperties(
280 ManagedState::ManagedType type,
281 const std::string& path,
282 const base::DictionaryValue& properties) {
283 ManagedState* managed = GetModifiableManagedState(GetManagedList(type), path);
284 if (!managed) {
285 LOG(ERROR) << "GetPropertiesCallback: " << path << " Not found!";
286 return;
288 bool network_property_changed = false;
289 for (base::DictionaryValue::Iterator iter(properties);
290 iter.HasNext(); iter.Advance()) {
291 if (type == ManagedState::MANAGED_TYPE_NETWORK) {
292 if (ParseNetworkServiceProperty(
293 managed->AsNetworkState(), iter.key(), iter.value())) {
294 network_property_changed = true;
296 } else {
297 managed->PropertyChanged(iter.key(), iter.value());
300 // Notify observers.
301 if (network_property_changed) {
302 NetworkState* network = managed->AsNetworkState();
303 DCHECK(network);
304 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_,
305 NetworkServiceChanged(network));
307 network_event_log::AddEntry(
308 kLogModule, "PropertiesReceived",
309 StringPrintf("%s (%s)", path.c_str(), managed->name().c_str()));
312 void NetworkStateHandler::UpdateNetworkServiceProperty(
313 const std::string& service_path,
314 const std::string& key,
315 const base::Value& value) {
316 NetworkState* network = GetModifiableNetworkState(service_path);
317 if (!network)
318 return;
319 if (ParseNetworkServiceProperty(network, key, value)) {
320 std::string detail = network->name() + "." + key;
321 std::string vstr;
322 if (value.GetAsString(&vstr))
323 detail += " = " + vstr;
324 network_event_log::AddEntry(kLogModule, "NetworkPropertyChanged", detail);
325 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_,
326 NetworkServiceChanged(network));
330 void NetworkStateHandler::UpdateNetworkServiceIPAddress(
331 const std::string& service_path,
332 const std::string& ip_address) {
333 NetworkState* network = GetModifiableNetworkState(service_path);
334 if (!network)
335 return;
336 std::string detail = network->name() + ".IPAddress = " + ip_address;
337 network_event_log::AddEntry(kLogModule, "NetworkIPChanged", detail);
338 network->set_ip_address(ip_address);
339 FOR_EACH_OBSERVER(
340 NetworkStateHandlerObserver, observers_,
341 NetworkServiceChanged(network));
344 void NetworkStateHandler::ManagerPropertyChanged() {
345 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_,
346 NetworkManagerChanged());
349 void NetworkStateHandler::ManagedStateListChanged(
350 ManagedState::ManagedType type) {
351 if (type == ManagedState::MANAGED_TYPE_NETWORK) {
352 // Notify observers that the list of networks has changed.
353 NetworkStateList network_list;
354 GetNetworkList(&network_list);
355 network_event_log::AddEntry(
356 kLogModule, "NetworkListChanged",
357 StringPrintf("Size: %"PRIuS, network_list_.size()));
358 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_,
359 NetworkListChanged(network_list));
360 // Update the active network and notify observers if it has changed.
361 NetworkState* new_active_network =
362 network_list_.empty() ? NULL : network_list_.front()->AsNetworkState();
363 std::string new_active_network_path;
364 if (new_active_network)
365 new_active_network_path = new_active_network->path();
366 if (new_active_network_path != active_network_path_) {
367 network_event_log::AddEntry(
368 kLogModule, "ActiveNetworkChanged", new_active_network_path);
369 active_network_path_ = new_active_network_path;
370 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_,
371 ActiveNetworkChanged(new_active_network));
373 } else if (type == ManagedState::MANAGED_TYPE_DEVICE) {
374 network_event_log::AddEntry(
375 kLogModule, "DeviceListChanged",
376 StringPrintf("Size: %"PRIuS, device_list_.size()));
377 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_,
378 DeviceListChanged());
379 } else {
380 NOTREACHED();
384 //------------------------------------------------------------------------------
385 // Private methods
387 DeviceState* NetworkStateHandler::GetModifiableDeviceState(
388 const std::string& device_path) const {
389 ManagedState* managed = GetModifiableManagedState(&device_list_, device_path);
390 if (!managed)
391 return NULL;
392 return managed->AsDeviceState();
395 NetworkState* NetworkStateHandler::GetModifiableNetworkState(
396 const std::string& service_path) const {
397 ManagedState* managed =
398 GetModifiableManagedState(&network_list_, service_path);
399 if (!managed)
400 return NULL;
401 return managed->AsNetworkState();
404 ManagedState* NetworkStateHandler::GetModifiableManagedState(
405 const ManagedStateList* managed_list,
406 const std::string& path) const {
407 for (ManagedStateList::const_iterator iter = managed_list->begin();
408 iter != managed_list->end(); ++iter) {
409 ManagedState* managed = *iter;
410 if (managed->path() == path)
411 return managed;
413 return NULL;
416 NetworkStateHandler::ManagedStateList* NetworkStateHandler::GetManagedList(
417 ManagedState::ManagedType type) {
418 switch (type) {
419 case ManagedState::MANAGED_TYPE_NETWORK:
420 return &network_list_;
421 case ManagedState::MANAGED_TYPE_DEVICE:
422 return &device_list_;
424 NOTREACHED();
425 return NULL;
428 bool NetworkStateHandler::ParseNetworkServiceProperty(
429 NetworkState* network,
430 const std::string& key,
431 const base::Value& value) {
432 DCHECK(network);
433 if (!network->PropertyChanged(key, value))
434 return false;
435 if (network->path() == active_network_path_ &&
436 key == flimflam::kStateProperty) {
437 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_,
438 ActiveNetworkStateChanged(network));
440 return true;
443 } // namespace chromeos