OLD | NEW |
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 <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
60 state->path().c_str()); | 60 state->path().c_str()); |
61 } | 61 } |
62 | 62 |
63 std::string ValueAsString(const base::Value& value) { | 63 std::string ValueAsString(const base::Value& value) { |
64 std::string vstr; | 64 std::string vstr; |
65 base::JSONWriter::WriteWithOptions( | 65 base::JSONWriter::WriteWithOptions( |
66 value, base::JSONWriter::OPTIONS_OMIT_BINARY_VALUES, &vstr); | 66 value, base::JSONWriter::OPTIONS_OMIT_BINARY_VALUES, &vstr); |
67 return vstr.empty() ? "''" : vstr; | 67 return vstr.empty() ? "''" : vstr; |
68 } | 68 } |
69 | 69 |
| 70 bool ShouldIncludeNetworkInList(const NetworkState* network_state, |
| 71 bool configured_only, |
| 72 bool visible_only, |
| 73 bool get_active) { |
| 74 if (configured_only && !network_state->IsInProfile()) |
| 75 return false; |
| 76 |
| 77 if (visible_only && !network_state->visible()) |
| 78 return false; |
| 79 |
| 80 bool is_network_active = |
| 81 network_state->IsConnectedState() || network_state->IsConnectingState(); |
| 82 if (is_network_active != get_active) |
| 83 return false; |
| 84 |
| 85 if (network_state->type() == shill::kTypeWifi && |
| 86 !network_state->tether_guid().empty()) { |
| 87 // Wi-Fi networks which are actually underlying Wi-Fi hotspots for a |
| 88 // Tether network should not be included since they should only be shown |
| 89 // to the user as Tether networks. |
| 90 return false; |
| 91 } |
| 92 |
| 93 return true; |
| 94 } |
| 95 |
70 } // namespace | 96 } // namespace |
71 | 97 |
72 const char NetworkStateHandler::kDefaultCheckPortalList[] = | 98 const char NetworkStateHandler::kDefaultCheckPortalList[] = |
73 "ethernet,wifi,cellular"; | 99 "ethernet,wifi,cellular"; |
74 | 100 |
75 NetworkStateHandler::NetworkStateHandler() {} | 101 NetworkStateHandler::NetworkStateHandler() {} |
76 | 102 |
77 NetworkStateHandler::~NetworkStateHandler() { | 103 NetworkStateHandler::~NetworkStateHandler() { |
78 // Normally Shutdown() will get called in ~NetworkHandler, however unit | 104 // Normally Shutdown() will get called in ~NetworkHandler, however unit |
79 // tests do not use that class so this needs to call Shutdown when we | 105 // tests do not use that class so this needs to call Shutdown when we |
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
407 true /* visible_only */, 0 /* no limit */, list); | 433 true /* visible_only */, 0 /* no limit */, list); |
408 } | 434 } |
409 | 435 |
410 void NetworkStateHandler::GetVisibleNetworkList(NetworkStateList* list) { | 436 void NetworkStateHandler::GetVisibleNetworkList(NetworkStateList* list) { |
411 GetVisibleNetworkListByType(NetworkTypePattern::Default(), list); | 437 GetVisibleNetworkListByType(NetworkTypePattern::Default(), list); |
412 } | 438 } |
413 | 439 |
414 void NetworkStateHandler::GetNetworkListByType(const NetworkTypePattern& type, | 440 void NetworkStateHandler::GetNetworkListByType(const NetworkTypePattern& type, |
415 bool configured_only, | 441 bool configured_only, |
416 bool visible_only, | 442 bool visible_only, |
417 int limit, | 443 size_t limit, |
418 NetworkStateList* list) { | 444 NetworkStateList* list) { |
419 DCHECK(list); | 445 DCHECK(list); |
420 list->clear(); | 446 list->clear(); |
421 | 447 |
422 // Sort the network list if necessary. | 448 // If |limit| is 0, there is no limit. Simplify the calculations below by |
| 449 // setting it to the maximum size_t value. |
| 450 if (limit == 0) |
| 451 limit = std::numeric_limits<size_t>::max(); |
| 452 |
423 if (!network_list_sorted_) | 453 if (!network_list_sorted_) |
424 SortNetworkList(); | 454 SortNetworkList(); |
425 | 455 |
| 456 // First, add active Tether networks. |
426 if (type.MatchesPattern(NetworkTypePattern::Tether())) | 457 if (type.MatchesPattern(NetworkTypePattern::Tether())) |
427 GetTetherNetworkList(limit, list); | 458 AppendTetherNetworksToList(true /* get_active */, limit, list); |
428 | 459 |
429 int count = list->size(); | 460 // Second, add active non-Tether networks. |
430 | 461 for (auto iter = network_list_.begin(); |
431 if (type.Equals(NetworkTypePattern::Tether()) || | 462 iter != network_list_.end() && list->size() < limit; ++iter) { |
432 (limit != 0 && count >= limit)) { | |
433 // If only searching for Tether networks, there is no need to continue | |
434 // searching through other network types; likewise, if the limit has already | |
435 // been reached, there is no need to continue searching. | |
436 return; | |
437 } | |
438 | |
439 for (auto iter = network_list_.begin(); iter != network_list_.end(); ++iter) { | |
440 const NetworkState* network = (*iter)->AsNetworkState(); | 463 const NetworkState* network = (*iter)->AsNetworkState(); |
441 DCHECK(network); | 464 DCHECK(network); |
442 if (!network->update_received() || !network->Matches(type)) | 465 if (!network->update_received() || !network->Matches(type)) |
443 continue; | 466 continue; |
444 if (configured_only && !network->IsInProfile()) | 467 if (!ShouldIncludeNetworkInList(network, configured_only, visible_only, |
| 468 true /* get_active */)) { |
445 continue; | 469 continue; |
446 if (visible_only && !network->visible()) | 470 } |
447 continue; | |
448 if (network->type() == shill::kTypeEthernet) { | 471 if (network->type() == shill::kTypeEthernet) { |
449 // Ethernet networks should always be in front. | 472 // Ethernet networks should always be in front. |
450 list->insert(list->begin(), network); | 473 list->insert(list->begin(), network); |
451 } else { | 474 } else { |
452 list->push_back(network); | 475 list->push_back(network); |
453 } | 476 } |
454 if (limit > 0 && ++count >= limit) | 477 } |
455 break; | 478 |
| 479 // Third, add inactive Tether networks. |
| 480 if (type.MatchesPattern(NetworkTypePattern::Tether())) |
| 481 AppendTetherNetworksToList(false /* get_active */, limit, list); |
| 482 |
| 483 // Fourth, add inactive non-Tether networks. |
| 484 for (auto iter = network_list_.begin(); |
| 485 iter != network_list_.end() && list->size() < limit; ++iter) { |
| 486 const NetworkState* network = (*iter)->AsNetworkState(); |
| 487 DCHECK(network); |
| 488 if (!network->update_received() || !network->Matches(type)) |
| 489 continue; |
| 490 if (!ShouldIncludeNetworkInList(network, configured_only, visible_only, |
| 491 false /* get_active */)) { |
| 492 continue; |
| 493 } |
| 494 list->push_back(network); |
456 } | 495 } |
457 } | 496 } |
458 | 497 |
459 void NetworkStateHandler::GetTetherNetworkList(int limit, | 498 void NetworkStateHandler::AppendTetherNetworksToList(bool get_active, |
460 NetworkStateList* list) { | 499 size_t limit, |
| 500 NetworkStateList* list) { |
461 DCHECK(list); | 501 DCHECK(list); |
462 list->clear(); | 502 DCHECK(limit != 0); |
463 | |
464 if (!IsTechnologyEnabled(NetworkTypePattern::Tether())) | 503 if (!IsTechnologyEnabled(NetworkTypePattern::Tether())) |
465 return; | 504 return; |
466 | 505 |
467 int count = 0; | |
468 for (auto iter = tether_network_list_.begin(); | 506 for (auto iter = tether_network_list_.begin(); |
469 iter != tether_network_list_.end(); ++iter) { | 507 iter != tether_network_list_.end() && list->size() < limit; ++iter) { |
470 list->push_back((*iter)->AsNetworkState()); | 508 const NetworkState* network = (*iter)->AsNetworkState(); |
471 if (limit > 0 && ++count >= limit) | 509 DCHECK(network); |
472 return; | 510 |
| 511 if (!ShouldIncludeNetworkInList(network, false /* configured_only */, |
| 512 false /* visible_only */, get_active)) { |
| 513 continue; |
| 514 } |
| 515 |
| 516 list->push_back(network); |
473 } | 517 } |
474 } | 518 } |
475 | 519 |
476 const NetworkState* NetworkStateHandler::GetNetworkStateFromServicePath( | 520 const NetworkState* NetworkStateHandler::GetNetworkStateFromServicePath( |
477 const std::string& service_path, | 521 const std::string& service_path, |
478 bool configured_only) const { | 522 bool configured_only) const { |
479 ManagedState* managed = | 523 ManagedState* managed = |
480 GetModifiableManagedState(&network_list_, service_path); | 524 GetModifiableManagedState(&network_list_, service_path); |
481 if (!managed) { | 525 if (!managed) { |
482 managed = GetModifiableManagedState(&tether_network_list_, service_path); | 526 managed = GetModifiableManagedState(&tether_network_list_, service_path); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
531 tether_network_state->set_visible(true); | 575 tether_network_state->set_visible(true); |
532 tether_network_state->set_update_received(); | 576 tether_network_state->set_update_received(); |
533 tether_network_state->set_update_requested(false); | 577 tether_network_state->set_update_requested(false); |
534 tether_network_state->set_connectable(true); | 578 tether_network_state->set_connectable(true); |
535 tether_network_state->set_carrier(carrier); | 579 tether_network_state->set_carrier(carrier); |
536 tether_network_state->set_battery_percentage(battery_percentage); | 580 tether_network_state->set_battery_percentage(battery_percentage); |
537 tether_network_state->set_tether_has_connected_to_host(has_connected_to_host); | 581 tether_network_state->set_tether_has_connected_to_host(has_connected_to_host); |
538 tether_network_state->set_signal_strength(signal_strength); | 582 tether_network_state->set_signal_strength(signal_strength); |
539 | 583 |
540 tether_network_list_.push_back(std::move(tether_network_state)); | 584 tether_network_list_.push_back(std::move(tether_network_state)); |
| 585 network_list_sorted_ = false; |
| 586 |
541 NotifyNetworkListChanged(); | 587 NotifyNetworkListChanged(); |
542 } | 588 } |
543 | 589 |
544 bool NetworkStateHandler::UpdateTetherNetworkProperties( | 590 bool NetworkStateHandler::UpdateTetherNetworkProperties( |
545 const std::string& guid, | 591 const std::string& guid, |
546 const std::string& carrier, | 592 const std::string& carrier, |
547 int battery_percentage, | 593 int battery_percentage, |
548 int signal_strength) { | 594 int signal_strength) { |
549 if (tether_technology_state_ != TECHNOLOGY_ENABLED) { | 595 if (tether_technology_state_ != TECHNOLOGY_ENABLED) { |
550 NET_LOG(ERROR) << "UpdateTetherNetworkProperties() called when Tether " | 596 NET_LOG(ERROR) << "UpdateTetherNetworkProperties() called when Tether " |
551 << "networks are not enabled. Cannot update."; | 597 << "networks are not enabled. Cannot update."; |
552 return false; | 598 return false; |
553 } | 599 } |
554 | 600 |
555 NetworkState* tether_network_state = GetModifiableNetworkStateFromGuid(guid); | 601 NetworkState* tether_network_state = GetModifiableNetworkStateFromGuid(guid); |
556 if (!tether_network_state) { | 602 if (!tether_network_state) { |
557 NET_LOG(ERROR) << "UpdateTetherNetworkProperties(): No NetworkState for " | 603 NET_LOG(ERROR) << "UpdateTetherNetworkProperties(): No NetworkState for " |
558 << "Tether network with GUID \"" << guid << "\"."; | 604 << "Tether network with GUID \"" << guid << "\"."; |
559 return false; | 605 return false; |
560 } | 606 } |
561 | 607 |
562 tether_network_state->set_carrier(carrier); | 608 tether_network_state->set_carrier(carrier); |
563 tether_network_state->set_battery_percentage(battery_percentage); | 609 tether_network_state->set_battery_percentage(battery_percentage); |
564 tether_network_state->set_signal_strength(signal_strength); | 610 tether_network_state->set_signal_strength(signal_strength); |
| 611 network_list_sorted_ = false; |
565 | 612 |
566 NotifyNetworkPropertiesUpdated(tether_network_state); | 613 NotifyNetworkPropertiesUpdated(tether_network_state); |
567 return true; | 614 return true; |
568 } | 615 } |
569 | 616 |
570 bool NetworkStateHandler::SetTetherNetworkHasConnectedToHost( | 617 bool NetworkStateHandler::SetTetherNetworkHasConnectedToHost( |
571 const std::string& guid) { | 618 const std::string& guid) { |
572 NetworkState* tether_network_state = GetModifiableNetworkStateFromGuid(guid); | 619 NetworkState* tether_network_state = GetModifiableNetworkStateFromGuid(guid); |
573 if (!tether_network_state) { | 620 if (!tether_network_state) { |
574 NET_LOG(ERROR) << "SetTetherNetworkHasConnectedToHost(): No NetworkState " | 621 NET_LOG(ERROR) << "SetTetherNetworkHasConnectedToHost(): No NetworkState " |
575 << "for Tether network with GUID \"" << guid << "\"."; | 622 << "for Tether network with GUID \"" << guid << "\"."; |
576 return false; | 623 return false; |
577 } | 624 } |
578 | 625 |
579 if (tether_network_state->tether_has_connected_to_host()) { | 626 if (tether_network_state->tether_has_connected_to_host()) { |
580 return false; | 627 return false; |
581 } | 628 } |
582 | 629 |
583 tether_network_state->set_tether_has_connected_to_host(true); | 630 tether_network_state->set_tether_has_connected_to_host(true); |
| 631 network_list_sorted_ = false; |
584 | 632 |
585 NotifyNetworkPropertiesUpdated(tether_network_state); | 633 NotifyNetworkPropertiesUpdated(tether_network_state); |
586 return true; | 634 return true; |
587 } | 635 } |
588 | 636 |
589 bool NetworkStateHandler::RemoveTetherNetworkState(const std::string& guid) { | 637 bool NetworkStateHandler::RemoveTetherNetworkState(const std::string& guid) { |
590 for (auto iter = tether_network_list_.begin(); | 638 for (auto iter = tether_network_list_.begin(); |
591 iter != tether_network_list_.end(); ++iter) { | 639 iter != tether_network_list_.end(); ++iter) { |
592 if (iter->get()->AsNetworkState()->guid() == guid) { | 640 if (iter->get()->AsNetworkState()->guid() == guid) { |
593 NetworkState* wifi_network = GetModifiableNetworkStateFromGuid( | 641 NetworkState* wifi_network = GetModifiableNetworkStateFromGuid( |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
627 return false; | 675 return false; |
628 } | 676 } |
629 | 677 |
630 if (wifi_network_state->tether_guid().empty() && | 678 if (wifi_network_state->tether_guid().empty() && |
631 tether_network_state->tether_guid().empty()) { | 679 tether_network_state->tether_guid().empty()) { |
632 return true; | 680 return true; |
633 } | 681 } |
634 | 682 |
635 wifi_network_state->set_tether_guid(std::string()); | 683 wifi_network_state->set_tether_guid(std::string()); |
636 tether_network_state->set_tether_guid(std::string()); | 684 tether_network_state->set_tether_guid(std::string()); |
| 685 network_list_sorted_ = false; |
637 | 686 |
638 NotifyNetworkPropertiesUpdated(wifi_network_state); | 687 NotifyNetworkPropertiesUpdated(wifi_network_state); |
639 NotifyNetworkPropertiesUpdated(tether_network_state); | 688 NotifyNetworkPropertiesUpdated(tether_network_state); |
640 | 689 |
641 return true; | 690 return true; |
642 } | 691 } |
643 | 692 |
644 bool NetworkStateHandler::AssociateTetherNetworkStateWithWifiNetwork( | 693 bool NetworkStateHandler::AssociateTetherNetworkStateWithWifiNetwork( |
645 const std::string& tether_network_guid, | 694 const std::string& tether_network_guid, |
646 const std::string& wifi_network_guid) { | 695 const std::string& wifi_network_guid) { |
(...skipping 27 matching lines...) Expand all Loading... |
674 return false; | 723 return false; |
675 } | 724 } |
676 | 725 |
677 if (wifi_network_state->tether_guid() == tether_network_guid && | 726 if (wifi_network_state->tether_guid() == tether_network_guid && |
678 tether_network_state->tether_guid() == wifi_network_guid) { | 727 tether_network_state->tether_guid() == wifi_network_guid) { |
679 return true; | 728 return true; |
680 } | 729 } |
681 | 730 |
682 tether_network_state->set_tether_guid(wifi_network_guid); | 731 tether_network_state->set_tether_guid(wifi_network_guid); |
683 wifi_network_state->set_tether_guid(tether_network_guid); | 732 wifi_network_state->set_tether_guid(tether_network_guid); |
| 733 network_list_sorted_ = false; |
684 | 734 |
685 NotifyNetworkPropertiesUpdated(wifi_network_state); | 735 NotifyNetworkPropertiesUpdated(wifi_network_state); |
686 NotifyNetworkPropertiesUpdated(tether_network_state); | 736 NotifyNetworkPropertiesUpdated(tether_network_state); |
687 | 737 |
688 return true; | 738 return true; |
689 } | 739 } |
690 | 740 |
691 void NetworkStateHandler::SetTetherNetworkStateDisconnected( | 741 void NetworkStateHandler::SetTetherNetworkStateDisconnected( |
692 const std::string& guid) { | 742 const std::string& guid) { |
693 SetTetherNetworkStateConnectionState(guid, shill::kStateDisconnect); | 743 SetTetherNetworkStateConnectionState(guid, shill::kStateDisconnect); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
732 NET_LOG(ERROR) << "SetTetherNetworkStateConnectionState: Tether network " | 782 NET_LOG(ERROR) << "SetTetherNetworkStateConnectionState: Tether network " |
733 << "not found: " << guid; | 783 << "not found: " << guid; |
734 return; | 784 return; |
735 } | 785 } |
736 | 786 |
737 DCHECK( | 787 DCHECK( |
738 NetworkTypePattern::Tether().MatchesType(tether_network_state->type())); | 788 NetworkTypePattern::Tether().MatchesType(tether_network_state->type())); |
739 | 789 |
740 std::string prev_connection_state = tether_network_state->connection_state(); | 790 std::string prev_connection_state = tether_network_state->connection_state(); |
741 tether_network_state->set_connection_state(connection_state); | 791 tether_network_state->set_connection_state(connection_state); |
| 792 network_list_sorted_ = false; |
| 793 |
742 DCHECK(!tether_network_state->is_captive_portal()); | 794 DCHECK(!tether_network_state->is_captive_portal()); |
743 | |
744 if (ConnectionStateChanged(tether_network_state, prev_connection_state, | 795 if (ConnectionStateChanged(tether_network_state, prev_connection_state, |
745 false /* prev_is_captive_portal */)) { | 796 false /* prev_is_captive_portal */)) { |
746 NET_LOG(EVENT) << "Changing connection state for Tether network with GUID " | 797 NET_LOG(EVENT) << "Changing connection state for Tether network with GUID " |
747 << guid << ". Old state: " << prev_connection_state << ", " | 798 << guid << ". Old state: " << prev_connection_state << ", " |
748 << "New state: " << connection_state; | 799 << "New state: " << connection_state; |
749 | 800 |
750 OnNetworkConnectionStateChanged(tether_network_state); | 801 OnNetworkConnectionStateChanged(tether_network_state); |
751 NotifyNetworkPropertiesUpdated(tether_network_state); | 802 NotifyNetworkPropertiesUpdated(tether_network_state); |
752 } | 803 } |
753 } | 804 } |
(...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1200 devices += ", "; | 1251 devices += ", "; |
1201 devices += (*iter)->name(); | 1252 devices += (*iter)->name(); |
1202 } | 1253 } |
1203 NET_LOG_EVENT("DeviceList", devices); | 1254 NET_LOG_EVENT("DeviceList", devices); |
1204 NotifyDeviceListChanged(); | 1255 NotifyDeviceListChanged(); |
1205 } else { | 1256 } else { |
1206 NOTREACHED(); | 1257 NOTREACHED(); |
1207 } | 1258 } |
1208 } | 1259 } |
1209 | 1260 |
1210 // TODO(khorimoto): Add sorting for the Tether network list as well. | |
1211 void NetworkStateHandler::SortNetworkList() { | 1261 void NetworkStateHandler::SortNetworkList() { |
| 1262 if (tether_sort_delegate_) |
| 1263 tether_sort_delegate_->SortTetherNetworkList(&tether_network_list_); |
| 1264 |
1212 // Note: usually active networks will precede inactive networks, however | 1265 // Note: usually active networks will precede inactive networks, however |
1213 // this may briefly be untrue during state transitions (e.g. a network may | 1266 // this may briefly be untrue during state transitions (e.g. a network may |
1214 // transition to idle before the list is updated). | 1267 // transition to idle before the list is updated). |
1215 ManagedStateList active, non_wifi_visible, wifi_visible, hidden, new_networks; | 1268 ManagedStateList active, non_wifi_visible, wifi_visible, hidden, new_networks; |
1216 for (ManagedStateList::iterator iter = network_list_.begin(); | 1269 for (ManagedStateList::iterator iter = network_list_.begin(); |
1217 iter != network_list_.end(); ++iter) { | 1270 iter != network_list_.end(); ++iter) { |
1218 NetworkState* network = (*iter)->AsNetworkState(); | 1271 NetworkState* network = (*iter)->AsNetworkState(); |
1219 if (!network->update_received()) { | 1272 if (!network->update_received()) { |
1220 new_networks.push_back(std::move(*iter)); | 1273 new_networks.push_back(std::move(*iter)); |
1221 continue; | 1274 continue; |
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1542 if (type.MatchesType(shill::kTypeVPN)) | 1595 if (type.MatchesType(shill::kTypeVPN)) |
1543 technologies.emplace_back(shill::kTypeVPN); | 1596 technologies.emplace_back(shill::kTypeVPN); |
1544 if (type.MatchesType(kTypeTether)) | 1597 if (type.MatchesType(kTypeTether)) |
1545 technologies.emplace_back(kTypeTether); | 1598 technologies.emplace_back(kTypeTether); |
1546 | 1599 |
1547 CHECK_GT(technologies.size(), 0ul); | 1600 CHECK_GT(technologies.size(), 0ul); |
1548 return technologies; | 1601 return technologies; |
1549 } | 1602 } |
1550 | 1603 |
1551 } // namespace chromeos | 1604 } // namespace chromeos |
OLD | NEW |