Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(316)

Side by Side Diff: chromeos/network/network_state_handler.cc

Issue 289383004: Merge FavoriteState into NetworkState (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chromeos/network/network_state_handler.h" 5 #include "chromeos/network/network_state_handler.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/format_macros.h" 8 #include "base/format_macros.h"
9 #include "base/guid.h" 9 #include "base/guid.h"
10 #include "base/location.h" 10 #include "base/location.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/metrics/histogram.h" 12 #include "base/metrics/histogram.h"
13 #include "base/stl_util.h" 13 #include "base/stl_util.h"
14 #include "base/strings/string_util.h" 14 #include "base/strings/string_util.h"
15 #include "base/strings/stringprintf.h" 15 #include "base/strings/stringprintf.h"
16 #include "base/values.h" 16 #include "base/values.h"
17 #include "chromeos/network/device_state.h" 17 #include "chromeos/network/device_state.h"
18 #include "chromeos/network/favorite_state.h"
19 #include "chromeos/network/managed_state.h" 18 #include "chromeos/network/managed_state.h"
20 #include "chromeos/network/network_event_log.h" 19 #include "chromeos/network/network_event_log.h"
21 #include "chromeos/network/network_state.h" 20 #include "chromeos/network/network_state.h"
22 #include "chromeos/network/network_state_handler_observer.h" 21 #include "chromeos/network/network_state_handler_observer.h"
23 #include "chromeos/network/shill_property_handler.h" 22 #include "chromeos/network/shill_property_handler.h"
24 #include "third_party/cros_system_api/dbus/service_constants.h" 23 #include "third_party/cros_system_api/dbus/service_constants.h"
25 24
26 namespace chromeos { 25 namespace chromeos {
27 26
28 namespace { 27 namespace {
29 28
30 bool ConnectionStateChanged(NetworkState* network, 29 bool ConnectionStateChanged(NetworkState* network,
31 const std::string& prev_connection_state) { 30 const std::string& prev_connection_state) {
32 return (network->connection_state() != prev_connection_state) && 31 return (network->connection_state() != prev_connection_state) &&
33 (network->connection_state() != shill::kStateIdle || 32 (network->connection_state() != shill::kStateIdle ||
34 !prev_connection_state.empty()); 33 !prev_connection_state.empty());
35 } 34 }
36 35
37 std::string GetManagedStateLogType(const ManagedState* state) { 36 std::string GetManagedStateLogType(const ManagedState* state) {
38 switch (state->managed_type()) { 37 switch (state->managed_type()) {
39 case ManagedState::MANAGED_TYPE_NETWORK: 38 case ManagedState::MANAGED_TYPE_NETWORK:
40 return "Network"; 39 return "Network";
41 case ManagedState::MANAGED_TYPE_FAVORITE:
42 return "Favorite";
43 case ManagedState::MANAGED_TYPE_DEVICE: 40 case ManagedState::MANAGED_TYPE_DEVICE:
44 return "Device"; 41 return "Device";
45 } 42 }
46 NOTREACHED(); 43 NOTREACHED();
47 return ""; 44 return "";
48 } 45 }
49 46
50 std::string GetManagedStateLogName(const ManagedState* state) { 47 std::string GetManagedStateLogName(const ManagedState* state) {
51 if (!state) 48 if (!state)
52 return "None"; 49 return "None";
53 return base::StringPrintf("%s (%s)", state->name().c_str(), 50 return base::StringPrintf("%s (%s)", state->name().c_str(),
54 state->path().c_str()); 51 state->path().c_str());
55 } 52 }
56 53
57 } // namespace 54 } // namespace
58 55
59 const char NetworkStateHandler::kDefaultCheckPortalList[] = 56 const char NetworkStateHandler::kDefaultCheckPortalList[] =
60 "ethernet,wifi,cellular"; 57 "ethernet,wifi,cellular";
61 58
62 NetworkStateHandler::NetworkStateHandler() { 59 NetworkStateHandler::NetworkStateHandler() {
63 } 60 }
64 61
65 NetworkStateHandler::~NetworkStateHandler() { 62 NetworkStateHandler::~NetworkStateHandler() {
66 STLDeleteContainerPointers(network_list_.begin(), network_list_.end()); 63 STLDeleteContainerPointers(network_list_.begin(), network_list_.end());
67 STLDeleteContainerPointers(favorite_list_.begin(), favorite_list_.end());
68 STLDeleteContainerPointers(device_list_.begin(), device_list_.end()); 64 STLDeleteContainerPointers(device_list_.begin(), device_list_.end());
69 } 65 }
70 66
71 void NetworkStateHandler::InitShillPropertyHandler() { 67 void NetworkStateHandler::InitShillPropertyHandler() {
72 shill_property_handler_.reset(new internal::ShillPropertyHandler(this)); 68 shill_property_handler_.reset(new internal::ShillPropertyHandler(this));
73 shill_property_handler_->Init(); 69 shill_property_handler_->Init();
74 } 70 }
75 71
76 // static 72 // static
77 NetworkStateHandler* NetworkStateHandler::InitializeForTest() { 73 NetworkStateHandler* NetworkStateHandler::InitializeForTest() {
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 return NULL; 179 return NULL;
184 return network; 180 return network;
185 } 181 }
186 182
187 const NetworkState* NetworkStateHandler::DefaultNetwork() const { 183 const NetworkState* NetworkStateHandler::DefaultNetwork() const {
188 if (default_network_path_.empty()) 184 if (default_network_path_.empty())
189 return NULL; 185 return NULL;
190 return GetNetworkState(default_network_path_); 186 return GetNetworkState(default_network_path_);
191 } 187 }
192 188
193 const FavoriteState* NetworkStateHandler::DefaultFavoriteNetwork() const {
194 const NetworkState* default_network = DefaultNetwork();
195 if (!default_network)
196 return NULL;
197 const FavoriteState* default_favorite = GetFavoriteStateFromServicePath(
198 default_network->path(), true /* configured_only */);
199 DCHECK(default_network->type() != shill::kTypeWifi || default_favorite)
200 << "No favorite for: " << default_network->path();
201 DCHECK(!default_favorite || default_favorite->update_received())
202 << "No update received for: " << default_network->path();
203 return default_favorite;
204 }
205
206 const NetworkState* NetworkStateHandler::ConnectedNetworkByType( 189 const NetworkState* NetworkStateHandler::ConnectedNetworkByType(
207 const NetworkTypePattern& type) const { 190 const NetworkTypePattern& type) const {
208 for (ManagedStateList::const_iterator iter = network_list_.begin(); 191 for (ManagedStateList::const_iterator iter = network_list_.begin();
209 iter != network_list_.end(); ++iter) { 192 iter != network_list_.end(); ++iter) {
210 const NetworkState* network = (*iter)->AsNetworkState(); 193 const NetworkState* network = (*iter)->AsNetworkState();
211 DCHECK(network); 194 DCHECK(network);
212 if (!network->update_received()) 195 if (!network->update_received())
213 continue; 196 continue;
214 if (!network->IsConnectedState()) 197 if (!network->IsConnectedState())
215 break; // Connected networks are listed first. 198 break; // Connected networks are listed first.
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
255 const NetworkState* network = ConnectedNetworkByType(type); 238 const NetworkState* network = ConnectedNetworkByType(type);
256 if (network) 239 if (network)
257 device = GetDeviceState(network->device_path()); 240 device = GetDeviceState(network->device_path());
258 else 241 else
259 device = GetDeviceStateByType(type); 242 device = GetDeviceStateByType(type);
260 if (!device) 243 if (!device)
261 return std::string(); 244 return std::string();
262 return network_util::FormattedMacAddress(device->mac_address()); 245 return network_util::FormattedMacAddress(device->mac_address());
263 } 246 }
264 247
265 void NetworkStateHandler::GetNetworkList(NetworkStateList* list) const { 248 void NetworkStateHandler::GetVisibleNetworkList(NetworkStateList* list) const {
266 GetNetworkListByType(NetworkTypePattern::Default(), list); 249 GetNetworkListByType(NetworkTypePattern::Default(),
250 false /* configured_only */,
251 true /* visible_only */,
252 0 /* no limit */,
253 list);
267 } 254 }
268 255
269 void NetworkStateHandler::GetNetworkListByType(const NetworkTypePattern& type, 256 void NetworkStateHandler::GetNetworkListByType(const NetworkTypePattern& type,
257 bool configured_only,
258 bool visible_only,
259 int limit,
270 NetworkStateList* list) const { 260 NetworkStateList* list) const {
271 DCHECK(list); 261 DCHECK(list);
272 list->clear();
273 for (ManagedStateList::const_iterator iter = network_list_.begin();
274 iter != network_list_.end(); ++iter) {
275 const NetworkState* network = (*iter)->AsNetworkState();
276 DCHECK(network);
277 if (network->update_received() && network->Matches(type))
278 list->push_back(network);
279 }
280 }
281
282 void NetworkStateHandler::GetDeviceList(DeviceStateList* list) const {
283 GetDeviceListByType(NetworkTypePattern::Default(), list);
284 }
285
286 void NetworkStateHandler::GetDeviceListByType(const NetworkTypePattern& type,
287 DeviceStateList* list) const {
288 DCHECK(list);
289 list->clear();
290 for (ManagedStateList::const_iterator iter = device_list_.begin();
291 iter != device_list_.end(); ++iter) {
292 const DeviceState* device = (*iter)->AsDeviceState();
293 DCHECK(device);
294 if (device->update_received() && device->Matches(type))
295 list->push_back(device);
296 }
297 }
298
299 void NetworkStateHandler::GetFavoriteList(FavoriteStateList* list) const {
300 GetFavoriteListByType(NetworkTypePattern::Default(),
301 true /* configured_only */,
302 false /* visible_only */,
303 0 /* no limit */,
304 list);
305 }
306
307 void NetworkStateHandler::GetFavoriteListByType(const NetworkTypePattern& type,
308 bool configured_only,
309 bool visible_only,
310 int limit,
311 FavoriteStateList* list) const {
312 DCHECK(list);
313 std::set<std::string> visible_networks; 262 std::set<std::string> visible_networks;
314 if (visible_only) { 263 if (visible_only) {
315 // Prepare a set of visible network service paths for fast lookup. 264 // Prepare a set of visible network service paths for fast lookup.
316 for (ManagedStateList::const_iterator iter = network_list_.begin(); 265 for (ManagedStateList::const_iterator iter = network_list_.begin();
317 iter != network_list_.end(); ++iter) { 266 iter != network_list_.end(); ++iter) {
318 visible_networks.insert((*iter)->path()); 267 visible_networks.insert((*iter)->path());
319 } 268 }
320 } 269 }
321 FavoriteStateList result; 270 NetworkStateList result;
322 list->clear(); 271 list->clear();
323 int count = 0; 272 int count = 0;
324 for (ManagedStateList::const_iterator iter = favorite_list_.begin(); 273 for (ManagedStateList::const_iterator iter = network_list_.begin();
325 iter != favorite_list_.end(); ++iter) { 274 iter != network_list_.end(); ++iter) {
326 const FavoriteState* favorite = (*iter)->AsFavoriteState(); 275 const NetworkState* network = (*iter)->AsNetworkState();
327 DCHECK(favorite); 276 DCHECK(network);
328 if (!favorite->update_received() || !favorite->Matches(type)) 277 if (!network->update_received() || !network->Matches(type))
329 continue; 278 continue;
330 if (configured_only && !favorite->IsInProfile()) 279 if (configured_only && !network->IsInProfile())
331 continue; 280 continue;
332 if (visible_only && !ContainsKey(visible_networks, favorite->path())) 281 if (visible_only && !ContainsKey(visible_networks, network->path()))
333 continue; 282 continue;
334 list->push_back(favorite); 283 list->push_back(network);
335 if (limit > 0 && ++count >= limit) 284 if (limit > 0 && ++count >= limit)
336 break; 285 break;
337 } 286 }
338 } 287 }
339 288
340 const FavoriteState* NetworkStateHandler::GetFavoriteStateFromServicePath( 289 const NetworkState* NetworkStateHandler::GetNetworkStateFromServicePath(
341 const std::string& service_path, 290 const std::string& service_path,
342 bool configured_only) const { 291 bool configured_only) const {
343 ManagedState* managed = 292 ManagedState* managed =
344 GetModifiableManagedState(&favorite_list_, service_path); 293 GetModifiableManagedState(&network_list_, service_path);
345 if (!managed) 294 if (!managed)
346 return NULL; 295 return NULL;
347 const FavoriteState* favorite = managed->AsFavoriteState(); 296 const NetworkState* network = managed->AsNetworkState();
348 DCHECK(favorite); 297 DCHECK(network);
349 if (!favorite->update_received() || 298 if (!network->update_received() ||
350 (configured_only && !favorite->IsInProfile())) { 299 (configured_only && !network->IsInProfile())) {
351 return NULL; 300 return NULL;
352 } 301 }
353 return favorite; 302 return network;
354 } 303 }
355 304
356 const FavoriteState* NetworkStateHandler::GetFavoriteStateFromGuid( 305 const NetworkState* NetworkStateHandler::GetNetworkStateFromGuid(
357 const std::string& guid) const { 306 const std::string& guid) const {
358 DCHECK(!guid.empty()); 307 DCHECK(!guid.empty());
359 for (ManagedStateList::const_iterator iter = favorite_list_.begin(); 308 for (ManagedStateList::const_iterator iter = network_list_.begin();
360 iter != favorite_list_.end(); ++iter) { 309 iter != network_list_.end(); ++iter) {
361 const FavoriteState* favorite = (*iter)->AsFavoriteState(); 310 const NetworkState* network = (*iter)->AsNetworkState();
362 if (favorite->guid() == guid) 311 if (network->guid() == guid)
363 return favorite; 312 return network;
364 } 313 }
365 return NULL; 314 return NULL;
366 } 315 }
367 316
317 void NetworkStateHandler::GetDeviceList(DeviceStateList* list) const {
318 GetDeviceListByType(NetworkTypePattern::Default(), list);
319 }
320
321 void NetworkStateHandler::GetDeviceListByType(const NetworkTypePattern& type,
322 DeviceStateList* list) const {
323 DCHECK(list);
324 list->clear();
325 for (ManagedStateList::const_iterator iter = device_list_.begin();
326 iter != device_list_.end(); ++iter) {
327 const DeviceState* device = (*iter)->AsDeviceState();
328 DCHECK(device);
329 if (device->update_received() && device->Matches(type))
330 list->push_back(device);
331 }
332 }
333
368 void NetworkStateHandler::RequestScan() const { 334 void NetworkStateHandler::RequestScan() const {
369 NET_LOG_USER("RequestScan", ""); 335 NET_LOG_USER("RequestScan", "");
370 shill_property_handler_->RequestScan(); 336 shill_property_handler_->RequestScan();
371 } 337 }
372 338
373 void NetworkStateHandler::WaitForScan(const std::string& type, 339 void NetworkStateHandler::WaitForScan(const std::string& type,
374 const base::Closure& callback) { 340 const base::Closure& callback) {
375 scan_complete_callbacks_[type].push_back(callback); 341 scan_complete_callbacks_[type].push_back(callback);
376 if (!GetScanningByType(NetworkTypePattern::Primitive(type))) 342 if (!GetScanningByType(NetworkTypePattern::Primitive(type)))
377 RequestScan(); 343 RequestScan();
(...skipping 22 matching lines...) Expand all
400 if (network) 366 if (network)
401 network->clear_last_error(); 367 network->clear_last_error();
402 } 368 }
403 369
404 void NetworkStateHandler::SetCheckPortalList( 370 void NetworkStateHandler::SetCheckPortalList(
405 const std::string& check_portal_list) { 371 const std::string& check_portal_list) {
406 NET_LOG_EVENT("SetCheckPortalList", check_portal_list); 372 NET_LOG_EVENT("SetCheckPortalList", check_portal_list);
407 shill_property_handler_->SetCheckPortalList(check_portal_list); 373 shill_property_handler_->SetCheckPortalList(check_portal_list);
408 } 374 }
409 375
410 const FavoriteState* NetworkStateHandler::GetEAPForEthernet( 376 const NetworkState* NetworkStateHandler::GetEAPForEthernet(
411 const std::string& service_path) const { 377 const std::string& service_path) const {
412 const NetworkState* network = GetNetworkState(service_path); 378 const NetworkState* network = GetNetworkState(service_path);
413 if (!network) { 379 if (!network) {
414 NET_LOG_ERROR("GetEAPForEthernet", "Unknown service path " + service_path); 380 NET_LOG_ERROR("GetEAPForEthernet", "Unknown service path " + service_path);
415 return NULL; 381 return NULL;
416 } 382 }
417 if (network->type() != shill::kTypeEthernet) { 383 if (network->type() != shill::kTypeEthernet) {
418 NET_LOG_ERROR("GetEAPForEthernet", "Not of type Ethernet: " + service_path); 384 NET_LOG_ERROR("GetEAPForEthernet", "Not of type Ethernet: " + service_path);
419 return NULL; 385 return NULL;
420 } 386 }
421 if (!network->IsConnectedState()) 387 if (!network->IsConnectedState())
422 return NULL; 388 return NULL;
423 389
424 // The same EAP service is shared for all ethernet services/devices. 390 // The same EAP service is shared for all ethernet services/devices.
425 // However EAP is used/enabled per device and only if the connection was 391 // However EAP is used/enabled per device and only if the connection was
426 // successfully established. 392 // successfully established.
427 const DeviceState* device = GetDeviceState(network->device_path()); 393 const DeviceState* device = GetDeviceState(network->device_path());
428 if (!device) { 394 if (!device) {
429 NET_LOG_ERROR( 395 NET_LOG_ERROR(
430 "GetEAPForEthernet", 396 "GetEAPForEthernet",
431 base::StringPrintf("Unknown device %s of connected ethernet service %s", 397 base::StringPrintf("Unknown device %s of connected ethernet service %s",
432 network->device_path().c_str(), 398 network->device_path().c_str(),
433 service_path.c_str())); 399 service_path.c_str()));
434 return NULL; 400 return NULL;
435 } 401 }
436 if (!device->eap_authentication_completed()) 402 if (!device->eap_authentication_completed())
437 return NULL; 403 return NULL;
438 404
439 FavoriteStateList list; 405 NetworkStateList list;
440 GetFavoriteListByType(NetworkTypePattern::Primitive(shill::kTypeEthernetEap), 406 GetNetworkListByType(NetworkTypePattern::Primitive(shill::kTypeEthernetEap),
441 true /* configured_only */, 407 true /* configured_only */,
442 false /* visible_only */, 408 false /* visible_only */,
443 1 /* limit */, 409 1 /* limit */,
444 &list); 410 &list);
445 if (list.empty()) { 411 if (list.empty()) {
446 NET_LOG_ERROR("GetEAPForEthernet", 412 NET_LOG_ERROR("GetEAPForEthernet",
447 base::StringPrintf( 413 base::StringPrintf(
448 "Ethernet service %s connected using EAP, but no " 414 "Ethernet service %s connected using EAP, but no "
449 "EAP service found.", 415 "EAP service found.",
450 service_path.c_str())); 416 service_path.c_str()));
451 return NULL; 417 return NULL;
452 } 418 }
453 return list.front(); 419 return list.front();
454 } 420 }
455 421
456 //------------------------------------------------------------------------------ 422 //------------------------------------------------------------------------------
457 // ShillPropertyHandler::Delegate overrides 423 // ShillPropertyHandler::Delegate overrides
458 424
425 void NetworkStateHandler::UpdateManagedDevices(const base::ListValue& entries) {
426 UpdateManagedList(ManagedState::MANAGED_TYPE_DEVICE, entries);
427 }
428
429 void NetworkStateHandler::UpdateManagedNetworks(
430 const base::ListValue& entries,
431 bool complete_list) {
432 if (complete_list) {
stevenjb 2014/05/28 23:06:10 elim {}
433 UpdateManagedList(ManagedState::MANAGED_TYPE_NETWORK, entries);
434 } else {
435 UpdateVisibleNetworks(entries);
436 }
437 }
438
459 void NetworkStateHandler::UpdateManagedList(ManagedState::ManagedType type, 439 void NetworkStateHandler::UpdateManagedList(ManagedState::ManagedType type,
460 const base::ListValue& entries) { 440 const base::ListValue& entries) {
461 ManagedStateList* managed_list = GetManagedList(type); 441 ManagedStateList* managed_list = GetManagedList(type);
462 NET_LOG_DEBUG(base::StringPrintf("UpdateManagedList:%d", type), 442 NET_LOG_DEBUG("UpdateManagedList: " + ManagedState::TypeToString(type),
463 base::StringPrintf("%" PRIuS, entries.GetSize())); 443 base::StringPrintf("%" PRIuS, entries.GetSize()));
464 // Create a map of existing entries. Assumes all entries in |managed_list| 444 // Create a map of existing entries. Assumes all entries in |managed_list|
465 // are unique. 445 // are unique.
466 std::map<std::string, ManagedState*> managed_map; 446 typedef std::map<std::string, ManagedState*> ManagedMap;
447 ManagedMap managed_map;
467 for (ManagedStateList::iterator iter = managed_list->begin(); 448 for (ManagedStateList::iterator iter = managed_list->begin();
468 iter != managed_list->end(); ++iter) { 449 iter != managed_list->end(); ++iter) {
469 ManagedState* managed = *iter; 450 ManagedState* managed = *iter;
470 DCHECK(!ContainsKey(managed_map, managed->path())); 451 DCHECK(!ContainsKey(managed_map, managed->path()));
471 managed_map[managed->path()] = managed; 452 managed_map[managed->path()] = managed;
472 } 453 }
473 // Clear the list (pointers are temporarily owned by managed_map). 454 // Clear the list (pointers are temporarily owned by managed_map).
474 managed_list->clear(); 455 managed_list->clear();
475 // Updates managed_list and request updates for new entries. 456 // Updates managed_list and request updates for new entries.
476 std::set<std::string> list_entries; 457 std::set<std::string> list_entries;
477 for (base::ListValue::const_iterator iter = entries.begin(); 458 for (base::ListValue::const_iterator iter = entries.begin();
478 iter != entries.end(); ++iter) { 459 iter != entries.end(); ++iter) {
479 std::string path; 460 std::string path;
480 (*iter)->GetAsString(&path); 461 (*iter)->GetAsString(&path);
481 if (path.empty() || path == shill::kFlimflamServicePath) { 462 if (path.empty() || path == shill::kFlimflamServicePath) {
482 NET_LOG_ERROR(base::StringPrintf("Bad path in list:%d", type), path); 463 NET_LOG_ERROR(base::StringPrintf("Bad path in list:%d", type), path);
483 continue; 464 continue;
484 } 465 }
485 std::map<std::string, ManagedState*>::iterator found =
486 managed_map.find(path);
487 ManagedState* managed; 466 ManagedState* managed;
467 ManagedMap::iterator found = managed_map.find(path);
488 if (found == managed_map.end()) { 468 if (found == managed_map.end()) {
489 if (list_entries.count(path) != 0) { 469 if (list_entries.count(path) != 0) {
490 NET_LOG_ERROR("Duplicate entry in list", path); 470 NET_LOG_ERROR("Duplicate entry in list", path);
491 continue; 471 continue;
492 } 472 }
493 managed = ManagedState::Create(type, path); 473 managed = ManagedState::Create(type, path);
494 managed_list->push_back(managed); 474 managed_list->push_back(managed);
495 } else { 475 } else {
496 managed = found->second; 476 managed = found->second;
497 managed_list->push_back(managed); 477 managed_list->push_back(managed);
498 managed_map.erase(found); 478 managed_map.erase(found);
499 } 479 }
480 NET_LOG_DEBUG("Managed Entry: " + ManagedState::TypeToString(type), path);
500 list_entries.insert(path); 481 list_entries.insert(path);
501 } 482 }
502 // Delete any remaining entries in managed_map. 483 // Delete any remaining entries in managed_map.
503 STLDeleteContainerPairSecondPointers(managed_map.begin(), managed_map.end()); 484 STLDeleteContainerPairSecondPointers(managed_map.begin(), managed_map.end());
504 } 485 }
505 486
506 void NetworkStateHandler::ProfileListChanged() { 487 void NetworkStateHandler::UpdateVisibleNetworks(
507 NET_LOG_EVENT("ProfileListChanged", "Re-Requesting Network Properties"); 488 const base::ListValue& entries) {
508 for (ManagedStateList::iterator iter = favorite_list_.begin(); 489 NET_LOG_DEBUG(base::StringPrintf("UpdateVisibleNetworks"),
509 iter != favorite_list_.end(); ++iter) { 490 base::StringPrintf("%" PRIuS, entries.GetSize()));
510 shill_property_handler_->RequestProperties( 491 // Clear visible state of all networks.
511 ManagedState::MANAGED_TYPE_NETWORK, (*iter)->path()); 492 ManagedStateList* network_list =
493 GetManagedList(ManagedState::MANAGED_TYPE_NETWORK);
494 typedef std::map<std::string, NetworkState*> NetworkMap;
495 NetworkMap network_map;
496 for (ManagedStateList::iterator iter = network_list->begin();
497 iter != network_list->end(); ++iter) {
498 NetworkState* network = (*iter)->AsNetworkState();
499 network_map[network->path()] = network;
500 network->set_visible(false);
501 }
502 for (base::ListValue::const_iterator iter = entries.begin();
503 iter != entries.end(); ++iter) {
504 std::string path;
505 (*iter)->GetAsString(&path);
506 if (path.empty() || path == shill::kFlimflamServicePath) {
507 NET_LOG_ERROR(base::StringPrintf("Bad path in visible networks"), path);
508 continue;
509 }
510 NetworkMap::iterator found = network_map.find(path);
511 if (found != network_map.end()) {
stevenjb 2014/05/28 23:06:10 ContainsKey
512 NetworkState* network = found->second;
513 network->set_visible(true);
514 }
512 } 515 }
513 } 516 }
514 517
518 void NetworkStateHandler::ProfileListChanged() {
519 NET_LOG_EVENT("ProfileListChanged", "Re-Requesting Network Properties");
520 for (ManagedStateList::iterator iter = network_list_.begin();
521 iter != network_list_.end(); ++iter) {
522 NetworkState* network = (*iter)->AsNetworkState();
523 DCHECK(network);
524 if (!network->IsInProfile())
525 continue;
526 shill_property_handler_->RequestProperties(
527 ManagedState::MANAGED_TYPE_NETWORK, network->path());
528 }
529 }
530
515 void NetworkStateHandler::UpdateManagedStateProperties( 531 void NetworkStateHandler::UpdateManagedStateProperties(
516 ManagedState::ManagedType type, 532 ManagedState::ManagedType type,
517 const std::string& path, 533 const std::string& path,
518 const base::DictionaryValue& properties) { 534 const base::DictionaryValue& properties) {
519 ManagedStateList* managed_list = GetManagedList(type); 535 ManagedStateList* managed_list = GetManagedList(type);
520 ManagedState* managed = GetModifiableManagedState(managed_list, path); 536 ManagedState* managed = GetModifiableManagedState(managed_list, path);
521 if (!managed) { 537 if (!managed) {
522 if (type != ManagedState::MANAGED_TYPE_FAVORITE) { 538 // The network has been removed from the list of visible networks.
stevenjb 2014/05/28 23:06:10 list of networks
523 // The network has been removed from the list of visible networks. 539 NET_LOG_DEBUG("UpdateManagedStateProperties: Not found", path);
524 NET_LOG_DEBUG("UpdateManagedStateProperties: Not found", path); 540 return;
525 return;
526 }
527 // A Favorite may not have been created yet if it was added later (e.g.
528 // through ConfigureService) since ServiceCompleteList updates are not
529 // emitted. Add and update the state here.
530 managed = ManagedState::Create(type, path);
531 managed_list->push_back(managed);
532 } 541 }
533 managed->set_update_received(); 542 managed->set_update_received();
534 543
535 std::string desc = GetManagedStateLogType(managed) + " Properties Received"; 544 std::string desc = GetManagedStateLogType(managed) + " Properties Received";
536 NET_LOG_DEBUG(desc, GetManagedStateLogName(managed)); 545 NET_LOG_DEBUG(desc, GetManagedStateLogName(managed));
537 546
538 if (type == ManagedState::MANAGED_TYPE_NETWORK) { 547 if (type == ManagedState::MANAGED_TYPE_NETWORK) {
539 UpdateNetworkStateProperties(managed->AsNetworkState(), properties); 548 UpdateNetworkStateProperties(managed->AsNetworkState(), properties);
540 } else { 549 } else {
541 // Device, Favorite 550 // Device
542 for (base::DictionaryValue::Iterator iter(properties); 551 for (base::DictionaryValue::Iterator iter(properties);
543 !iter.IsAtEnd(); iter.Advance()) { 552 !iter.IsAtEnd(); iter.Advance()) {
544 managed->PropertyChanged(iter.key(), iter.value()); 553 managed->PropertyChanged(iter.key(), iter.value());
545 } 554 }
546 managed->InitialPropertiesReceived(properties); 555 managed->InitialPropertiesReceived(properties);
547 } 556 }
548 UpdateGuid(managed);
549 managed->set_update_requested(false); 557 managed->set_update_requested(false);
550 } 558 }
551 559
552 void NetworkStateHandler::UpdateNetworkStateProperties( 560 void NetworkStateHandler::UpdateNetworkStateProperties(
553 NetworkState* network, 561 NetworkState* network,
554 const base::DictionaryValue& properties) { 562 const base::DictionaryValue& properties) {
555 DCHECK(network); 563 DCHECK(network);
556 bool network_property_updated = false; 564 bool network_property_updated = false;
557 std::string prev_connection_state = network->connection_state(); 565 std::string prev_connection_state = network->connection_state();
558 for (base::DictionaryValue::Iterator iter(properties); 566 for (base::DictionaryValue::Iterator iter(properties);
559 !iter.IsAtEnd(); iter.Advance()) { 567 !iter.IsAtEnd(); iter.Advance()) {
560 if (network->PropertyChanged(iter.key(), iter.value())) 568 if (network->PropertyChanged(iter.key(), iter.value()))
561 network_property_updated = true; 569 network_property_updated = true;
562 } 570 }
563 network_property_updated |= network->InitialPropertiesReceived(properties); 571 network_property_updated |= network->InitialPropertiesReceived(properties);
564 // Notify observers of NetworkState changes. 572 // Notify observers of NetworkState changes.
565 if (network_property_updated || network->update_requested()) { 573 if (network_property_updated || network->update_requested()) {
566 // Signal connection state changed after all properties have been updated. 574 // Signal connection state changed after all properties have been updated.
567 if (ConnectionStateChanged(network, prev_connection_state)) 575 if (ConnectionStateChanged(network, prev_connection_state))
568 OnNetworkConnectionStateChanged(network); 576 OnNetworkConnectionStateChanged(network);
569 NET_LOG_EVENT("NetworkPropertiesUpdated", GetManagedStateLogName(network)); 577 NET_LOG_EVENT("NetworkPropertiesUpdated", GetManagedStateLogName(network));
570 NotifyNetworkPropertiesUpdated(network); 578 NotifyNetworkPropertiesUpdated(network);
571 } 579 }
580 UpdateGuid(network);
572 } 581 }
573 582
574 void NetworkStateHandler::UpdateNetworkServiceProperty( 583 void NetworkStateHandler::UpdateNetworkServiceProperty(
575 const std::string& service_path, 584 const std::string& service_path,
576 const std::string& key, 585 const std::string& key,
577 const base::Value& value) { 586 const base::Value& value) {
578 // Update any associated FavoriteState.
579 ManagedState* favorite =
580 GetModifiableManagedState(&favorite_list_, service_path);
581 bool changed = false; 587 bool changed = false;
582 if (favorite)
583 changed |= favorite->PropertyChanged(key, value);
584
585 // Update the NetworkState.
586 NetworkState* network = GetModifiableNetworkState(service_path); 588 NetworkState* network = GetModifiableNetworkState(service_path);
587 if (!network) 589 if (!network)
588 return; 590 return;
589 std::string prev_connection_state = network->connection_state(); 591 std::string prev_connection_state = network->connection_state();
590 std::string prev_profile_path = network->profile_path(); 592 std::string prev_profile_path = network->profile_path();
591 changed |= network->PropertyChanged(key, value); 593 changed |= network->PropertyChanged(key, value);
592 if (!changed) 594 if (!changed)
593 return; 595 return;
594 596
595 if (key == shill::kStateProperty) { 597 if (key == shill::kStateProperty) {
(...skipping 28 matching lines...) Expand all
624 } else { 626 } else {
625 log_level = network_event_log::LOG_LEVEL_EVENT; 627 log_level = network_event_log::LOG_LEVEL_EVENT;
626 } 628 }
627 NET_LOG_LEVEL(log_level, log_event, detail); 629 NET_LOG_LEVEL(log_level, log_event, detail);
628 } 630 }
629 } 631 }
630 632
631 // All property updates signal 'NetworkPropertiesUpdated'. 633 // All property updates signal 'NetworkPropertiesUpdated'.
632 NotifyNetworkPropertiesUpdated(network); 634 NotifyNetworkPropertiesUpdated(network);
633 635
634 // If added to a Profile, request a full update so that a FavoriteState 636 // If added to a Profile, request a full update so that a NetworkState
635 // gets created. 637 // gets created.
636 if (prev_profile_path.empty() && !network->profile_path().empty()) 638 if (prev_profile_path.empty() && !network->profile_path().empty())
637 RequestUpdateForNetwork(service_path); 639 RequestUpdateForNetwork(service_path);
638 } 640 }
639 641
640 void NetworkStateHandler::UpdateDeviceProperty(const std::string& device_path, 642 void NetworkStateHandler::UpdateDeviceProperty(const std::string& device_path,
641 const std::string& key, 643 const std::string& key,
642 const base::Value& value) { 644 const base::Value& value) {
643 DeviceState* device = GetModifiableDeviceState(device_path); 645 DeviceState* device = GetModifiableDeviceState(device_path);
644 if (!device) 646 if (!device)
645 return; 647 return;
646 if (!device->PropertyChanged(key, value)) 648 if (!device->PropertyChanged(key, value))
647 return; 649 return;
648 650
649 std::string detail = device->name() + "." + key; 651 std::string detail = device->name() + "." + key;
650 detail += " = " + network_event_log::ValueAsString(value); 652 detail += " = " + network_event_log::ValueAsString(value);
651 NET_LOG_EVENT("DevicePropertyUpdated", detail); 653 NET_LOG_EVENT("DevicePropertyUpdated", detail);
652 654
653 NotifyDeviceListChanged(); 655 NotifyDeviceListChanged();
654 656
655 if (key == shill::kScanningProperty && device->scanning() == false) 657 if (key == shill::kScanningProperty && device->scanning() == false)
656 ScanCompleted(device->type()); 658 ScanCompleted(device->type());
657 if (key == shill::kEapAuthenticationCompletedProperty) { 659 if (key == shill::kEapAuthenticationCompletedProperty) {
658 // Notify a change for each Ethernet service using this device. 660 // Notify a change for each Ethernet service using this device.
659 NetworkStateList ethernet_services; 661 NetworkStateList ethernet_services;
660 GetNetworkListByType(NetworkTypePattern::Ethernet(), &ethernet_services); 662 GetNetworkListByType(NetworkTypePattern::Ethernet(),
663 false /* configured_only */,
664 false /* visible_only */,
665 1 /* limit */,
666 &ethernet_services);
661 for (NetworkStateList::const_iterator it = ethernet_services.begin(); 667 for (NetworkStateList::const_iterator it = ethernet_services.begin();
662 it != ethernet_services.end(); ++it) { 668 it != ethernet_services.end(); ++it) {
663 const NetworkState* ethernet_service = *it; 669 const NetworkState* ethernet_service = *it;
664 if (ethernet_service->update_received() || 670 if (ethernet_service->update_received() ||
665 ethernet_service->device_path() != device->path()) { 671 ethernet_service->device_path() != device->path()) {
666 continue; 672 continue;
667 } 673 }
668 RequestUpdateForNetwork(ethernet_service->path()); 674 RequestUpdateForNetwork(ethernet_service->path());
669 } 675 }
670 } 676 }
(...skipping 30 matching lines...) Expand all
701 707
702 void NetworkStateHandler::ManagedStateListChanged( 708 void NetworkStateHandler::ManagedStateListChanged(
703 ManagedState::ManagedType type) { 709 ManagedState::ManagedType type) {
704 if (type == ManagedState::MANAGED_TYPE_NETWORK) { 710 if (type == ManagedState::MANAGED_TYPE_NETWORK) {
705 // Notify observers that the list of networks has changed. 711 // Notify observers that the list of networks has changed.
706 NET_LOG_EVENT("NetworkListChanged", 712 NET_LOG_EVENT("NetworkListChanged",
707 base::StringPrintf("Size:%" PRIuS, network_list_.size())); 713 base::StringPrintf("Size:%" PRIuS, network_list_.size()));
708 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_, 714 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_,
709 NetworkListChanged()); 715 NetworkListChanged());
710 // Update UMA stats. 716 // Update UMA stats.
711 UMA_HISTOGRAM_COUNTS_100("Networks.Visible", network_list_.size()); 717 size_t shared = 0, unshared = 0, visible = 0;
712 } else if (type == ManagedState::MANAGED_TYPE_FAVORITE) { 718 for (ManagedStateList::iterator iter = network_list_.begin();
713 NET_LOG_DEBUG("FavoriteListChanged", 719 iter != network_list_.end(); ++iter) {
714 base::StringPrintf("Size:%" PRIuS, favorite_list_.size())); 720 NetworkState* network = (*iter)->AsNetworkState();
715 // The FavoriteState list only changes when the NetworkState list changes, 721 if (network->visible())
716 // so no need to signal observers here again. 722 ++visible;
717 723 if (network->IsInProfile()) {
718 // Update UMA stats. 724 if (network->IsPrivate())
719 size_t shared = 0, unshared = 0; 725 ++unshared;
720 for (ManagedStateList::iterator iter = favorite_list_.begin(); 726 else
721 iter != favorite_list_.end(); ++iter) { 727 ++shared;
722 FavoriteState* favorite = (*iter)->AsFavoriteState(); 728 }
723 if (!favorite->IsInProfile())
724 continue;
725 if (favorite->IsPrivate())
726 ++unshared;
727 else
728 ++shared;
729 } 729 }
730 UMA_HISTOGRAM_COUNTS_100("Networks.Visible", visible);
730 UMA_HISTOGRAM_COUNTS_100("Networks.RememberedShared", shared); 731 UMA_HISTOGRAM_COUNTS_100("Networks.RememberedShared", shared);
731 UMA_HISTOGRAM_COUNTS_100("Networks.RememberedUnshared", unshared); 732 UMA_HISTOGRAM_COUNTS_100("Networks.RememberedUnshared", unshared);
732 } else if (type == ManagedState::MANAGED_TYPE_DEVICE) { 733 } else if (type == ManagedState::MANAGED_TYPE_DEVICE) {
733 std::string devices; 734 std::string devices;
734 for (ManagedStateList::const_iterator iter = device_list_.begin(); 735 for (ManagedStateList::const_iterator iter = device_list_.begin();
735 iter != device_list_.end(); ++iter) { 736 iter != device_list_.end(); ++iter) {
736 if (iter != device_list_.begin()) 737 if (iter != device_list_.begin())
737 devices += ", "; 738 devices += ", ";
738 devices += (*iter)->name(); 739 devices += (*iter)->name();
739 } 740 }
740 NET_LOG_EVENT("DeviceList:", devices); 741 NET_LOG_EVENT("DeviceList", devices);
741 NotifyDeviceListChanged(); 742 NotifyDeviceListChanged();
742 } else { 743 } else {
743 NOTREACHED(); 744 NOTREACHED();
744 } 745 }
745 } 746 }
746 747
747 void NetworkStateHandler::DefaultNetworkServiceChanged( 748 void NetworkStateHandler::DefaultNetworkServiceChanged(
748 const std::string& service_path) { 749 const std::string& service_path) {
749 // Shill uses '/' for empty service path values; check explicitly for that. 750 // Shill uses '/' for empty service path values; check explicitly for that.
750 const char* kEmptyServicePath = "/"; 751 const char* kEmptyServicePath = "/";
(...skipping 17 matching lines...) Expand all
768 NET_LOG_ERROR( 769 NET_LOG_ERROR(
769 "DefaultNetwork is not connected: " + network->connection_state(), 770 "DefaultNetwork is not connected: " + network->connection_state(),
770 network->path()); 771 network->path());
771 } 772 }
772 NotifyDefaultNetworkChanged(network); 773 NotifyDefaultNetworkChanged(network);
773 } 774 }
774 775
775 //------------------------------------------------------------------------------ 776 //------------------------------------------------------------------------------
776 // Private methods 777 // Private methods
777 778
778 void NetworkStateHandler::UpdateGuid(ManagedState* managed) { 779 void NetworkStateHandler::UpdateGuid(NetworkState* network) {
779 if (managed->managed_type() == ManagedState::MANAGED_TYPE_FAVORITE) { 780 std::string specifier = network->GetSpecifier();
780 FavoriteState* favorite = managed->AsFavoriteState(); 781 if (!network->guid().empty()) {
781 std::string specifier = favorite->GetSpecifier(); 782 // If the network is saved in a profile, remove the entry from the map.
782 if (!favorite->guid().empty()) { 783 // Otherwise ensure that the entry matches the specified GUID.
783 // If the favorite is saved in a profile, remove the entry from the map. 784 if (network->IsInProfile())
784 // Otherwise ensure that the entry matches the specified GUID. 785 specifier_guid_map_.erase(specifier);
785 if (favorite->IsInProfile()) 786 else
786 specifier_guid_map_.erase(specifier); 787 specifier_guid_map_[specifier] = network->guid();
787 else 788 return;
788 specifier_guid_map_[specifier] = favorite->guid();
789 return;
790 }
791 // Ensure that the FavoriteState has a valid GUID.
792 std::string guid;
793 SpecifierGuidMap::iterator iter = specifier_guid_map_.find(specifier);
794 if (iter != specifier_guid_map_.end()) {
795 guid = iter->second;
796 } else {
797 guid = base::GenerateGUID();
798 specifier_guid_map_[specifier] = guid;
799 }
800 favorite->SetGuid(guid);
801 NetworkState* network = GetModifiableNetworkState(favorite->path());
802 if (network)
803 network->SetGuid(guid);
804 } else if (managed->managed_type() == ManagedState::MANAGED_TYPE_NETWORK) {
805 // If the GUID is not set and a corresponding FavoriteState exists, get the
806 // GUID from the FavoriteState. Otherwise it will get set when the Favorite
807 // is created.
808 NetworkState* network = managed->AsNetworkState();
809 if (!network->guid().empty())
810 return;
811 // ShillPropertyHandler will always call UpdateManagedStateProperties with
812 // type FAVORITE before type NETWORK, so there should always be a
813 // corresponding FavoriteState here.
814 FavoriteState* favorite = GetModifiableFavoriteState(network->path());
815 DCHECK(favorite);
816 if (favorite && !favorite->guid().empty())
817 network->SetGuid(favorite->guid());
818 } 789 }
790 // Ensure that the NetworkState has a valid GUID.
791 std::string guid;
792 SpecifierGuidMap::iterator iter = specifier_guid_map_.find(specifier);
793 if (iter != specifier_guid_map_.end()) {
794 guid = iter->second;
795 } else {
796 guid = base::GenerateGUID();
797 specifier_guid_map_[specifier] = guid;
798 }
799 network->SetGuid(guid);
819 } 800 }
820 801
821 void NetworkStateHandler::NotifyDeviceListChanged() { 802 void NetworkStateHandler::NotifyDeviceListChanged() {
822 NET_LOG_DEBUG("NotifyDeviceListChanged", 803 NET_LOG_DEBUG("NotifyDeviceListChanged",
823 base::StringPrintf("Size:%" PRIuS, device_list_.size())); 804 base::StringPrintf("Size:%" PRIuS, device_list_.size()));
824 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_, 805 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_,
825 DeviceListChanged()); 806 DeviceListChanged());
826 } 807 }
827 808
828 DeviceState* NetworkStateHandler::GetModifiableDeviceState( 809 DeviceState* NetworkStateHandler::GetModifiableDeviceState(
829 const std::string& device_path) const { 810 const std::string& device_path) const {
830 ManagedState* managed = GetModifiableManagedState(&device_list_, device_path); 811 ManagedState* managed = GetModifiableManagedState(&device_list_, device_path);
831 if (!managed) 812 if (!managed)
832 return NULL; 813 return NULL;
833 return managed->AsDeviceState(); 814 return managed->AsDeviceState();
834 } 815 }
835 816
836 NetworkState* NetworkStateHandler::GetModifiableNetworkState( 817 NetworkState* NetworkStateHandler::GetModifiableNetworkState(
837 const std::string& service_path) const { 818 const std::string& service_path) const {
838 ManagedState* managed = 819 ManagedState* managed =
839 GetModifiableManagedState(&network_list_, service_path); 820 GetModifiableManagedState(&network_list_, service_path);
840 if (!managed) 821 if (!managed)
841 return NULL; 822 return NULL;
842 return managed->AsNetworkState(); 823 return managed->AsNetworkState();
843 } 824 }
844 825
845 FavoriteState* NetworkStateHandler::GetModifiableFavoriteState(
846 const std::string& service_path) const {
847 ManagedState* managed =
848 GetModifiableManagedState(&favorite_list_, service_path);
849 if (!managed)
850 return NULL;
851 return managed->AsFavoriteState();
852 }
853
854 ManagedState* NetworkStateHandler::GetModifiableManagedState( 826 ManagedState* NetworkStateHandler::GetModifiableManagedState(
855 const ManagedStateList* managed_list, 827 const ManagedStateList* managed_list,
856 const std::string& path) const { 828 const std::string& path) const {
857 for (ManagedStateList::const_iterator iter = managed_list->begin(); 829 for (ManagedStateList::const_iterator iter = managed_list->begin();
858 iter != managed_list->end(); ++iter) { 830 iter != managed_list->end(); ++iter) {
859 ManagedState* managed = *iter; 831 ManagedState* managed = *iter;
860 if (managed->path() == path) 832 if (managed->path() == path)
861 return managed; 833 return managed;
862 } 834 }
863 return NULL; 835 return NULL;
864 } 836 }
865 837
866 NetworkStateHandler::ManagedStateList* NetworkStateHandler::GetManagedList( 838 NetworkStateHandler::ManagedStateList* NetworkStateHandler::GetManagedList(
867 ManagedState::ManagedType type) { 839 ManagedState::ManagedType type) {
868 switch (type) { 840 switch (type) {
869 case ManagedState::MANAGED_TYPE_NETWORK: 841 case ManagedState::MANAGED_TYPE_NETWORK:
870 return &network_list_; 842 return &network_list_;
871 case ManagedState::MANAGED_TYPE_FAVORITE:
872 return &favorite_list_;
873 case ManagedState::MANAGED_TYPE_DEVICE: 843 case ManagedState::MANAGED_TYPE_DEVICE:
874 return &device_list_; 844 return &device_list_;
875 } 845 }
876 NOTREACHED(); 846 NOTREACHED();
877 return NULL; 847 return NULL;
878 } 848 }
879 849
880 void NetworkStateHandler::OnNetworkConnectionStateChanged( 850 void NetworkStateHandler::OnNetworkConnectionStateChanged(
881 NetworkState* network) { 851 NetworkState* network) {
882 DCHECK(network); 852 DCHECK(network);
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
961 if (type.MatchesType(shill::kTypeBluetooth)) 931 if (type.MatchesType(shill::kTypeBluetooth))
962 technologies.push_back(new std::string(shill::kTypeBluetooth)); 932 technologies.push_back(new std::string(shill::kTypeBluetooth));
963 if (type.MatchesType(shill::kTypeVPN)) 933 if (type.MatchesType(shill::kTypeVPN))
964 technologies.push_back(new std::string(shill::kTypeVPN)); 934 technologies.push_back(new std::string(shill::kTypeVPN));
965 935
966 CHECK_GT(technologies.size(), 0ul); 936 CHECK_GT(technologies.size(), 0ul);
967 return technologies.Pass(); 937 return technologies.Pass();
968 } 938 }
969 939
970 } // namespace chromeos 940 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698