| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/chromeos/cros/network_library_impl_base.h" |
| |
| #include "base/bind.h" |
| #include "chrome/browser/chromeos/cros/native_network_parser.h" |
| #include "chrome/browser/chromeos/cros/onc_network_parser.h" |
| #include "chrome/browser/chromeos/network_login_observer.h" |
| #include "chrome/common/net/x509_certificate_model.h" |
| #include "content/public/browser/browser_thread.h" |
| #include "crypto/nss_util.h" // crypto::GetTPMTokenInfo() for 802.1X and VPN. |
| #include "grit/generated_resources.h" |
| #include "third_party/cros_system_api/dbus/service_constants.h" |
| #include "ui/base/l10n/l10n_util.h" |
| |
| using content::BrowserThread; |
| |
| namespace chromeos { |
| |
| // Local constants. |
| namespace { |
| |
| // Only send network change notifications to observers once every 50ms. |
| const int kNetworkNotifyDelayMs = 50; |
| |
| // How long we should remember that cellular plan payment was received. |
| const int kRecentPlanPaymentHours = 6; |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // Misc. |
| |
| NetworkProfileType GetProfileTypeForSource(NetworkUIData::ONCSource source) { |
| switch (source) { |
| case NetworkUIData::ONC_SOURCE_DEVICE_POLICY: |
| return PROFILE_SHARED; |
| case NetworkUIData::ONC_SOURCE_USER_POLICY: |
| return PROFILE_USER; |
| case NetworkUIData::ONC_SOURCE_NONE: |
| case NetworkUIData::ONC_SOURCE_USER_IMPORT: |
| return PROFILE_NONE; |
| } |
| NOTREACHED() << "Unknown ONC source " << source; |
| return PROFILE_NONE; |
| } |
| |
| } // namespace |
| |
| NetworkLibraryImplBase::NetworkLibraryImplBase() |
| : ethernet_(NULL), |
| active_wifi_(NULL), |
| active_cellular_(NULL), |
| active_wimax_(NULL), |
| active_virtual_(NULL), |
| available_devices_(0), |
| enabled_devices_(0), |
| busy_devices_(0), |
| connected_devices_(0), |
| wifi_scanning_(false), |
| offline_mode_(false), |
| is_locked_(false), |
| sim_operation_(SIM_OPERATION_NONE), |
| ALLOW_THIS_IN_INITIALIZER_LIST(notify_manager_weak_factory_(this)) { |
| network_login_observer_.reset(new NetworkLoginObserver()); |
| AddNetworkManagerObserver(network_login_observer_.get()); |
| } |
| |
| NetworkLibraryImplBase::~NetworkLibraryImplBase() { |
| network_manager_observers_.Clear(); |
| data_plan_observers_.Clear(); |
| pin_operation_observers_.Clear(); |
| user_action_observers_.Clear(); |
| DeleteNetworks(); |
| DeleteRememberedNetworks(); |
| STLDeleteValues(&data_plan_map_); |
| STLDeleteValues(&device_map_); |
| STLDeleteValues(&network_device_observers_); |
| STLDeleteValues(&network_observers_); |
| STLDeleteValues(&network_onc_map_); |
| } |
| |
| ////////////////////////////////////////////////////////////////////////////// |
| // NetworkLibrary implementation. |
| |
| void NetworkLibraryImplBase::AddNetworkManagerObserver( |
| NetworkManagerObserver* observer) { |
| if (!network_manager_observers_.HasObserver(observer)) |
| network_manager_observers_.AddObserver(observer); |
| } |
| |
| void NetworkLibraryImplBase::RemoveNetworkManagerObserver( |
| NetworkManagerObserver* observer) { |
| network_manager_observers_.RemoveObserver(observer); |
| } |
| |
| void NetworkLibraryImplBase::AddNetworkObserver( |
| const std::string& service_path, NetworkObserver* observer) { |
| // First, add the observer to the callback map. |
| NetworkObserverMap::iterator iter = network_observers_.find(service_path); |
| NetworkObserverList* oblist; |
| if (iter != network_observers_.end()) { |
| oblist = iter->second; |
| } else { |
| oblist = new NetworkObserverList(); |
| network_observers_[service_path] = oblist; |
| } |
| if (observer && !oblist->HasObserver(observer)) |
| oblist->AddObserver(observer); |
| MonitorNetworkStart(service_path); |
| } |
| |
| void NetworkLibraryImplBase::RemoveNetworkObserver( |
| const std::string& service_path, NetworkObserver* observer) { |
| DCHECK(service_path.size()); |
| NetworkObserverMap::iterator map_iter = |
| network_observers_.find(service_path); |
| if (map_iter != network_observers_.end()) { |
| map_iter->second->RemoveObserver(observer); |
| if (!map_iter->second->size()) { |
| MonitorNetworkStop(service_path); |
| delete map_iter->second; |
| network_observers_.erase(map_iter); |
| } |
| } |
| } |
| |
| void NetworkLibraryImplBase::RemoveObserverForAllNetworks( |
| NetworkObserver* observer) { |
| DCHECK(observer); |
| NetworkObserverMap::iterator map_iter = network_observers_.begin(); |
| while (map_iter != network_observers_.end()) { |
| map_iter->second->RemoveObserver(observer); |
| if (!map_iter->second->size()) { |
| MonitorNetworkStop(map_iter->first); |
| delete map_iter->second; |
| network_observers_.erase(map_iter++); |
| } else { |
| ++map_iter; |
| } |
| } |
| } |
| |
| void NetworkLibraryImplBase::AddNetworkDeviceObserver( |
| const std::string& device_path, NetworkDeviceObserver* observer) { |
| // First, add the observer to the callback map. |
| NetworkDeviceObserverMap::iterator iter = |
| network_device_observers_.find(device_path); |
| NetworkDeviceObserverList* oblist; |
| if (iter != network_device_observers_.end()) { |
| oblist = iter->second; |
| } else { |
| oblist = new NetworkDeviceObserverList(); |
| network_device_observers_[device_path] = oblist; |
| } |
| if (!oblist->HasObserver(observer)) |
| oblist->AddObserver(observer); |
| MonitorNetworkDeviceStart(device_path); |
| } |
| |
| void NetworkLibraryImplBase::RemoveNetworkDeviceObserver( |
| const std::string& device_path, NetworkDeviceObserver* observer) { |
| DCHECK(device_path.size()); |
| NetworkDeviceObserverMap::iterator map_iter = |
| network_device_observers_.find(device_path); |
| if (map_iter != network_device_observers_.end()) { |
| map_iter->second->RemoveObserver(observer); |
| } |
| } |
| |
| void NetworkLibraryImplBase::DeleteDeviceFromDeviceObserversMap( |
| const std::string& device_path) { |
| // Delete all device observers associated with this device. |
| NetworkDeviceObserverMap::iterator map_iter = |
| network_device_observers_.find(device_path); |
| if (map_iter != network_device_observers_.end()) { |
| delete map_iter->second; |
| network_device_observers_.erase(map_iter); |
| } |
| } |
| |
| ////////////////////////////////////////////////////////////////////////////// |
| |
| void NetworkLibraryImplBase::Lock() { |
| if (is_locked_) |
| return; |
| is_locked_ = true; |
| NotifyNetworkManagerChanged(true); // Forced update. |
| } |
| |
| void NetworkLibraryImplBase::Unlock() { |
| DCHECK(is_locked_); |
| if (!is_locked_) |
| return; |
| is_locked_ = false; |
| NotifyNetworkManagerChanged(true); // Forced update. |
| } |
| |
| bool NetworkLibraryImplBase::IsLocked() { |
| return is_locked_; |
| } |
| |
| ////////////////////////////////////////////////////////////////////////////// |
| |
| void NetworkLibraryImplBase::AddCellularDataPlanObserver( |
| CellularDataPlanObserver* observer) { |
| if (!data_plan_observers_.HasObserver(observer)) |
| data_plan_observers_.AddObserver(observer); |
| } |
| |
| void NetworkLibraryImplBase::RemoveCellularDataPlanObserver( |
| CellularDataPlanObserver* observer) { |
| data_plan_observers_.RemoveObserver(observer); |
| } |
| |
| void NetworkLibraryImplBase::AddPinOperationObserver( |
| PinOperationObserver* observer) { |
| if (!pin_operation_observers_.HasObserver(observer)) |
| pin_operation_observers_.AddObserver(observer); |
| } |
| |
| void NetworkLibraryImplBase::RemovePinOperationObserver( |
| PinOperationObserver* observer) { |
| pin_operation_observers_.RemoveObserver(observer); |
| } |
| |
| void NetworkLibraryImplBase::AddUserActionObserver( |
| UserActionObserver* observer) { |
| if (!user_action_observers_.HasObserver(observer)) |
| user_action_observers_.AddObserver(observer); |
| } |
| |
| void NetworkLibraryImplBase::RemoveUserActionObserver( |
| UserActionObserver* observer) { |
| user_action_observers_.RemoveObserver(observer); |
| } |
| |
| const EthernetNetwork* NetworkLibraryImplBase::ethernet_network() const { |
| return ethernet_; |
| } |
| |
| bool NetworkLibraryImplBase::ethernet_connecting() const { |
| return ethernet_ ? ethernet_->connecting() : false; |
| } |
| bool NetworkLibraryImplBase::ethernet_connected() const { |
| return ethernet_ ? ethernet_->connected() : false; |
| } |
| const WifiNetwork* NetworkLibraryImplBase::wifi_network() const { |
| return active_wifi_; |
| } |
| bool NetworkLibraryImplBase::wifi_connecting() const { |
| return active_wifi_ ? active_wifi_->connecting() : false; |
| } |
| bool NetworkLibraryImplBase::wifi_connected() const { |
| return active_wifi_ ? active_wifi_->connected() : false; |
| } |
| const CellularNetwork* NetworkLibraryImplBase::cellular_network() const { |
| return active_cellular_; |
| } |
| bool NetworkLibraryImplBase::cellular_connecting() const { |
| return active_cellular_ ? active_cellular_->connecting() : false; |
| } |
| bool NetworkLibraryImplBase::cellular_connected() const { |
| return active_cellular_ ? active_cellular_->connected() : false; |
| } |
| const WimaxNetwork* NetworkLibraryImplBase::wimax_network() const { |
| return active_wimax_; |
| } |
| bool NetworkLibraryImplBase::wimax_connecting() const { |
| return active_wimax_ ? active_wimax_->connecting() : false; |
| } |
| bool NetworkLibraryImplBase::wimax_connected() const { |
| return active_wimax_ ? active_wimax_->connected() : false; |
| } |
| const Network* NetworkLibraryImplBase::mobile_network() const { |
| return active_cellular_ ? |
| static_cast<Network*>(active_cellular_) : |
| static_cast<Network*>(active_wimax_); |
| } |
| bool NetworkLibraryImplBase::mobile_connecting() const { |
| return cellular_connecting() || wimax_connecting(); |
| } |
| bool NetworkLibraryImplBase::mobile_connected() const { |
| return wimax_connecting() || wimax_connected(); |
| } |
| const VirtualNetwork* NetworkLibraryImplBase::virtual_network() const { |
| return active_virtual_; |
| } |
| bool NetworkLibraryImplBase::virtual_network_connecting() const { |
| return active_virtual_ ? active_virtual_->connecting() : false; |
| } |
| bool NetworkLibraryImplBase::virtual_network_connected() const { |
| return active_virtual_ ? active_virtual_->connected() : false; |
| } |
| bool NetworkLibraryImplBase::Connected() const { |
| return ethernet_connected() || wifi_connected() || |
| cellular_connected() || wimax_connected(); |
| } |
| bool NetworkLibraryImplBase::Connecting() const { |
| return ethernet_connecting() || wifi_connecting() || |
| cellular_connecting() || wimax_connecting(); |
| } |
| const WifiNetworkVector& NetworkLibraryImplBase::wifi_networks() const { |
| return wifi_networks_; |
| } |
| const WifiNetworkVector& |
| NetworkLibraryImplBase::remembered_wifi_networks() const { |
| return remembered_wifi_networks_; |
| } |
| const CellularNetworkVector& NetworkLibraryImplBase::cellular_networks() const { |
| return cellular_networks_; |
| } |
| const WimaxNetworkVector& NetworkLibraryImplBase::wimax_networks() const { |
| return wimax_networks_; |
| } |
| const VirtualNetworkVector& NetworkLibraryImplBase::virtual_networks() const { |
| return virtual_networks_; |
| } |
| const VirtualNetworkVector& |
| NetworkLibraryImplBase::remembered_virtual_networks() const { |
| return remembered_virtual_networks_; |
| } |
| |
| // Use shill's ordering of the services to determine which type of |
| // network to return (i.e. don't assume priority of network types). |
| // Note: This does not include any virtual networks. |
| namespace { |
| Network* highest_priority(Network* a, Network*b) { |
| if (!a) |
| return b; |
| if (!b) |
| return a; |
| if (b->priority_order() < a->priority_order()) |
| return b; |
| return a; |
| } |
| } |
| |
| const Network* NetworkLibraryImplBase::active_network() const { |
| Network* result = NULL; |
| if (ethernet_ && ethernet_->is_active()) |
| result = ethernet_; |
| if (active_wifi_ && active_wifi_->is_active()) |
| result = highest_priority(result, active_wifi_); |
| if (active_cellular_ && active_cellular_->is_active()) |
| result = highest_priority(result, active_cellular_); |
| if (active_wimax_ && active_wimax_->is_active()) |
| result = highest_priority(result, active_wimax_); |
| if (active_virtual_ && active_virtual_->is_active()) |
| result = highest_priority(result, active_virtual_); |
| return result; |
| } |
| |
| const Network* NetworkLibraryImplBase::connected_network() const { |
| Network* result = NULL; |
| if (ethernet_ && ethernet_->connected()) |
| result = ethernet_; |
| if (active_wifi_ && active_wifi_->connected()) |
| result = highest_priority(result, active_wifi_); |
| if (active_cellular_ && active_cellular_->connected()) |
| result = highest_priority(result, active_cellular_); |
| if (active_wimax_ && active_wimax_->connected()) |
| result = highest_priority(result, active_wimax_); |
| return result; |
| } |
| |
| // Connecting order in logical prefernce. |
| const Network* NetworkLibraryImplBase::connecting_network() const { |
| if (ethernet_connecting()) |
| return ethernet_network(); |
| else if (wifi_connecting()) |
| return wifi_network(); |
| else if (cellular_connecting()) |
| return cellular_network(); |
| else if (wimax_connecting()) |
| return wimax_network(); |
| return NULL; |
| } |
| |
| bool NetworkLibraryImplBase::ethernet_available() const { |
| return available_devices_ & (1 << TYPE_ETHERNET); |
| } |
| |
| bool NetworkLibraryImplBase::wifi_available() const { |
| return available_devices_ & (1 << TYPE_WIFI); |
| } |
| |
| bool NetworkLibraryImplBase::wimax_available() const { |
| return available_devices_ & (1 << TYPE_WIMAX); |
| } |
| |
| bool NetworkLibraryImplBase::cellular_available() const { |
| return available_devices_ & (1 << TYPE_CELLULAR); |
| } |
| |
| bool NetworkLibraryImplBase::mobile_available() const { |
| return cellular_available() || wimax_available(); |
| } |
| |
| bool NetworkLibraryImplBase::ethernet_enabled() const { |
| return enabled_devices_ & (1 << TYPE_ETHERNET); |
| } |
| |
| bool NetworkLibraryImplBase::wifi_enabled() const { |
| return enabled_devices_ & (1 << TYPE_WIFI); |
| } |
| |
| bool NetworkLibraryImplBase::wimax_enabled() const { |
| return enabled_devices_ & (1 << TYPE_WIMAX); |
| } |
| |
| bool NetworkLibraryImplBase::cellular_enabled() const { |
| return enabled_devices_ & (1 << TYPE_CELLULAR); |
| } |
| |
| bool NetworkLibraryImplBase::mobile_enabled() const { |
| return cellular_enabled() || wimax_enabled(); |
| } |
| |
| bool NetworkLibraryImplBase::ethernet_busy() const { |
| return busy_devices_ & (1 << TYPE_ETHERNET); |
| } |
| |
| bool NetworkLibraryImplBase::wifi_busy() const { |
| return busy_devices_ & (1 << TYPE_WIFI); |
| } |
| |
| bool NetworkLibraryImplBase::wimax_busy() const { |
| return busy_devices_ & (1 << TYPE_WIMAX); |
| } |
| |
| bool NetworkLibraryImplBase::cellular_busy() const { |
| return busy_devices_ & (1 << TYPE_CELLULAR); |
| } |
| |
| bool NetworkLibraryImplBase::mobile_busy() const { |
| return cellular_busy() || wimax_busy(); |
| } |
| |
| bool NetworkLibraryImplBase::wifi_scanning() const { |
| return wifi_scanning_; |
| } |
| |
| bool NetworkLibraryImplBase::offline_mode() const { return offline_mode_; } |
| |
| std::string NetworkLibraryImplBase::GetCheckPortalList() const { |
| return check_portal_list_; |
| } |
| |
| // Returns the IP address for the active network. |
| // TODO(stevenjb): Fix this for VPNs. See chromium-os:13972. |
| const std::string& NetworkLibraryImplBase::IPAddress() const { |
| const Network* result = active_network(); |
| if (!result) |
| result = connected_network(); // happens if we are connected to a VPN. |
| if (!result) |
| result = ethernet_; // Use non active ethernet addr if no active network. |
| if (result) |
| return result->ip_address(); |
| CR_DEFINE_STATIC_LOCAL(std::string, null_address, ("0.0.0.0")); |
| return null_address; |
| } |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| |
| const NetworkDevice* NetworkLibraryImplBase::FindNetworkDeviceByPath( |
| const std::string& path) const { |
| NetworkDeviceMap::const_iterator iter = device_map_.find(path); |
| if (iter != device_map_.end()) |
| return iter->second; |
| LOG(WARNING) << "Device path not found: " << path; |
| return NULL; |
| } |
| |
| NetworkDevice* NetworkLibraryImplBase::FindNetworkDeviceByPath( |
| const std::string& path) { |
| NetworkDeviceMap::iterator iter = device_map_.find(path); |
| if (iter != device_map_.end()) |
| return iter->second; |
| LOG(WARNING) << "Device path not found: " << path; |
| return NULL; |
| } |
| |
| const NetworkDevice* NetworkLibraryImplBase::FindCellularDevice() const { |
| return FindDeviceByType(TYPE_CELLULAR); |
| } |
| |
| const NetworkDevice* NetworkLibraryImplBase::FindEthernetDevice() const { |
| return FindDeviceByType(TYPE_ETHERNET); |
| } |
| |
| const NetworkDevice* NetworkLibraryImplBase::FindWifiDevice() const { |
| return FindDeviceByType(TYPE_WIFI); |
| } |
| |
| const NetworkDevice* NetworkLibraryImplBase::FindWimaxDevice() const { |
| return FindDeviceByType(TYPE_WIMAX); |
| } |
| |
| const NetworkDevice* NetworkLibraryImplBase::FindMobileDevice() const { |
| const NetworkDevice* device = FindDeviceByType(TYPE_CELLULAR); |
| if (device) |
| return device; |
| |
| return FindDeviceByType(TYPE_WIMAX); |
| } |
| |
| Network* NetworkLibraryImplBase::FindNetworkByPath( |
| const std::string& path) const { |
| NetworkMap::const_iterator iter = network_map_.find(path); |
| if (iter != network_map_.end()) |
| return iter->second; |
| return NULL; |
| } |
| |
| Network* NetworkLibraryImplBase::FindNetworkByUniqueId( |
| const std::string& unique_id) const { |
| NetworkMap::const_iterator found = network_unique_id_map_.find(unique_id); |
| if (found != network_unique_id_map_.end()) |
| return found->second; |
| return NULL; |
| } |
| |
| WirelessNetwork* NetworkLibraryImplBase::FindWirelessNetworkByPath( |
| const std::string& path) const { |
| Network* network = FindNetworkByPath(path); |
| if (network && |
| (network->type() == TYPE_WIFI || network->type() == TYPE_WIMAX || |
| network->type() == TYPE_CELLULAR)) |
| return static_cast<WirelessNetwork*>(network); |
| return NULL; |
| } |
| |
| WifiNetwork* NetworkLibraryImplBase::FindWifiNetworkByPath( |
| const std::string& path) const { |
| Network* network = FindNetworkByPath(path); |
| if (network && network->type() == TYPE_WIFI) |
| return static_cast<WifiNetwork*>(network); |
| return NULL; |
| } |
| |
| WimaxNetwork* NetworkLibraryImplBase::FindWimaxNetworkByPath( |
| const std::string& path) const { |
| Network* network = FindNetworkByPath(path); |
| if (network && (network->type() == TYPE_WIMAX)) |
| return static_cast<WimaxNetwork*>(network); |
| return NULL; |
| } |
| |
| CellularNetwork* NetworkLibraryImplBase::FindCellularNetworkByPath( |
| const std::string& path) const { |
| Network* network = FindNetworkByPath(path); |
| if (network && network->type() == TYPE_CELLULAR) |
| return static_cast<CellularNetwork*>(network); |
| return NULL; |
| } |
| |
| VirtualNetwork* NetworkLibraryImplBase::FindVirtualNetworkByPath( |
| const std::string& path) const { |
| Network* network = FindNetworkByPath(path); |
| if (network && network->type() == TYPE_VPN) |
| return static_cast<VirtualNetwork*>(network); |
| return NULL; |
| } |
| |
| Network* NetworkLibraryImplBase::FindRememberedFromNetwork( |
| const Network* network) const { |
| for (NetworkMap::const_iterator iter = remembered_network_map_.begin(); |
| iter != remembered_network_map_.end(); ++iter) { |
| if (iter->second->unique_id() == network->unique_id()) |
| return iter->second; |
| } |
| return NULL; |
| } |
| |
| Network* NetworkLibraryImplBase::FindRememberedNetworkByPath( |
| const std::string& path) const { |
| NetworkMap::const_iterator iter = remembered_network_map_.find(path); |
| if (iter != remembered_network_map_.end()) |
| return iter->second; |
| return NULL; |
| } |
| |
| Network* NetworkLibraryImplBase::FindRememberedNetworkByUniqueId( |
| const std::string& unique_id) const { |
| NetworkMap::const_iterator found = |
| remembered_network_unique_id_map_.find(unique_id); |
| if (found != remembered_network_unique_id_map_.end()) |
| return found->second; |
| return NULL; |
| } |
| |
| const base::DictionaryValue* NetworkLibraryImplBase::FindOncForNetwork( |
| const std::string& unique_id) const { |
| NetworkOncMap::const_iterator iter = network_onc_map_.find(unique_id); |
| return iter != network_onc_map_.end() ? iter->second : NULL; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////// |
| // Data Plans. |
| |
| const CellularDataPlanVector* NetworkLibraryImplBase::GetDataPlans( |
| const std::string& path) const { |
| CellularDataPlanMap::const_iterator iter = data_plan_map_.find(path); |
| if (iter == data_plan_map_.end()) |
| return NULL; |
| // If we need a new plan, then ignore any data plans we have. |
| CellularNetwork* cellular = FindCellularNetworkByPath(path); |
| if (cellular && cellular->needs_new_plan()) |
| return NULL; |
| return iter->second; |
| } |
| |
| const CellularDataPlan* NetworkLibraryImplBase::GetSignificantDataPlan( |
| const std::string& path) const { |
| const CellularDataPlanVector* plans = GetDataPlans(path); |
| if (plans) |
| return GetSignificantDataPlanFromVector(plans); |
| return NULL; |
| } |
| |
| const CellularDataPlan* NetworkLibraryImplBase:: |
| GetSignificantDataPlanFromVector(const CellularDataPlanVector* plans) const { |
| const CellularDataPlan* significant = NULL; |
| for (CellularDataPlanVector::const_iterator iter = plans->begin(); |
| iter != plans->end(); ++iter) { |
| // Set significant to the first plan or to first non metered base plan. |
| if (significant == NULL || |
| significant->plan_type == CELLULAR_DATA_PLAN_METERED_BASE) |
| significant = *iter; |
| } |
| return significant; |
| } |
| |
| CellularNetwork::DataLeft NetworkLibraryImplBase::GetDataLeft( |
| CellularDataPlanVector* data_plan_vector) { |
| const CellularDataPlan* plan = |
| GetSignificantDataPlanFromVector(data_plan_vector); |
| if (!plan) |
| return CellularNetwork::DATA_UNKNOWN; |
| if (plan->plan_type == CELLULAR_DATA_PLAN_UNLIMITED) { |
| base::TimeDelta remaining = plan->remaining_time(); |
| if (remaining <= base::TimeDelta::FromSeconds(0)) |
| return CellularNetwork::DATA_NONE; |
| if (remaining <= base::TimeDelta::FromSeconds(kCellularDataVeryLowSecs)) |
| return CellularNetwork::DATA_VERY_LOW; |
| if (remaining <= base::TimeDelta::FromSeconds(kCellularDataLowSecs)) |
| return CellularNetwork::DATA_LOW; |
| return CellularNetwork::DATA_NORMAL; |
| } else if (plan->plan_type == CELLULAR_DATA_PLAN_METERED_PAID || |
| plan->plan_type == CELLULAR_DATA_PLAN_METERED_BASE) { |
| int64 remaining = plan->remaining_data(); |
| if (remaining <= 0) |
| return CellularNetwork::DATA_NONE; |
| if (remaining <= kCellularDataVeryLowBytes) |
| return CellularNetwork::DATA_VERY_LOW; |
| // For base plans, we do not care about low data. |
| if (remaining <= kCellularDataLowBytes && |
| plan->plan_type != CELLULAR_DATA_PLAN_METERED_BASE) |
| return CellularNetwork::DATA_LOW; |
| return CellularNetwork::DATA_NORMAL; |
| } |
| return CellularNetwork::DATA_UNKNOWN; |
| } |
| |
| void NetworkLibraryImplBase::UpdateCellularDataPlan( |
| const std::string& service_path, |
| CellularDataPlanVector* data_plan_vector) { |
| VLOG(1) << "Updating cellular data plans for: " << service_path; |
| // Find and delete any existing data plans associated with |service_path|. |
| CellularDataPlanMap::iterator found = data_plan_map_.find(service_path); |
| if (found != data_plan_map_.end()) |
| delete found->second; // This will delete existing data plans. |
| // Takes ownership of |data_plan_vector|. |
| data_plan_map_[service_path] = data_plan_vector; |
| |
| // Now, update any matching cellular network's cached data |
| CellularNetwork* cellular = FindCellularNetworkByPath(service_path); |
| if (cellular) { |
| CellularNetwork::DataLeft data_left; |
| // If the network needs a new plan, then there's no data. |
| if (cellular->needs_new_plan()) |
| data_left = CellularNetwork::DATA_NONE; |
| else |
| data_left = GetDataLeft(data_plan_vector); |
| VLOG(2) << " Data left: " << data_left |
| << " Need plan: " << cellular->needs_new_plan(); |
| cellular->set_data_left(data_left); |
| } |
| NotifyCellularDataPlanChanged(); |
| } |
| |
| void NetworkLibraryImplBase::SignalCellularPlanPayment() { |
| DCHECK(!HasRecentCellularPlanPayment()); |
| cellular_plan_payment_time_ = base::Time::Now(); |
| } |
| |
| bool NetworkLibraryImplBase::HasRecentCellularPlanPayment() { |
| return (base::Time::Now() - |
| cellular_plan_payment_time_).InHours() < kRecentPlanPaymentHours; |
| } |
| |
| const std::string& NetworkLibraryImplBase::GetCellularHomeCarrierId() const { |
| const NetworkDevice* cellular = FindCellularDevice(); |
| if (cellular) |
| return cellular->home_provider_id(); |
| return EmptyString(); |
| } |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| // Profiles. |
| |
| bool NetworkLibraryImplBase::HasProfileType(NetworkProfileType type) const { |
| for (NetworkProfileList::const_iterator iter = profile_list_.begin(); |
| iter != profile_list_.end(); ++iter) { |
| if ((*iter).type == type) |
| return true; |
| } |
| return false; |
| } |
| |
| // Note: currently there is no way to change the profile of a network |
| // unless it is visible (i.e. in network_map_). We change the profile by |
| // setting the Profile property of the visible network. |
| // See chromium-os:15523. |
| void NetworkLibraryImplBase::SetNetworkProfile( |
| const std::string& service_path, NetworkProfileType type) { |
| Network* network = FindNetworkByPath(service_path); |
| if (!network) { |
| LOG(WARNING) << "SetNetworkProfile: Network not found: " << service_path; |
| return; |
| } |
| if (network->profile_type() == type) { |
| LOG(WARNING) << "Remembered Network: " << service_path |
| << " already in profile: " << type; |
| return; |
| } |
| if (network->RequiresUserProfile() && type == PROFILE_SHARED) { |
| LOG(WARNING) << "SetNetworkProfile to Shared for non sharable network: " |
| << service_path; |
| return; |
| } |
| VLOG(1) << "Setting network: " << network->name() |
| << " to profile type: " << type; |
| SetProfileType(network, type); |
| NotifyNetworkManagerChanged(false); |
| } |
| |
| NetworkLibraryImplBase::NetworkProfile::NetworkProfile(const std::string& p, |
| NetworkProfileType t) |
| : path(p), |
| type(t) { |
| } |
| |
| NetworkLibraryImplBase::NetworkProfile::~NetworkProfile() {} |
| |
| NetworkLibraryImplBase::ConnectData::ConnectData() |
| : security(SECURITY_NONE), |
| eap_method(EAP_METHOD_UNKNOWN), |
| eap_auth(EAP_PHASE_2_AUTH_AUTO), |
| eap_use_system_cas(false), |
| save_credentials(false), |
| profile_type(PROFILE_NONE) { |
| } |
| |
| NetworkLibraryImplBase::ConnectData::~ConnectData() {} |
| |
| const NetworkDevice* NetworkLibraryImplBase::FindDeviceByType( |
| ConnectionType type) const { |
| for (NetworkDeviceMap::const_iterator iter = device_map_.begin(); |
| iter != device_map_.end(); ++iter) { |
| if (iter->second && iter->second->type() == type) |
| return iter->second; |
| } |
| return NULL; |
| } |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| // Connect to an existing network. |
| |
| bool NetworkLibraryImplBase::CanConnectToNetwork(const Network* network) const { |
| if (!HasProfileType(PROFILE_USER) && network->RequiresUserProfile()) |
| return false; |
| return true; |
| } |
| |
| // 1. Request a connection to an existing wifi network. |
| // Use |shared| to pass along the desired profile type. |
| void NetworkLibraryImplBase::ConnectToWifiNetwork( |
| WifiNetwork* wifi, bool shared) { |
| NetworkConnectStartWifi(wifi, shared ? PROFILE_SHARED : PROFILE_USER); |
| } |
| |
| // 1. Request a connection to an existing wifi network. |
| void NetworkLibraryImplBase::ConnectToWifiNetwork(WifiNetwork* wifi) { |
| NetworkConnectStartWifi(wifi, PROFILE_NONE); |
| } |
| |
| // 1. Request a connection to an existing wimax network. |
| // Use |shared| to pass along the desired profile type. |
| void NetworkLibraryImplBase::ConnectToWimaxNetwork( |
| WimaxNetwork* wimax, bool shared) { |
| NetworkConnectStart(wimax, shared ? PROFILE_SHARED : PROFILE_USER); |
| } |
| |
| // 1. Request a connection to an existing wimax network. |
| void NetworkLibraryImplBase::ConnectToWimaxNetwork(WimaxNetwork* wimax) { |
| NetworkConnectStart(wimax, PROFILE_NONE); |
| } |
| |
| // 1. Connect to a cellular network. |
| void NetworkLibraryImplBase::ConnectToCellularNetwork( |
| CellularNetwork* cellular) { |
| NetworkConnectStart(cellular, PROFILE_NONE); |
| } |
| |
| // 1. Connect to an existing virtual network. |
| void NetworkLibraryImplBase::ConnectToVirtualNetwork(VirtualNetwork* vpn) { |
| NetworkConnectStartVPN(vpn); |
| } |
| |
| // 2. Start the connection. |
| void NetworkLibraryImplBase::NetworkConnectStartWifi( |
| WifiNetwork* wifi, NetworkProfileType profile_type) { |
| DCHECK(!wifi->connection_started()); |
| // This will happen if a network resets, gets out of range or is forgotten. |
| if (wifi->user_passphrase_ != wifi->passphrase_ || |
| wifi->passphrase_required()) |
| wifi->SetPassphrase(wifi->user_passphrase_); |
| // For enterprise 802.1X networks, always provide TPM PIN when available. |
| // shill uses the PIN if it needs to access certificates in the TPM and |
| // ignores it otherwise. |
| if (wifi->encryption() == SECURITY_8021X) { |
| // If the TPM initialization has not completed, GetTpmPin() will return |
| // an empty value, in which case we do not want to clear the PIN since |
| // that will cause shill to flag the network as unconfigured. |
| // TODO(stevenjb): We may want to delay attempting to connect, or fail |
| // immediately, rather than let the network layer attempt a connection. |
| std::string tpm_pin = GetTpmPin(); |
| if (!tpm_pin.empty()) |
| wifi->SetCertificatePin(tpm_pin); |
| } |
| NetworkConnectStart(wifi, profile_type); |
| } |
| |
| void NetworkLibraryImplBase::NetworkConnectStartVPN(VirtualNetwork* vpn) { |
| // shill needs the TPM PIN for some VPN networks to access client |
| // certificates, and ignores the PIN if it doesn't need them. Only set this |
| // if the TPM is ready (see comment in NetworkConnectStartWifi). |
| std::string tpm_pin = GetTpmPin(); |
| if (!tpm_pin.empty()) { |
| std::string tpm_slot = GetTpmSlot(); |
| vpn->SetCertificateSlotAndPin(tpm_slot, tpm_pin); |
| } |
| NetworkConnectStart(vpn, PROFILE_NONE); |
| } |
| |
| void NetworkLibraryImplBase::NetworkConnectStart( |
| Network* network, NetworkProfileType profile_type) { |
| DCHECK(network); |
| DCHECK(!network->connection_started()); |
| // In order to be certain to trigger any notifications, set the connecting |
| // state locally and notify observers. Otherwise there might be a state |
| // change without a forced notify. |
| network->set_connecting(); |
| // Distinguish between user-initiated connection attempts |
| // and auto-connect. |
| network->set_connection_started(true); |
| NotifyNetworkManagerChanged(true); // Forced update. |
| VLOG(1) << "Requesting connect to network: " << network->name() |
| << " profile type: " << profile_type; |
| // Specify the correct profile for wifi networks (if specified or unset). |
| if ((network->type() == TYPE_WIFI || network->type() == TYPE_WIMAX) && |
| (profile_type != PROFILE_NONE || |
| network->profile_type() == PROFILE_NONE)) { |
| if (network->RequiresUserProfile()) |
| profile_type = PROFILE_USER; // Networks with certs can not be shared. |
| else if (profile_type == PROFILE_NONE) |
| profile_type = PROFILE_SHARED; // Other networks are shared by default. |
| std::string profile_path = GetProfilePath(profile_type); |
| if (!profile_path.empty()) { |
| if (profile_path != network->profile_path()) |
| SetProfileType(network, profile_type); |
| } else if (profile_type == PROFILE_USER) { |
| // The user profile was specified but is not available (i.e. pre-login). |
| // Add this network to the list of networks to move to the user profile |
| // when it becomes available. |
| VLOG(1) << "Queuing: " << network->name() << " to user_networks list."; |
| user_networks_.push_back(network->service_path()); |
| } |
| } |
| CallConnectToNetwork(network); |
| } |
| |
| // 3. Start the connection attempt for Network. |
| // Must Call NetworkConnectCompleted when the connection attempt completes. |
| // virtual void CallConnectToNetwork(Network* network) = 0; |
| |
| // 4. Complete the connection. |
| void NetworkLibraryImplBase::NetworkConnectCompleted( |
| Network* network, NetworkConnectStatus status) { |
| DCHECK(network); |
| if (status != CONNECT_SUCCESS) { |
| // This will trigger the connection failed notification. |
| // TODO(stevenjb): Remove if chromium-os:13203 gets fixed. |
| network->SetState(STATE_FAILURE); |
| if (status == CONNECT_BAD_PASSPHRASE) { |
| network->SetError(ERROR_BAD_PASSPHRASE); |
| } else { |
| network->SetError(ERROR_CONNECT_FAILED); |
| } |
| NotifyNetworkManagerChanged(true); // Forced update. |
| NotifyNetworkChanged(network); |
| VLOG(1) << "Error connecting to network: " << network->name() |
| << " Status: " << status; |
| return; |
| } |
| |
| VLOG(1) << "Connected to network: " << network->name() |
| << " State: " << network->state() |
| << " Status: " << status; |
| |
| // If the user asked not to save credentials, shill will have |
| // forgotten them. Wipe our cache as well. |
| if (!network->save_credentials()) |
| network->EraseCredentials(); |
| |
| ClearActiveNetwork(network->type()); |
| UpdateActiveNetwork(network); |
| |
| // Notify observers. |
| NotifyNetworkManagerChanged(true); // Forced update. |
| NotifyUserConnectionInitiated(network); |
| NotifyNetworkChanged(network); |
| } |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| // Request a network and connect to it. |
| |
| // 1. Connect to an unconfigured or unlisted wifi network. |
| // This needs to request information about the named service. |
| // The connection attempt will occur in the callback. |
| void NetworkLibraryImplBase::ConnectToUnconfiguredWifiNetwork( |
| const std::string& ssid, |
| ConnectionSecurity security, |
| const std::string& passphrase, |
| const EAPConfigData* eap_config, |
| bool save_credentials, |
| bool shared) { |
| // Store the connection data to be used by the callback. |
| connect_data_.security = security; |
| connect_data_.service_name = ssid; |
| connect_data_.passphrase = passphrase; |
| connect_data_.save_credentials = save_credentials; |
| connect_data_.profile_type = shared ? PROFILE_SHARED : PROFILE_USER; |
| if (security == SECURITY_8021X) { |
| DCHECK(eap_config); |
| connect_data_.service_name = ssid; |
| connect_data_.eap_method = eap_config->method; |
| connect_data_.eap_auth = eap_config->auth; |
| connect_data_.server_ca_cert_nss_nickname = |
| eap_config->server_ca_cert_nss_nickname; |
| connect_data_.eap_use_system_cas = eap_config->use_system_cas; |
| connect_data_.client_cert_pkcs11_id = |
| eap_config->client_cert_pkcs11_id; |
| connect_data_.eap_identity = eap_config->identity; |
| connect_data_.eap_anonymous_identity = eap_config->anonymous_identity; |
| } |
| |
| CallRequestWifiNetworkAndConnect(ssid, security); |
| } |
| |
| // 1. Connect to a virtual network with a PSK. |
| void NetworkLibraryImplBase::ConnectToUnconfiguredVirtualNetwork( |
| const std::string& service_name, |
| const std::string& server_hostname, |
| ProviderType provider_type, |
| const VPNConfigData& config) { |
| // Store the connection data to be used by the callback. |
| connect_data_.service_name = service_name; |
| connect_data_.server_hostname = server_hostname; |
| connect_data_.psk_key = config.psk; |
| connect_data_.server_ca_cert_nss_nickname = |
| config.server_ca_cert_nss_nickname; |
| connect_data_.client_cert_pkcs11_id = config.client_cert_pkcs11_id; |
| connect_data_.username = config.username; |
| connect_data_.passphrase = config.user_passphrase; |
| connect_data_.otp = config.otp; |
| connect_data_.group_name = config.group_name; |
| CallRequestVirtualNetworkAndConnect( |
| service_name, server_hostname, provider_type); |
| } |
| |
| // 2. Requests a WiFi Network by SSID and security. |
| // Calls ConnectToWifiNetworkUsingConnectData if network request succeeds. |
| // virtual void CallRequestWifiNetworkAndConnect( |
| // const std::string& ssid, ConnectionSecurity security) = 0; |
| |
| // 2. Requests a Virtual Network by service name, etc. |
| // Calls ConnectToVirtualNetworkUsingConnectData if network request succeeds. |
| // virtual void CallRequestVirtualNetworkAndConnect( |
| // const std::string& service_name, |
| // const std::string& server_hostname, |
| // ProviderType provider_type) = 0; |
| |
| // 3. Sets network properties stored in ConnectData and calls |
| // NetworkConnectStart. |
| void NetworkLibraryImplBase::ConnectToWifiNetworkUsingConnectData( |
| WifiNetwork* wifi) { |
| ConnectData& data = connect_data_; |
| if (wifi->name() != data.service_name) { |
| LOG(WARNING) << "WiFi network name does not match ConnectData: " |
| << wifi->name() << " != " << data.service_name; |
| return; |
| } |
| wifi->set_added(true); |
| if (data.security == SECURITY_8021X) { |
| // Enterprise 802.1X EAP network. |
| wifi->SetEAPMethod(data.eap_method); |
| wifi->SetEAPPhase2Auth(data.eap_auth); |
| wifi->SetEAPServerCaCertNssNickname(data.server_ca_cert_nss_nickname); |
| wifi->SetEAPUseSystemCAs(data.eap_use_system_cas); |
| wifi->SetEAPClientCertPkcs11Id(data.client_cert_pkcs11_id); |
| wifi->SetEAPIdentity(data.eap_identity); |
| wifi->SetEAPAnonymousIdentity(data.eap_anonymous_identity); |
| wifi->SetEAPPassphrase(data.passphrase); |
| wifi->SetSaveCredentials(data.save_credentials); |
| } else { |
| // Ordinary, non-802.1X network. |
| wifi->SetPassphrase(data.passphrase); |
| } |
| |
| NetworkConnectStartWifi(wifi, data.profile_type); |
| } |
| |
| // 3. Sets network properties stored in ConnectData and calls |
| // ConnectToVirtualNetwork. |
| void NetworkLibraryImplBase::ConnectToVirtualNetworkUsingConnectData( |
| VirtualNetwork* vpn) { |
| ConnectData& data = connect_data_; |
| if (vpn->name() != data.service_name) { |
| LOG(WARNING) << "Virtual network name does not match ConnectData: " |
| << vpn->name() << " != " << data.service_name; |
| return; |
| } |
| |
| // When a L2TP/IPsec certificate-based VPN is created, the VirtualNetwork |
| // instance is created by NativeNetworkParser::CreateNetworkFromInfo(). |
| // At that point, the provider type is deduced based on the value of |
| // client_cert_id_ of the VirtualNetwork instance, which hasn't been |
| // updated to the value of connect_data_.client_cert_pkcs11_id. Thus, |
| // the provider type is always incorrectly set to L2TP_IPSEC_PSK when |
| // L2TP_IPSEC_USER_CERT is expected. Here we fix the provider type based |
| // on connect_data_.client_cert_pkcs11_id. |
| // |
| // TODO(benchan): This is a quick and dirty workaround, we should refactor |
| // the code to make the flow more straightforward. See crosbug.com/24636 |
| if (vpn->provider_type() == PROVIDER_TYPE_L2TP_IPSEC_PSK && |
| !connect_data_.client_cert_pkcs11_id.empty()) { |
| vpn->set_provider_type(PROVIDER_TYPE_L2TP_IPSEC_USER_CERT); |
| } |
| |
| vpn->set_added(true); |
| if (!data.server_hostname.empty()) |
| vpn->set_server_hostname(data.server_hostname); |
| |
| vpn->SetCACertNSS(data.server_ca_cert_nss_nickname); |
| switch (vpn->provider_type()) { |
| case PROVIDER_TYPE_L2TP_IPSEC_PSK: |
| vpn->SetL2TPIPsecPSKCredentials( |
| data.psk_key, data.username, data.passphrase, data.group_name); |
| break; |
| case PROVIDER_TYPE_L2TP_IPSEC_USER_CERT: { |
| vpn->SetL2TPIPsecCertCredentials( |
| data.client_cert_pkcs11_id, |
| data.username, data.passphrase, data.group_name); |
| break; |
| } |
| case PROVIDER_TYPE_OPEN_VPN: { |
| vpn->SetOpenVPNCredentials( |
| data.client_cert_pkcs11_id, |
| data.username, data.passphrase, data.otp); |
| break; |
| } |
| case PROVIDER_TYPE_MAX: |
| NOTREACHED(); |
| break; |
| } |
| |
| NetworkConnectStartVPN(vpn); |
| } |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| |
| void NetworkLibraryImplBase::ForgetNetwork(const std::string& service_path) { |
| // Remove network from remembered list and notify observers. |
| DeleteRememberedNetwork(service_path); |
| NotifyNetworkManagerChanged(true); // Forced update. |
| } |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| |
| void NetworkLibraryImplBase::EnableEthernetNetworkDevice(bool enable) { |
| if (is_locked_) |
| return; |
| CallEnableNetworkDeviceType(TYPE_ETHERNET, enable); |
| } |
| |
| void NetworkLibraryImplBase::EnableWifiNetworkDevice(bool enable) { |
| if (is_locked_) |
| return; |
| CallEnableNetworkDeviceType(TYPE_WIFI, enable); |
| } |
| |
| void NetworkLibraryImplBase::EnableMobileNetworkDevice(bool enable) { |
| EnableWimaxNetworkDevice(enable); |
| EnableCellularNetworkDevice(enable); |
| } |
| |
| void NetworkLibraryImplBase::EnableWimaxNetworkDevice(bool enable) { |
| if (is_locked_) |
| return; |
| CallEnableNetworkDeviceType(TYPE_WIMAX, enable); |
| } |
| |
| void NetworkLibraryImplBase::EnableCellularNetworkDevice(bool enable) { |
| if (is_locked_) |
| return; |
| CallEnableNetworkDeviceType(TYPE_CELLULAR, enable); |
| } |
| |
| void NetworkLibraryImplBase::SwitchToPreferredNetwork() { |
| // If current network (if any) is not preferred, check network service list to |
| // see if the first not connected network is preferred and set to autoconnect. |
| // If so, connect to it. |
| if (!wifi_enabled() || (active_wifi_ && active_wifi_->preferred())) |
| return; |
| for (WifiNetworkVector::const_iterator it = wifi_networks_.begin(); |
| it != wifi_networks_.end(); ++it) { |
| WifiNetwork* wifi = *it; |
| if (wifi->connected() || wifi->connecting()) // Skip connected/connecting. |
| continue; |
| if (!wifi->preferred()) // All preferred networks are sorted in front. |
| break; |
| if (wifi->auto_connect()) { |
| ConnectToWifiNetwork(wifi); |
| break; |
| } |
| } |
| } |
| |
| bool NetworkLibraryImplBase::LoadOncNetworks(const std::string& onc_blob, |
| const std::string& passphrase, |
| NetworkUIData::ONCSource source, |
| bool allow_web_trust_from_policy, |
| std::string* error) { |
| OncNetworkParser parser(onc_blob, passphrase, source); |
| parser.set_allow_web_trust_from_policy(allow_web_trust_from_policy); |
| |
| if (!parser.parse_error().empty()) { |
| if (error) |
| *error = parser.parse_error(); |
| return false; |
| } |
| |
| for (int i = 0; i < parser.GetCertificatesSize(); i++) { |
| // Insert each of the available certs into the certificate DB. |
| if (parser.ParseCertificate(i).get() == NULL && |
| !parser.parse_error().empty()) { |
| DLOG(WARNING) << "Cannot parse certificate in ONC file"; |
| if (error) |
| *error = parser.parse_error(); |
| return false; |
| } |
| } |
| |
| // Parse all networks. Bail out if that fails. |
| NetworkOncMap added_onc_map; |
| ScopedVector<Network> networks; |
| std::set<std::string> removal_ids; |
| for (int i = 0; i < parser.GetNetworkConfigsSize(); i++) { |
| // Parse Open Network Configuration blob into a temporary Network object. |
| bool marked_for_removal = false; |
| Network* network = parser.ParseNetwork(i, &marked_for_removal); |
| if (!network) { |
| DLOG(WARNING) << "Cannot parse network in ONC file"; |
| if (error) |
| *error = parser.parse_error(); |
| return false; |
| } |
| |
| // Disallow anything but WiFi and Ethernet for device-level policy (which |
| // corresponds to shared networks). See also http://crosbug.com/28741. |
| if (source == NetworkUIData::ONC_SOURCE_DEVICE_POLICY && |
| network->type() != TYPE_WIFI && |
| network->type() != TYPE_ETHERNET) { |
| LOG(WARNING) << "Ignoring device-level policy-pushed network of type " |
| << network->type(); |
| delete network; |
| continue; |
| } |
| |
| networks.push_back(network); |
| if (!(source == NetworkUIData::ONC_SOURCE_USER_IMPORT && |
| marked_for_removal)) |
| added_onc_map[network->unique_id()] = parser.GetNetworkConfig(i); |
| |
| if (marked_for_removal) |
| removal_ids.insert(network->unique_id()); |
| } |
| |
| // Update the ONC map. |
| for (NetworkOncMap::iterator iter(added_onc_map.begin()); |
| iter != added_onc_map.end(); ++iter) { |
| const base::DictionaryValue*& entry = network_onc_map_[iter->first]; |
| delete entry; |
| entry = iter->second->DeepCopy(); |
| } |
| |
| // Configure the networks. While doing so, collect unique identifiers of the |
| // networks that are defined in the ONC blob in |network_ids|. They're later |
| // used to clean out any previously-existing networks that had been configured |
| // through policy but are no longer specified in the updated ONC blob. |
| std::string profile_path(GetProfilePath(GetProfileTypeForSource(source))); |
| std::set<std::string>& network_ids(network_source_map_[source]); |
| network_ids.clear(); |
| for (std::vector<Network*>::iterator iter(networks.begin()); |
| iter != networks.end(); ++iter) { |
| Network* network = *iter; |
| |
| // Don't configure a network that is supposed to be removed. For |
| // policy-managed networks, the "remove" functionality of ONC is ignored. |
| if (source == NetworkUIData::ONC_SOURCE_USER_IMPORT && |
| removal_ids.find(network->unique_id()) != removal_ids.end()) { |
| continue; |
| } |
| |
| DictionaryValue dict; |
| for (Network::PropertyMap::const_iterator props = |
| network->property_map_.begin(); |
| props != network->property_map_.end(); ++props) { |
| std::string key = |
| NativeNetworkParser::property_mapper()->GetKey(props->first); |
| if (!key.empty()) |
| dict.SetWithoutPathExpansion(key, props->second->DeepCopy()); |
| else |
| VLOG(2) << "Property " << props->first << " will not be sent"; |
| } |
| |
| // Set the appropriate profile for |source|. |
| if (!profile_path.empty()) |
| dict.SetString(flimflam::kProfileProperty, profile_path); |
| |
| // For Ethernet networks, apply them to the current Ethernet service. |
| if (network->type() == TYPE_ETHERNET) { |
| const EthernetNetwork* ethernet = ethernet_network(); |
| if (ethernet) { |
| CallConfigureService(ethernet->unique_id(), &dict); |
| } else { |
| DLOG(WARNING) << "Tried to import ONC with an Ethernet network when " |
| << "there is no active Ethernet connection."; |
| } |
| } else { |
| CallConfigureService(network->unique_id(), &dict); |
| } |
| |
| network_ids.insert(network->unique_id()); |
| } |
| |
| if (source == NetworkUIData::ONC_SOURCE_USER_POLICY || |
| source == NetworkUIData::ONC_SOURCE_DEVICE_POLICY) { |
| // For policy-managed networks, go through the list of existing remembered |
| // networks and clean out the ones that no longer have a definition in the |
| // ONC blob. We first collect the networks and do the actual deletion later |
| // because ForgetNetwork() changes the remembered network vectors. |
| ForgetNetworksById(source, network_ids, false); |
| } else if (source == NetworkUIData::ONC_SOURCE_USER_IMPORT) { |
| // User-imported files should always contain something. |
| if (parser.GetNetworkConfigsSize() == 0 && |
| parser.GetCertificatesSize() == 0) { |
| LOG(ERROR) << "ONC file contains no networks or certificates."; |
| if (error) { |
| *error = l10n_util::GetStringUTF8( |
| IDS_NETWORK_CONFIG_ERROR_NETWORK_IMPORT); |
| } |
| return false; |
| } |
| |
| if (removal_ids.empty()) |
| return true; |
| |
| ForgetNetworksById(source, removal_ids, true); |
| } |
| |
| return true; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////// |
| // Testing functions. |
| |
| bool NetworkLibraryImplBase::SetActiveNetwork( |
| ConnectionType type, const std::string& service_path) { |
| Network* network = NULL; |
| if (!service_path.empty()) |
| network = FindNetworkByPath(service_path); |
| if (network && network->type() != type) { |
| LOG(WARNING) << "SetActiveNetwork type mismatch for: " << network->name(); |
| return false; |
| } |
| |
| ClearActiveNetwork(type); |
| |
| if (!network) |
| return true; |
| |
| // Set |network| to active. |
| UpdateActiveNetwork(network); |
| return true; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////// |
| // Network list management functions. |
| |
| // Note: sometimes shill still returns networks when the device type is |
| // disabled. Always check the appropriate enabled() state before adding |
| // networks to a list or setting an active network so that we do not show them |
| // in the UI. |
| |
| // This relies on services being requested from shill in priority order, |
| // and the updates getting processed and received in order. |
| void NetworkLibraryImplBase::UpdateActiveNetwork(Network* network) { |
| network->set_is_active(true); |
| ConnectionType type(network->type()); |
| if (type == TYPE_ETHERNET) { |
| if (ethernet_enabled()) { |
| // Set ethernet_ to the first connected ethernet service, or the first |
| // disconnected ethernet service if none are connected. |
| if (ethernet_ == NULL || !ethernet_->connected()) { |
| ethernet_ = static_cast<EthernetNetwork*>(network); |
| VLOG(2) << "Active ethernet -> " << ethernet_->name(); |
| } |
| } |
| } else if (type == TYPE_WIFI) { |
| if (wifi_enabled()) { |
| // Set active_wifi_ to the first connected or connecting wifi service. |
| if (active_wifi_ == NULL && network->connecting_or_connected()) { |
| active_wifi_ = static_cast<WifiNetwork*>(network); |
| VLOG(2) << "Active wifi -> " << active_wifi_->name(); |
| } |
| } |
| } else if (type == TYPE_CELLULAR) { |
| if (cellular_enabled()) { |
| // Set active_cellular_ to first connected/connecting celluar service. |
| if (active_cellular_ == NULL && network->connecting_or_connected()) { |
| active_cellular_ = static_cast<CellularNetwork*>(network); |
| VLOG(2) << "Active cellular -> " << active_cellular_->name(); |
| } |
| } |
| } else if (type == TYPE_WIMAX) { |
| if (wimax_enabled()) { |
| // Set active_wimax_ to first connected/connecting wimax service. |
| if (active_wimax_ == NULL && network->connecting_or_connected()) { |
| active_wimax_ = static_cast<WimaxNetwork*>(network); |
| VLOG(2) << "Active wimax -> " << active_wimax_->name(); |
| } |
| } |
| } else if (type == TYPE_VPN) { |
| // Set active_virtual_ to the first connected or connecting vpn service. { |
| if (active_virtual_ == NULL && network->connecting_or_connected()) { |
| active_virtual_ = static_cast<VirtualNetwork*>(network); |
| VLOG(2) << "Active virtual -> " << active_virtual_->name(); |
| } |
| } |
| } |
| |
| void NetworkLibraryImplBase::ClearActiveNetwork(ConnectionType type) { |
| // Clear any existing active network matching |type|. |
| for (NetworkMap::iterator iter = network_map_.begin(); |
| iter != network_map_.end(); ++iter) { |
| Network* other = iter->second; |
| if (other->type() == type) |
| other->set_is_active(false); |
| } |
| switch (type) { |
| case TYPE_ETHERNET: |
| ethernet_ = NULL; |
| break; |
| case TYPE_WIFI: |
| active_wifi_ = NULL; |
| break; |
| case TYPE_CELLULAR: |
| active_cellular_ = NULL; |
| break; |
| case TYPE_WIMAX: |
| active_wimax_ = NULL; |
| break; |
| case TYPE_VPN: |
| active_virtual_ = NULL; |
| break; |
| default: |
| break; |
| } |
| } |
| |
| void NetworkLibraryImplBase::AddNetwork(Network* network) { |
| std::pair<NetworkMap::iterator, bool> result = |
| network_map_.insert(std::make_pair(network->service_path(), network)); |
| DCHECK(result.second); // Should only get called with new network. |
| VLOG(2) << "Adding Network: " << network->service_path() |
| << " (" << network->name() << ")"; |
| ConnectionType type(network->type()); |
| if (type == TYPE_WIFI) { |
| if (wifi_enabled()) |
| wifi_networks_.push_back(static_cast<WifiNetwork*>(network)); |
| } else if (type == TYPE_CELLULAR) { |
| if (cellular_enabled()) |
| cellular_networks_.push_back(static_cast<CellularNetwork*>(network)); |
| } else if (type == TYPE_WIMAX) { |
| if (wimax_enabled()) |
| wimax_networks_.push_back(static_cast<WimaxNetwork*>(network)); |
| } else if (type == TYPE_VPN) { |
| virtual_networks_.push_back(static_cast<VirtualNetwork*>(network)); |
| } |
| // Do not set the active network here. Wait until we parse the network. |
| } |
| |
| // Deletes a network. It must already be removed from any lists. |
| void NetworkLibraryImplBase::DeleteNetwork(Network* network) { |
| CHECK(network_map_.find(network->service_path()) == network_map_.end()); |
| if (network->type() == TYPE_CELLULAR) { |
| // Find and delete any existing data plans associated with |service_path|. |
| CellularDataPlanMap::iterator found = |
| data_plan_map_.find(network->service_path()); |
| if (found != data_plan_map_.end()) { |
| CellularDataPlanVector* data_plan_vector = found->second; |
| delete data_plan_vector; |
| data_plan_map_.erase(found); |
| } |
| } |
| delete network; |
| } |
| |
| void NetworkLibraryImplBase::ForgetNetworksById( |
| NetworkUIData::ONCSource source, |
| std::set<std::string> ids, |
| bool if_found) { |
| std::vector<std::string> to_be_forgotten; |
| for (WifiNetworkVector::iterator i = remembered_wifi_networks_.begin(); |
| i != remembered_wifi_networks_.end(); ++i) { |
| WifiNetwork* wifi_network = *i; |
| if (wifi_network->ui_data().onc_source() == source && |
| if_found == (ids.find(wifi_network->unique_id()) != ids.end())) |
| to_be_forgotten.push_back(wifi_network->service_path()); |
| } |
| |
| for (VirtualNetworkVector::iterator i = remembered_virtual_networks_.begin(); |
| i != remembered_virtual_networks_.end(); ++i) { |
| VirtualNetwork* virtual_network = *i; |
| if (virtual_network->ui_data().onc_source() == source && |
| if_found == (ids.find(virtual_network->unique_id()) != ids.end())) |
| to_be_forgotten.push_back(virtual_network->service_path()); |
| } |
| |
| for (std::vector<std::string>::const_iterator i = to_be_forgotten.begin(); |
| i != to_be_forgotten.end(); ++i) { |
| ForgetNetwork(*i); |
| } |
| } |
| |
| bool NetworkLibraryImplBase::ValidateRememberedNetwork(Network* network) { |
| std::pair<NetworkMap::iterator, bool> result = |
| remembered_network_map_.insert( |
| std::make_pair(network->service_path(), network)); |
| DCHECK(result.second); // Should only get called with new network. |
| |
| // See if this is a policy-configured network that has meanwhile been removed. |
| // This situation may arise when the full list of remembered networks is not |
| // available to LoadOncNetworks(), which can happen due to the asynchronous |
| // communication between shill and NetworkLibrary. Just tell shill to |
| // delete the network now. |
| const NetworkUIData::ONCSource source = network->ui_data().onc_source(); |
| if (source == NetworkUIData::ONC_SOURCE_USER_POLICY || |
| source == NetworkUIData::ONC_SOURCE_DEVICE_POLICY) { |
| NetworkSourceMap::const_iterator network_id_set( |
| network_source_map_.find(source)); |
| if (network_id_set != network_source_map_.end() && |
| network_id_set->second.find(network->unique_id()) == |
| network_id_set->second.end()) { |
| DeleteRememberedNetwork(network->service_path()); |
| return false; |
| } |
| } |
| |
| return true; |
| } |
| |
| bool NetworkLibraryImplBase::ValidateAndAddRememberedNetwork(Network* network) { |
| if (!ValidateRememberedNetwork(network)) |
| return false; |
| |
| if (network->type() == TYPE_WIFI) { |
| remembered_wifi_networks_.push_back( |
| static_cast<WifiNetwork*>(network)); |
| } else if (network->type() == TYPE_VPN) { |
| remembered_virtual_networks_.push_back( |
| static_cast<VirtualNetwork*>(network)); |
| } else { |
| NOTREACHED(); |
| } |
| // Find service path in profiles. Shill does not set the Profile |
| // property for remembered networks, only active networks. |
| for (NetworkProfileList::iterator iter = profile_list_.begin(); |
| iter != profile_list_.end(); ++iter) { |
| NetworkProfile& profile = *iter; |
| if (profile.services.find(network->service_path()) != |
| profile.services.end()) { |
| network->set_profile_path(profile.path); |
| network->set_profile_type(profile.type); |
| VLOG(1) << "ValidateAndAddRememberedNetwork: " << network->service_path() |
| << " profile: " << profile.path; |
| break; |
| } |
| } |
| DCHECK(!network->profile_path().empty()) |
| << "Service path not in any profile: " << network->service_path(); |
| return true; |
| } |
| |
| void NetworkLibraryImplBase::DeleteRememberedNetwork( |
| const std::string& service_path) { |
| NetworkMap::iterator found = remembered_network_map_.find(service_path); |
| if (found == remembered_network_map_.end()) { |
| LOG(WARNING) << "Attempt to delete non-existent remembered network: " |
| << service_path; |
| return; |
| } |
| Network* remembered_network = found->second; |
| VLOG(1) << "Deleting remembered network: " |
| << remembered_network->service_path(); |
| |
| // Update any associated network service before removing from profile |
| // so that shill doesn't recreate the service (e.g. when we disconenct it). |
| Network* network = FindNetworkByUniqueId(remembered_network->unique_id()); |
| if (network) { |
| // Clear the stored credentials for any forgotten networks. |
| network->EraseCredentials(); |
| network->ClearUIData(); |
| SetProfileType(network, PROFILE_NONE); |
| // Remove VPN from list of networks. |
| if (network->type() == TYPE_VPN) |
| CallRemoveNetwork(network); |
| } else { |
| // Network is not in service list. |
| VLOG(2) << "Remembered Network not in service list: " |
| << remembered_network->unique_id(); |
| } |
| |
| // Delete remembered network from lists. |
| remembered_network_map_.erase(found); |
| |
| if (remembered_network->type() == TYPE_WIFI) { |
| WifiNetworkVector::iterator iter = std::find( |
| remembered_wifi_networks_.begin(), |
| remembered_wifi_networks_.end(), |
| remembered_network); |
| if (iter != remembered_wifi_networks_.end()) |
| remembered_wifi_networks_.erase(iter); |
| } else if (remembered_network->type() == TYPE_VPN) { |
| VirtualNetworkVector::iterator iter = std::find( |
| remembered_virtual_networks_.begin(), |
| remembered_virtual_networks_.end(), |
| remembered_network); |
| if (iter != remembered_virtual_networks_.end()) |
| remembered_virtual_networks_.erase(iter); |
| } |
| |
| // Delete remembered network from all profiles it is in. |
| for (NetworkProfileList::iterator iter = profile_list_.begin(); |
| iter != profile_list_.end(); ++iter) { |
| NetworkProfile& profile = *iter; |
| NetworkProfile::ServiceList::iterator found = |
| profile.services.find(remembered_network->service_path()); |
| if (found != profile.services.end()) { |
| VLOG(1) << "Deleting: " << remembered_network->service_path() |
| << " From: " << profile.path; |
| CallDeleteRememberedNetwork(profile.path, |
| remembered_network->service_path()); |
| profile.services.erase(found); |
| } |
| } |
| |
| // Remove the ONC blob for the network, if present. |
| NetworkOncMap::iterator onc_map_entry = |
| network_onc_map_.find(remembered_network->unique_id()); |
| if (onc_map_entry != network_onc_map_.end()) { |
| delete onc_map_entry->second; |
| network_onc_map_.erase(onc_map_entry); |
| } |
| |
| delete remembered_network; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////// |
| |
| void NetworkLibraryImplBase::ClearNetworks() { |
| network_map_.clear(); |
| network_unique_id_map_.clear(); |
| ethernet_ = NULL; |
| active_wifi_ = NULL; |
| active_cellular_ = NULL; |
| active_wimax_ = NULL; |
| active_virtual_ = NULL; |
| wifi_networks_.clear(); |
| cellular_networks_.clear(); |
| wimax_networks_.clear(); |
| virtual_networks_.clear(); |
| } |
| |
| void NetworkLibraryImplBase::ClearRememberedNetworks() { |
| remembered_network_map_.clear(); |
| remembered_network_unique_id_map_.clear(); |
| remembered_wifi_networks_.clear(); |
| remembered_virtual_networks_.clear(); |
| } |
| |
| void NetworkLibraryImplBase::DeleteNetworks() { |
| STLDeleteValues(&network_map_); |
| ClearNetworks(); |
| } |
| |
| void NetworkLibraryImplBase::DeleteRememberedNetworks() { |
| STLDeleteValues(&remembered_network_map_); |
| ClearRememberedNetworks(); |
| } |
| |
| void NetworkLibraryImplBase::DeleteDevice(const std::string& device_path) { |
| NetworkDeviceMap::iterator found = device_map_.find(device_path); |
| if (found == device_map_.end()) { |
| LOG(WARNING) << "Attempt to delete non-existent device: " |
| << device_path; |
| return; |
| } |
| VLOG(2) << " Deleting device: " << device_path; |
| NetworkDevice* device = found->second; |
| device_map_.erase(found); |
| delete device; |
| DeleteDeviceFromDeviceObserversMap(device_path); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////// |
| |
| void NetworkLibraryImplBase::AddProfile( |
| const std::string& profile_path, NetworkProfileType profile_type) { |
| profile_list_.push_back(NetworkProfile(profile_path, profile_type)); |
| // Check to see if we connected to any networks before a user profile was |
| // available (i.e. before login), but unchecked the "Share" option (i.e. |
| // the desired pofile is the user profile). Move these networks to the |
| // user profile when it becomes available. |
| if (profile_type == PROFILE_USER && !user_networks_.empty()) { |
| for (std::list<std::string>::iterator iter2 = user_networks_.begin(); |
| iter2 != user_networks_.end(); ++iter2) { |
| Network* network = FindNetworkByPath(*iter2); |
| if (network && network->profile_path() != profile_path) |
| network->SetProfilePath(profile_path); |
| } |
| user_networks_.clear(); |
| } |
| } |
| |
| NetworkLibraryImplBase::NetworkProfile* |
| NetworkLibraryImplBase::GetProfileForType(NetworkProfileType type) { |
| for (NetworkProfileList::iterator iter = profile_list_.begin(); |
| iter != profile_list_.end(); ++iter) { |
| NetworkProfile& profile = *iter; |
| if (profile.type == type) |
| return &profile; |
| } |
| return NULL; |
| } |
| |
| void NetworkLibraryImplBase::SetProfileType( |
| Network* network, NetworkProfileType type) { |
| if (type == PROFILE_NONE) { |
| network->SetProfilePath(std::string()); |
| network->set_profile_type(PROFILE_NONE); |
| } else { |
| std::string profile_path = GetProfilePath(type); |
| if (!profile_path.empty()) { |
| network->SetProfilePath(profile_path); |
| network->set_profile_type(type); |
| } else { |
| LOG(WARNING) << "Profile type not found: " << type; |
| network->set_profile_type(PROFILE_NONE); |
| } |
| } |
| } |
| |
| void NetworkLibraryImplBase::SetProfileTypeFromPath(Network* network) { |
| if (network->profile_path().empty()) { |
| network->set_profile_type(PROFILE_NONE); |
| return; |
| } |
| for (NetworkProfileList::iterator iter = profile_list_.begin(); |
| iter != profile_list_.end(); ++iter) { |
| NetworkProfile& profile = *iter; |
| if (profile.path == network->profile_path()) { |
| network->set_profile_type(profile.type); |
| return; |
| } |
| } |
| LOG(WARNING) << "Profile path not found: " << network->profile_path(); |
| network->set_profile_type(PROFILE_NONE); |
| } |
| |
| std::string NetworkLibraryImplBase::GetProfilePath(NetworkProfileType type) { |
| std::string profile_path; |
| NetworkProfile* profile = GetProfileForType(type); |
| if (profile) |
| profile_path = profile->path; |
| return profile_path; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////// |
| // Notifications. |
| |
| // We call this any time something in NetworkLibrary changes. |
| // TODO(stevenjb): We should consider breaking this into multiple |
| // notifications, e.g. connection state, devices, services, etc. |
| void NetworkLibraryImplBase::NotifyNetworkManagerChanged(bool force_update) { |
| // Cancel any pending signals. |
| notify_manager_weak_factory_.InvalidateWeakPtrs(); |
| if (force_update) { |
| // Signal observers now. |
| SignalNetworkManagerObservers(); |
| } else { |
| // Schedule a delayed signal to limit the frequency of notifications. |
| BrowserThread::PostDelayedTask( |
| BrowserThread::UI, |
| FROM_HERE, |
| base::Bind(&NetworkLibraryImplBase::SignalNetworkManagerObservers, |
| notify_manager_weak_factory_.GetWeakPtr()), |
| base::TimeDelta::FromMilliseconds(kNetworkNotifyDelayMs)); |
| } |
| } |
| |
| void NetworkLibraryImplBase::SignalNetworkManagerObservers() { |
| FOR_EACH_OBSERVER(NetworkManagerObserver, |
| network_manager_observers_, |
| OnNetworkManagerChanged(this)); |
| // Clear notification flags. |
| for (NetworkMap::iterator iter = network_map_.begin(); |
| iter != network_map_.end(); ++iter) { |
| iter->second->set_notify_failure(false); |
| } |
| } |
| |
| void NetworkLibraryImplBase::NotifyNetworkChanged(const Network* network) { |
| DCHECK(network); |
| VLOG(2) << "Network changed: " << network->name(); |
| NetworkObserverMap::const_iterator iter = network_observers_.find( |
| network->service_path()); |
| if (iter != network_observers_.end()) { |
| FOR_EACH_OBSERVER(NetworkObserver, |
| *(iter->second), |
| OnNetworkChanged(this, network)); |
| } else if (IsCros()) { |
| LOG(ERROR) << "Unexpected signal for unobserved network: " |
| << network->name(); |
| } |
| } |
| |
| void NetworkLibraryImplBase::NotifyNetworkDeviceChanged( |
| NetworkDevice* device, PropertyIndex index) { |
| DCHECK(device); |
| VLOG(2) << "Network device changed: " << device->name(); |
| NetworkDeviceObserverMap::const_iterator iter = |
| network_device_observers_.find(device->device_path()); |
| if (iter != network_device_observers_.end()) { |
| NetworkDeviceObserverList* device_observer_list = iter->second; |
| if (index == PROPERTY_INDEX_FOUND_NETWORKS) { |
| FOR_EACH_OBSERVER(NetworkDeviceObserver, |
| *device_observer_list, |
| OnNetworkDeviceFoundNetworks(this, device)); |
| } else if (index == PROPERTY_INDEX_SIM_LOCK) { |
| FOR_EACH_OBSERVER(NetworkDeviceObserver, |
| *device_observer_list, |
| OnNetworkDeviceSimLockChanged(this, device)); |
| } |
| FOR_EACH_OBSERVER(NetworkDeviceObserver, |
| *device_observer_list, |
| OnNetworkDeviceChanged(this, device)); |
| } else { |
| LOG(ERROR) << "Unexpected signal for unobserved device: " |
| << device->name(); |
| } |
| } |
| |
| void NetworkLibraryImplBase::NotifyCellularDataPlanChanged() { |
| FOR_EACH_OBSERVER(CellularDataPlanObserver, |
| data_plan_observers_, |
| OnCellularDataPlanChanged(this)); |
| } |
| |
| void NetworkLibraryImplBase::NotifyPinOperationCompleted( |
| PinOperationError error) { |
| FOR_EACH_OBSERVER(PinOperationObserver, |
| pin_operation_observers_, |
| OnPinOperationCompleted(this, error)); |
| sim_operation_ = SIM_OPERATION_NONE; |
| } |
| |
| void NetworkLibraryImplBase::NotifyUserConnectionInitiated( |
| const Network* network) { |
| FOR_EACH_OBSERVER(UserActionObserver, |
| user_action_observers_, |
| OnConnectionInitiated(this, network)); |
| } |
| |
| ////////////////////////////////////////////////////////////////////////////// |
| // Pin related functions. |
| |
| void NetworkLibraryImplBase::GetTpmInfo() { |
| // Avoid making multiple synchronous D-Bus calls to cryptohome by caching |
| // the TPM PIN, which does not change during a session. |
| if (tpm_pin_.empty()) { |
| if (crypto::IsTPMTokenReady()) { |
| std::string tpm_label; |
| crypto::GetTPMTokenInfo(&tpm_label, &tpm_pin_); |
| // VLOG(1) << "TPM Label: " << tpm_label << ", PIN: " << tpm_pin_; |
| // TODO(stevenjb): GetTPMTokenInfo returns a label, but the network |
| // code expects a slot ID. See chromium-os:17998. |
| // For now, use a hard coded, well known slot instead. |
| const char kHardcodedTpmSlot[] = "0"; |
| tpm_slot_ = kHardcodedTpmSlot; |
| } else if (IsCros()) { |
| LOG(WARNING) << "TPM token not ready"; |
| } |
| } |
| } |
| |
| const std::string& NetworkLibraryImplBase::GetTpmSlot() { |
| GetTpmInfo(); |
| return tpm_slot_; |
| } |
| |
| const std::string& NetworkLibraryImplBase::GetTpmPin() { |
| GetTpmInfo(); |
| return tpm_pin_; |
| } |
| |
| } // namespace chromeos |