network_state_handler.cc revision 5c02ac1a9c1b504631c0a3d2b6e737b5d738bae1
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromeos/network/network_state_handler.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/bind.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/format_macros.h"
97d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/location.h"
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/logging.h"
11424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "base/metrics/histogram.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h"
13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromeos/network/device_state.h"
17eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chromeos/network/favorite_state.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromeos/network/managed_state.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chromeos/network/network_event_log.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromeos/network/network_state.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromeos/network/network_state_handler_observer.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromeos/network/shill_property_handler.h"
2358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chromeos/network/shill_property_util.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/cros_system_api/dbus/service_constants.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
262385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochnamespace chromeos {
272385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
302385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochbool ConnectionStateChanged(NetworkState* network,
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                            const std::string& prev_connection_state) {
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return (network->connection_state() != prev_connection_state) &&
3368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)         (network->connection_state() != shill::kStateIdle ||
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          !prev_connection_state.empty());
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
372385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochstd::string GetManagedStateLogType(const ManagedState* state) {
382385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  switch (state->managed_type()) {
392385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    case ManagedState::MANAGED_TYPE_NETWORK:
402385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      return "Network";
412385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    case ManagedState::MANAGED_TYPE_FAVORITE:
422385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      return "Favorite";
432385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    case ManagedState::MANAGED_TYPE_DEVICE:
442385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      return "Device";
452385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  }
462385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  NOTREACHED();
472385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  return "";
482385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
492385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
502385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochstd::string GetManagedStateLogName(const ManagedState* state) {
5190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!state)
5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return "None";
5390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return base::StringPrintf("%s (%s)", state->name().c_str(),
5490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                            state->path().c_str());
5590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
59868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const char NetworkStateHandler::kDefaultCheckPortalList[] =
60868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    "ethernet,wifi,cellular";
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NetworkStateHandler::NetworkStateHandler() {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NetworkStateHandler::~NetworkStateHandler() {
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  STLDeleteContainerPointers(network_list_.begin(), network_list_.end());
67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  STLDeleteContainerPointers(favorite_list_.begin(), favorite_list_.end());
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  STLDeleteContainerPointers(device_list_.begin(), device_list_.end());
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NetworkStateHandler::InitShillPropertyHandler() {
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  shill_property_handler_.reset(new internal::ShillPropertyHandler(this));
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  shill_property_handler_->Init();
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
7790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)NetworkStateHandler* NetworkStateHandler::InitializeForTest() {
7890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  NetworkStateHandler* handler = new NetworkStateHandler();
7990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  handler->InitShillPropertyHandler();
8090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return handler;
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void NetworkStateHandler::AddObserver(
847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    NetworkStateHandlerObserver* observer,
857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const tracked_objects::Location& from_here) {
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  observers_.AddObserver(observer);
877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  network_event_log::internal::AddEntry(
887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      from_here.file_name(), from_here.line_number(),
897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      network_event_log::LOG_LEVEL_DEBUG,
907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      "NetworkStateHandler::AddObserver", "");
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NetworkStateHandler::RemoveObserver(
947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    NetworkStateHandlerObserver* observer,
957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const tracked_objects::Location& from_here) {
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  observers_.RemoveObserver(observer);
977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  network_event_log::internal::AddEntry(
987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      from_here.file_name(), from_here.line_number(),
997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      network_event_log::LOG_LEVEL_DEBUG,
1007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      "NetworkStateHandler::RemoveObserver", "");
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid NetworkStateHandler::UpdateManagerProperties() {
104eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  NET_LOG_USER("UpdateManagerProperties", "");
105eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  shill_property_handler_->UpdateManagerProperties();
106eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
107eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)NetworkStateHandler::TechnologyState NetworkStateHandler::GetTechnologyState(
10958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const NetworkTypePattern& type) const {
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string technology = GetTechnologyForType(type);
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TechnologyState state;
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (shill_property_handler_->IsTechnologyEnabled(technology))
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    state = TECHNOLOGY_ENABLED;
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  else if (shill_property_handler_->IsTechnologyEnabling(technology))
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    state = TECHNOLOGY_ENABLING;
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  else if (shill_property_handler_->IsTechnologyUninitialized(technology))
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    state = TECHNOLOGY_UNINITIALIZED;
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  else if (shill_property_handler_->IsTechnologyAvailable(technology))
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    state = TECHNOLOGY_AVAILABLE;
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  else
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    state = TECHNOLOGY_UNAVAILABLE;
12258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  VLOG(2) << "GetTechnologyState: " << type.ToDebugString() << " = " << state;
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return state;
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NetworkStateHandler::SetTechnologyEnabled(
12758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const NetworkTypePattern& type,
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool enabled,
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const network_handler::ErrorCallback& error_callback) {
1305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  ScopedVector<std::string> technologies = GetTechnologiesForType(type);
1315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  for (ScopedVector<std::string>::iterator it = technologies.begin();
1325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      it != technologies.end(); ++it) {
1335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    std::string* technology = *it;
1345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    DCHECK(technology);
1355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    NET_LOG_USER("SetTechnologyEnabled",
1365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                 base::StringPrintf("%s:%d", technology->c_str(), enabled));
1375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    shill_property_handler_->SetTechnologyEnabled(
1385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        *technology, enabled, error_callback);
1395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
140d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Signal Device/Technology state changed.
141d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  NotifyDeviceListChanged();
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const DeviceState* NetworkStateHandler::GetDeviceState(
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& device_path) const {
14658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  const DeviceState* device = GetModifiableDeviceState(device_path);
1474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (device && !device->update_received())
1484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return NULL;
14958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return device;
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const DeviceState* NetworkStateHandler::GetDeviceStateByType(
15358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const NetworkTypePattern& type) const {
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ManagedStateList::const_iterator iter = device_list_.begin();
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       iter != device_list_.end(); ++iter) {
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ManagedState* device = *iter;
15758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (!device->update_received())
15858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      continue;
15958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (device->Matches(type))
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return device->AsDeviceState();
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool NetworkStateHandler::GetScanningByType(
16658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const NetworkTypePattern& type) const {
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (ManagedStateList::const_iterator iter = device_list_.begin();
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       iter != device_list_.end(); ++iter) {
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const DeviceState* device = (*iter)->AsDeviceState();
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(device);
17158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (!device->update_received())
17258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      continue;
17358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (device->Matches(type) && device->scanning())
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return true;
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const NetworkState* NetworkStateHandler::GetNetworkState(
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& service_path) const {
18158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  const NetworkState* network = GetModifiableNetworkState(service_path);
1824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (network && !network->update_received())
1834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return NULL;
18458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return network;
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const NetworkState* NetworkStateHandler::DefaultNetwork() const {
188a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (default_network_path_.empty())
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
190a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return GetNetworkState(default_network_path_);
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const FavoriteState* NetworkStateHandler::DefaultFavoriteNetwork() const {
1944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const NetworkState* default_network = DefaultNetwork();
1954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!default_network)
1964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return NULL;
1974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const FavoriteState* default_favorite =
1984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      GetFavoriteState(default_network->path());
199a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(default_network->type() != shill::kTypeWifi ||
200a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)         default_favorite) << "No favorite for: " << default_network->path();
201a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(!default_favorite || default_favorite->update_received())
202a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      << "No update received for: " << default_network->path();
2034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return default_favorite;
2044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const NetworkState* NetworkStateHandler::ConnectedNetworkByType(
20758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const NetworkTypePattern& type) const {
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ManagedStateList::const_iterator iter = network_list_.begin();
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       iter != network_list_.end(); ++iter) {
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const NetworkState* network = (*iter)->AsNetworkState();
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(network);
21258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (!network->update_received())
21358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      continue;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!network->IsConnectedState())
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;  // Connected networks are listed first.
21658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (network->Matches(type))
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return network;
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const NetworkState* NetworkStateHandler::ConnectingNetworkByType(
22358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const NetworkTypePattern& type) const {
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ManagedStateList::const_iterator iter = network_list_.begin();
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       iter != network_list_.end(); ++iter) {
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const NetworkState* network = (*iter)->AsNetworkState();
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(network);
22858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (!network->update_received() || network->IsConnectedState())
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!network->IsConnectingState())
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;  // Connected and connecting networks are listed first.
23258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (network->Matches(type))
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return network;
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return NULL;
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const NetworkState* NetworkStateHandler::FirstNetworkByType(
23958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const NetworkTypePattern& type) const {
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (ManagedStateList::const_iterator iter = network_list_.begin();
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       iter != network_list_.end(); ++iter) {
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const NetworkState* network = (*iter)->AsNetworkState();
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(network);
24458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (!network->update_received())
24558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      continue;
24658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (network->Matches(type))
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return network;
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)std::string NetworkStateHandler::FormattedHardwareAddressForType(
25358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const NetworkTypePattern& type) const {
254f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const DeviceState* device = NULL;
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const NetworkState* network = ConnectedNetworkByType(type);
256f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (network)
257f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    device = GetDeviceState(network->device_path());
258f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  else
259f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    device = GetDeviceStateByType(type);
26058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!device)
26158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return std::string();
2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return device->GetFormattedMacAddress();
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NetworkStateHandler::GetNetworkList(NetworkStateList* list) const {
26658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  GetNetworkListByType(NetworkTypePattern::Default(), list);
267424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
268424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
26958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void NetworkStateHandler::GetNetworkListByType(const NetworkTypePattern& type,
270424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                                               NetworkStateList* list) const {
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(list);
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  list->clear();
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ManagedStateList::const_iterator iter = network_list_.begin();
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       iter != network_list_.end(); ++iter) {
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const NetworkState* network = (*iter)->AsNetworkState();
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(network);
2774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (network->update_received() && network->Matches(type))
278424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      list->push_back(network);
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid NetworkStateHandler::GetDeviceList(DeviceStateList* list) const {
2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GetDeviceListByType(NetworkTypePattern::Default(), list);
2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void NetworkStateHandler::GetDeviceListByType(const NetworkTypePattern& type,
2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                              DeviceStateList* list) const {
2887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(list);
2897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  list->clear();
2907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  for (ManagedStateList::const_iterator iter = device_list_.begin();
2917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch       iter != device_list_.end(); ++iter) {
2927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const DeviceState* device = (*iter)->AsDeviceState();
2937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    DCHECK(device);
2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (device->update_received() && device->Matches(type))
2954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      list->push_back(device);
2967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
2977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
2987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
299eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid NetworkStateHandler::GetFavoriteList(FavoriteStateList* list) const {
3004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  GetFavoriteListByType(NetworkTypePattern::Default(), list);
3014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
3024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void NetworkStateHandler::GetFavoriteListByType(const NetworkTypePattern& type,
3044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                                FavoriteStateList* list) const {
305eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DCHECK(list);
306eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  FavoriteStateList result;
307eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  list->clear();
308eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  for (ManagedStateList::const_iterator iter = favorite_list_.begin();
309eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch       iter != favorite_list_.end(); ++iter) {
310eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const FavoriteState* favorite = (*iter)->AsFavoriteState();
311eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    DCHECK(favorite);
312effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    if (favorite->update_received() && favorite->IsFavorite() &&
3134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        favorite->Matches(type)) {
314eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      list->push_back(favorite);
3154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
316eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
317eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
318eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
319eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochconst FavoriteState* NetworkStateHandler::GetFavoriteState(
320eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const std::string& service_path) const {
321eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ManagedState* managed =
322eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      GetModifiableManagedState(&favorite_list_, service_path);
323eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!managed)
324eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return NULL;
3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const FavoriteState* favorite = managed->AsFavoriteState();
3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(favorite);
327effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (!favorite->update_received() || !favorite->IsFavorite())
3284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return NULL;
3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return favorite;
330eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
331eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NetworkStateHandler::RequestScan() const {
333868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NET_LOG_USER("RequestScan", "");
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  shill_property_handler_->RequestScan();
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void NetworkStateHandler::WaitForScan(const std::string& type,
338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                      const base::Closure& callback) {
339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scan_complete_callbacks_[type].push_back(callback);
34058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!GetScanningByType(NetworkTypePattern::Primitive(type)))
341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    RequestScan();
342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void NetworkStateHandler::ConnectToBestWifiNetwork() {
345868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NET_LOG_USER("ConnectToBestWifiNetwork", "");
34668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  WaitForScan(shill::kTypeWifi,
347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              base::Bind(&internal::ShillPropertyHandler::ConnectToBestServices,
348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         shill_property_handler_->AsWeakPtr()));
349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void NetworkStateHandler::RequestUpdateForNetwork(
35290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const std::string& service_path) {
35390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  NetworkState* network = GetModifiableNetworkState(service_path);
3543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (network)
3553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    network->set_update_requested(true);
35690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  NET_LOG_EVENT("RequestUpdate", service_path);
35790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  shill_property_handler_->RequestProperties(
35890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      ManagedState::MANAGED_TYPE_NETWORK, service_path);
35990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
36090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
361a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void NetworkStateHandler::ClearLastErrorForNetwork(
362a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const std::string& service_path) {
363a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  NetworkState* network = GetModifiableNetworkState(service_path);
364a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (network)
365a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    network->clear_last_error();
366a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
367a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
368868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void NetworkStateHandler::SetCheckPortalList(
369868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const std::string& check_portal_list) {
370868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NET_LOG_EVENT("SetCheckPortalList", check_portal_list);
371868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  shill_property_handler_->SetCheckPortalList(check_portal_list);
372868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
373868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const FavoriteState* NetworkStateHandler::GetEAPForEthernet(
3754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const std::string& service_path) const {
3764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const NetworkState* network = GetNetworkState(service_path);
3774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!network) {
3784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    NET_LOG_ERROR("GetEAPForEthernet", "Unknown service path " + service_path);
3794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return NULL;
3804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
3814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (network->type() != shill::kTypeEthernet) {
3824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    NET_LOG_ERROR("GetEAPForEthernet", "Not of type Ethernet: " + service_path);
3834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return NULL;
3844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
3854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!network->IsConnectedState())
3864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return NULL;
3874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // The same EAP service is shared for all ethernet services/devices.
3894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // However EAP is used/enabled per device and only if the connection was
3904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // successfully established.
3914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const DeviceState* device = GetDeviceState(network->device_path());
3924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!device) {
3934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    NET_LOG_ERROR(
3944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        "GetEAPForEthernet",
3954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        base::StringPrintf("Unknown device %s of connected ethernet service %s",
3964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                           network->device_path().c_str(),
3974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                           service_path.c_str()));
3984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return NULL;
3994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
4004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!device->eap_authentication_completed())
4014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return NULL;
4024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  FavoriteStateList list;
4044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  GetFavoriteListByType(NetworkTypePattern::Primitive(shill::kTypeEthernetEap),
4054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                        &list);
4064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (list.empty()) {
4074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    NET_LOG_ERROR("GetEAPForEthernet",
4084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                  base::StringPrintf(
4094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                      "Ethernet service %s connected using EAP, but no "
4104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                      "EAP service found.",
4114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                      service_path.c_str()));
4124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return NULL;
4134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
4144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(list.size() == 1);
4154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return list.front();
4164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
4174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void NetworkStateHandler::GetNetworkStatePropertiesForTest(
419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    base::DictionaryValue* dictionary) const {
420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (ManagedStateList::const_iterator iter = network_list_.begin();
421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       iter != network_list_.end(); ++iter) {
422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    base::DictionaryValue* network_dict = new base::DictionaryValue;
423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    (*iter)->AsNetworkState()->GetProperties(network_dict);
424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    dictionary->SetWithoutPathExpansion((*iter)->path(), network_dict);
425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//------------------------------------------------------------------------------
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ShillPropertyHandler::Delegate overrides
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NetworkStateHandler::UpdateManagedList(ManagedState::ManagedType type,
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            const base::ListValue& entries) {
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ManagedStateList* managed_list = GetManagedList(type);
434eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  NET_LOG_DEBUG(base::StringPrintf("UpdateManagedList:%d", type),
435a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                base::StringPrintf("%" PRIuS, entries.GetSize()));
4367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Create a map of existing entries. Assumes all entries in |managed_list|
4377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // are unique.
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::map<std::string, ManagedState*> managed_map;
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ManagedStateList::iterator iter = managed_list->begin();
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       iter != managed_list->end(); ++iter) {
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ManagedState* managed = *iter;
4427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    DCHECK(!ContainsKey(managed_map, managed->path()));
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    managed_map[managed->path()] = managed;
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Clear the list (pointers are temporarily owned by managed_map).
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  managed_list->clear();
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Updates managed_list and request updates for new entries.
4487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  std::set<std::string> list_entries;
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (base::ListValue::const_iterator iter = entries.begin();
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       iter != entries.end(); ++iter) {
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string path;
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (*iter)->GetAsString(&path);
453a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (path.empty() || path == shill::kFlimflamServicePath) {
454a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      NET_LOG_ERROR(base::StringPrintf("Bad path in list:%d", type), path);
4557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      continue;
4567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    }
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::map<std::string, ManagedState*>::iterator found =
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        managed_map.find(path);
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ManagedState* managed;
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (found == managed_map.end()) {
4617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      if (list_entries.count(path) != 0) {
462a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        NET_LOG_ERROR("Duplicate entry in list", path);
4637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        continue;
4647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      }
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      managed = ManagedState::Create(type, path);
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      managed_list->push_back(managed);
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      managed = found->second;
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      managed_list->push_back(managed);
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      managed_map.erase(found);
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    list_entries.insert(path);
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
474ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Delete any remaining entries in managed_map.
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  STLDeleteContainerPairSecondPointers(managed_map.begin(), managed_map.end());
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
478c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void NetworkStateHandler::ProfileListChanged() {
47990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  NET_LOG_EVENT("ProfileListChanged", "Re-Requesting Network Properties");
480effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  for (ManagedStateList::iterator iter = favorite_list_.begin();
481effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch       iter != favorite_list_.end(); ++iter) {
482c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    shill_property_handler_->RequestProperties(
483c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        ManagedState::MANAGED_TYPE_NETWORK, (*iter)->path());
484c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
485c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
486c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NetworkStateHandler::UpdateManagedStateProperties(
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ManagedState::ManagedType type,
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& path,
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::DictionaryValue& properties) {
4912385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  ManagedStateList* managed_list = GetManagedList(type);
4922385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  ManagedState* managed = GetModifiableManagedState(managed_list, path);
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!managed) {
4942385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    if (type != ManagedState::MANAGED_TYPE_FAVORITE) {
49558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      // The network has been removed from the list of visible networks.
49658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      NET_LOG_DEBUG("UpdateManagedStateProperties: Not found", path);
4972385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      return;
4982385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    }
4992385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // A Favorite may not have been created yet if it was added later (e.g.
5002385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // through ConfigureService) since ServiceCompleteList updates are not
5012385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // emitted. Add and update the state here.
5022385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    managed = new FavoriteState(path);
5032385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    managed_list->push_back(managed);
5042385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  }
5052385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  managed->set_update_received();
5062385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
507effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  std::string desc = GetManagedStateLogType(managed) + " Properties Received";
5082385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  NET_LOG_DEBUG(desc, GetManagedStateLogName(managed));
5092385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
5102385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if (type == ManagedState::MANAGED_TYPE_NETWORK) {
5112385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    UpdateNetworkStateProperties(managed->AsNetworkState(), properties);
5122385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  } else {
5132385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // Device, Favorite
5142385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    for (base::DictionaryValue::Iterator iter(properties);
5152385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch         !iter.IsAtEnd(); iter.Advance()) {
5162385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      managed->PropertyChanged(iter.key(), iter.value());
5172385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    }
5182385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    managed->InitialPropertiesReceived(properties);
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5202385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  managed->set_update_requested(false);
5212385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
5222385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
5232385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid NetworkStateHandler::UpdateNetworkStateProperties(
5242385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    NetworkState* network,
5252385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    const base::DictionaryValue& properties) {
5262385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  DCHECK(network);
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool network_property_updated = false;
5282385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  std::string prev_connection_state = network->connection_state();
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (base::DictionaryValue::Iterator iter(properties);
530c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       !iter.IsAtEnd(); iter.Advance()) {
5312385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    if (network->PropertyChanged(iter.key(), iter.value()))
5322385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      network_property_updated = true;
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5342385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  network_property_updated |= network->InitialPropertiesReceived(properties);
5352385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // Notify observers of NetworkState changes.
5362385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if (network_property_updated || network->update_requested()) {
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Signal connection state changed after all properties have been updated.
5382385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    if (ConnectionStateChanged(network, prev_connection_state))
5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      OnNetworkConnectionStateChanged(network);
540a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    NET_LOG_EVENT("NetworkPropertiesUpdated", GetManagedStateLogName(network));
541a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    NotifyNetworkPropertiesUpdated(network);
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NetworkStateHandler::UpdateNetworkServiceProperty(
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& service_path,
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& key,
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::Value& value) {
549eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Update any associated FavoriteState.
550eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ManagedState* favorite =
551eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      GetModifiableManagedState(&favorite_list_, service_path);
5524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  bool changed = false;
553eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (favorite)
5544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    changed |= favorite->PropertyChanged(key, value);
555eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
556eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Update the NetworkState.
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NetworkState* network = GetModifiableNetworkState(service_path);
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!network)
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string prev_connection_state = network->connection_state();
561ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  std::string prev_profile_path = network->profile_path();
5624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  changed |= network->PropertyChanged(key, value);
5634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!changed)
5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
56668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (key == shill::kStateProperty) {
567ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    if (ConnectionStateChanged(network, prev_connection_state)) {
568c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      OnNetworkConnectionStateChanged(network);
569ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      // If the connection state changes, other properties such as IPConfig
570ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      // may have changed, so request a full update.
571ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      RequestUpdateForNetwork(service_path);
572ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    }
573c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else {
5744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    std::string value_str;
5754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    value.GetAsString(&value_str);
5764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // Some property changes are noisy and not interesting:
5774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // * Wifi SignalStrength
5784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // * WifiFrequencyList updates
5794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // * Device property changes to "/" (occurs before a service is removed)
5804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (key != shill::kSignalStrengthProperty &&
5814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        key != shill::kWifiFrequencyListProperty &&
5824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        (key != shill::kDeviceProperty || value_str != "/")) {
583a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      std::string log_event = "NetworkPropertyUpdated";
5844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      // Trigger a default network update for interesting changes only.
585a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      if (network->path() == default_network_path_) {
586a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        NotifyDefaultNetworkChanged(network);
587a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        log_event = "Default" + log_event;
588a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      }
589a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // Log event.
590ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      std::string detail = network->name() + "." + key;
591ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      detail += " = " + network_event_log::ValueAsString(value);
592ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      network_event_log::LogLevel log_level;
59368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      if (key == shill::kErrorProperty || key == shill::kErrorDetailsProperty) {
594ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        log_level = network_event_log::LOG_LEVEL_ERROR;
595ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      } else {
596ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        log_level = network_event_log::LOG_LEVEL_EVENT;
597ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      }
598a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      NET_LOG_LEVEL(log_level, log_event, detail);
599ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    }
600c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
6014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
6024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // All property updates signal 'NetworkPropertiesUpdated'.
603a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  NotifyNetworkPropertiesUpdated(network);
6044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
6054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // If added to a Profile, request a full update so that a FavoriteState
6064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // gets created.
6074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (prev_profile_path.empty() && !network->profile_path().empty())
6084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    RequestUpdateForNetwork(service_path);
6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NetworkStateHandler::UpdateDeviceProperty(const std::string& device_path,
6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                               const std::string& key,
6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                               const base::Value& value) {
6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DeviceState* device = GetModifiableDeviceState(device_path);
6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!device)
6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!device->PropertyChanged(key, value))
6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string detail = device->name() + "." + key;
62190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  detail += " = " + network_event_log::ValueAsString(value);
62290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  NET_LOG_EVENT("DevicePropertyUpdated", detail);
623c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
624d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  NotifyDeviceListChanged();
625c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
62668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (key == shill::kScanningProperty && device->scanning() == false)
627c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ScanCompleted(device->type());
6284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (key == shill::kEapAuthenticationCompletedProperty) {
6294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // Notify a change for each Ethernet service using this device.
6304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    NetworkStateList ethernet_services;
6314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    GetNetworkListByType(NetworkTypePattern::Ethernet(), &ethernet_services);
6324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    for (NetworkStateList::const_iterator it = ethernet_services.begin();
6334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)         it != ethernet_services.end(); ++it) {
6344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      const NetworkState* ethernet_service = *it;
6354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      if (ethernet_service->update_received() ||
6364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          ethernet_service->device_path() != device->path()) {
6374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        continue;
6384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      }
6394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      RequestUpdateForNetwork(ethernet_service->path());
6404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
6414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
644868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void NetworkStateHandler::CheckPortalListChanged(
645868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const std::string& check_portal_list) {
646868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  check_portal_list_ = check_portal_list;
647868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
648868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
649d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void NetworkStateHandler::TechnologyListChanged() {
650d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Eventually we would like to replace Technology state with Device state.
651d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // For now, treat technology state changes as device list changes.
652d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  NotifyDeviceListChanged();
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NetworkStateHandler::ManagedStateListChanged(
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ManagedState::ManagedType type) {
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (type == ManagedState::MANAGED_TYPE_NETWORK) {
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Notify observers that the list of networks has changed.
65990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    NET_LOG_EVENT("NetworkListChanged",
660a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                  base::StringPrintf("Size:%" PRIuS, network_list_.size()));
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_,
6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      NetworkListChanged());
663424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    // Update UMA stats.
664424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    UMA_HISTOGRAM_COUNTS_100("Networks.Visible", network_list_.size());
665eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  } else if (type == ManagedState::MANAGED_TYPE_FAVORITE) {
666eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    NET_LOG_DEBUG("FavoriteListChanged",
667a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                  base::StringPrintf("Size:%" PRIuS, favorite_list_.size()));
668ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    // The FavoriteState list only changes when the NetworkState list changes,
669ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    // so no need to signal observers here again.
670424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
671424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    // Update UMA stats.
672424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    size_t shared = 0, unshared = 0;
673424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    for (ManagedStateList::iterator iter = favorite_list_.begin();
674424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)         iter != favorite_list_.end(); ++iter) {
675424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      FavoriteState* favorite = (*iter)->AsFavoriteState();
676effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      if (!favorite->IsFavorite())
677424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        continue;
678424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      if (favorite->IsPrivate())
679424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        ++unshared;
680424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      else
681424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        ++shared;
682424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    }
683424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    UMA_HISTOGRAM_COUNTS_100("Networks.RememberedShared", shared);
684424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    UMA_HISTOGRAM_COUNTS_100("Networks.RememberedUnshared", unshared);
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (type == ManagedState::MANAGED_TYPE_DEVICE) {
686d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    NotifyDeviceListChanged();
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
692a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void NetworkStateHandler::DefaultNetworkServiceChanged(
693a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const std::string& service_path) {
694a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Shill uses '/' for empty service path values; check explicitly for that.
695a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const char* kEmptyServicePath = "/";
696a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (service_path == kEmptyServicePath)
697a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    default_network_path_.clear();
698a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  else
699a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    default_network_path_ = service_path;
700a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  NET_LOG_EVENT("DefaultNetworkServiceChanged:", default_network_path_);
701a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const NetworkState* network = NULL;
702a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!default_network_path_.empty()) {
703a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    network = GetNetworkState(default_network_path_);
704a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (!network) {
705a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // If NetworkState is not available yet, do not notify observers here,
706a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // they will be notified when the state is received.
707a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      NET_LOG_DEBUG("Default NetworkState not available",
708a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                    default_network_path_);
709a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return;
710a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
711a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
712a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (network && !network->IsConnectedState()) {
713a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    NET_LOG_ERROR(
714a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        "DefaultNetwork is not connected: " + network->connection_state(),
715a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        network->path());
716a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
717a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  NotifyDefaultNetworkChanged(network);
718a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
719a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//------------------------------------------------------------------------------
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Private methods
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
723d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void NetworkStateHandler::NotifyDeviceListChanged() {
724d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  NET_LOG_DEBUG("NotifyDeviceListChanged",
725d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                base::StringPrintf("Size:%" PRIuS, device_list_.size()));
726d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_,
727d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                    DeviceListChanged());
728d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
729d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DeviceState* NetworkStateHandler::GetModifiableDeviceState(
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& device_path) const {
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ManagedState* managed = GetModifiableManagedState(&device_list_, device_path);
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!managed)
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return managed->AsDeviceState();
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NetworkState* NetworkStateHandler::GetModifiableNetworkState(
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& service_path) const {
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ManagedState* managed =
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetModifiableManagedState(&network_list_, service_path);
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!managed)
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return managed->AsNetworkState();
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ManagedState* NetworkStateHandler::GetModifiableManagedState(
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ManagedStateList* managed_list,
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& path) const {
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ManagedStateList::const_iterator iter = managed_list->begin();
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       iter != managed_list->end(); ++iter) {
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ManagedState* managed = *iter;
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (managed->path() == path)
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return managed;
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NetworkStateHandler::ManagedStateList* NetworkStateHandler::GetManagedList(
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ManagedState::ManagedType type) {
7612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch (type) {
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ManagedState::MANAGED_TYPE_NETWORK:
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return &network_list_;
764eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    case ManagedState::MANAGED_TYPE_FAVORITE:
765eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      return &favorite_list_;
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ManagedState::MANAGED_TYPE_DEVICE:
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return &device_list_;
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NetworkStateHandler::OnNetworkConnectionStateChanged(
7742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NetworkState* network) {
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(network);
776a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  std::string event = "NetworkConnectionStateChanged";
777a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (network->path() == default_network_path_) {
778a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    event = "Default" + event;
779a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (!network->IsConnectedState()) {
780a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      NET_LOG_ERROR(
781a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          "DefaultNetwork is not connected: " + network->connection_state(),
782a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          network->path());
783a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
784a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
785a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  NET_LOG_EVENT(event + ": " + network->connection_state(),
786a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                GetManagedStateLogName(network));
7872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_,
7882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    NetworkConnectionStateChanged(network));
789a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (network->path() == default_network_path_)
790a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    NotifyDefaultNetworkChanged(network);
7912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
793a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void NetworkStateHandler::NotifyDefaultNetworkChanged(
794a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const NetworkState* default_network) {
7952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_,
7962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    DefaultNetworkChanged(default_network));
7972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
799a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void NetworkStateHandler::NotifyNetworkPropertiesUpdated(
8002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const NetworkState* network) {
8012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_,
8022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    NetworkPropertiesUpdated(network));
803c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
804c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
805c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void NetworkStateHandler::ScanCompleted(const std::string& type) {
806c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  size_t num_callbacks = scan_complete_callbacks_.count(type);
80790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  NET_LOG_EVENT("ScanCompleted",
808a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                base::StringPrintf("%s:%" PRIuS, type.c_str(), num_callbacks));
809c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (num_callbacks == 0)
810c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
811c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ScanCallbackList& callback_list = scan_complete_callbacks_[type];
812c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (ScanCallbackList::iterator iter = callback_list.begin();
813c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       iter != callback_list.end(); ++iter) {
814c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    (*iter).Run();
815c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
816c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scan_complete_callbacks_.erase(type);
817c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
818c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
819c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)std::string NetworkStateHandler::GetTechnologyForType(
82058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const NetworkTypePattern& type) const {
82168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (type.MatchesType(shill::kTypeEthernet))
82268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return shill::kTypeEthernet;
82358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
82468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (type.MatchesType(shill::kTypeWifi))
82568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return shill::kTypeWifi;
82658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
82758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (type.Equals(NetworkTypePattern::Wimax()))
82868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return shill::kTypeWimax;
82958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
83058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Prefer Wimax over Cellular only if it's available.
83168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (type.MatchesType(shill::kTypeWimax) &&
83268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      shill_property_handler_->IsTechnologyAvailable(shill::kTypeWimax)) {
83368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return shill::kTypeWimax;
834c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
83558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
83668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (type.MatchesType(shill::kTypeCellular))
83768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return shill::kTypeCellular;
83858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
83958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  NOTREACHED();
84058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return std::string();
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuScopedVector<std::string> NetworkStateHandler::GetTechnologiesForType(
8445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    const NetworkTypePattern& type) const {
8455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  ScopedVector<std::string> technologies;
8465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (type.MatchesType(shill::kTypeEthernet))
8475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    technologies.push_back(new std::string(shill::kTypeEthernet));
8485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (type.MatchesType(shill::kTypeWifi))
8495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    technologies.push_back(new std::string(shill::kTypeWifi));
8505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (type.MatchesType(shill::kTypeWimax))
8515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    technologies.push_back(new std::string(shill::kTypeWimax));
8525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (type.MatchesType(shill::kTypeCellular))
8535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    technologies.push_back(new std::string(shill::kTypeCellular));
8545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (type.MatchesType(shill::kTypeBluetooth))
8555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    technologies.push_back(new std::string(shill::kTypeBluetooth));
8565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (type.MatchesType(shill::kTypeVPN))
8575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    technologies.push_back(new std::string(shill::kTypeVPN));
8585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
8595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  CHECK_GT(technologies.size(), 0ul);
8605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  return technologies.Pass();
8615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
8625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace chromeos
864