| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "chrome/browser/chromeos/cros/network_library_impl_base.h" | |
| 6 | |
| 7 #include "base/bind.h" | |
| 8 #include "base/json/json_writer.h" | |
| 9 #include "base/memory/scoped_vector.h" | |
| 10 #include "base/stl_util.h" | |
| 11 #include "base/strings/string_util.h" | |
| 12 #include "chrome/browser/chromeos/cros/network_constants.h" | |
| 13 #include "chrome/browser/chromeos/login/user_manager.h" | |
| 14 #include "chrome/browser/chromeos/net/onc_utils.h" | |
| 15 #include "chromeos/network/network_state_handler.h" | |
| 16 #include "chromeos/network/network_ui_data.h" | |
| 17 #include "chromeos/network/onc/onc_constants.h" | |
| 18 #include "chromeos/network/onc/onc_normalizer.h" | |
| 19 #include "chromeos/network/onc/onc_signature.h" | |
| 20 #include "chromeos/network/onc/onc_translator.h" | |
| 21 #include "chromeos/network/onc/onc_utils.h" | |
| 22 #include "content/public/browser/browser_thread.h" | |
| 23 #include "crypto/nss_util.h" // crypto::GetTPMTokenInfo() for 802.1X and VPN. | |
| 24 #include "third_party/cros_system_api/dbus/service_constants.h" | |
| 25 | |
| 26 using content::BrowserThread; | |
| 27 | |
| 28 namespace chromeos { | |
| 29 | |
| 30 namespace { | |
| 31 | |
| 32 // Only send network change notifications to observers once every 50ms. | |
| 33 const int kNetworkNotifyDelayMs = 50; | |
| 34 | |
| 35 // How long we should remember that cellular plan payment was received. | |
| 36 const int kRecentPlanPaymentHours = 6; | |
| 37 | |
| 38 NetworkProfileType GetProfileTypeForSource(onc::ONCSource source) { | |
| 39 switch (source) { | |
| 40 case onc::ONC_SOURCE_DEVICE_POLICY: | |
| 41 return PROFILE_SHARED; | |
| 42 case onc::ONC_SOURCE_USER_POLICY: | |
| 43 return PROFILE_USER; | |
| 44 case onc::ONC_SOURCE_NONE: | |
| 45 case onc::ONC_SOURCE_USER_IMPORT: | |
| 46 return PROFILE_NONE; | |
| 47 } | |
| 48 NOTREACHED() << "Unknown ONC source " << source; | |
| 49 return PROFILE_NONE; | |
| 50 } | |
| 51 | |
| 52 } // namespace | |
| 53 | |
| 54 NetworkLibraryImplBase::NetworkLibraryImplBase() | |
| 55 : ethernet_(NULL), | |
| 56 active_wifi_(NULL), | |
| 57 active_cellular_(NULL), | |
| 58 active_wimax_(NULL), | |
| 59 active_virtual_(NULL), | |
| 60 available_devices_(0), | |
| 61 uninitialized_devices_(0), | |
| 62 enabled_devices_(0), | |
| 63 busy_devices_(0), | |
| 64 wifi_scanning_(false), | |
| 65 is_locked_(false), | |
| 66 sim_operation_(SIM_OPERATION_NONE), | |
| 67 notify_manager_weak_factory_(this) { | |
| 68 } | |
| 69 | |
| 70 NetworkLibraryImplBase::~NetworkLibraryImplBase() { | |
| 71 network_profile_observers_.Clear(); | |
| 72 network_manager_observers_.Clear(); | |
| 73 pin_operation_observers_.Clear(); | |
| 74 STLDeleteValues(&network_map_); | |
| 75 ClearNetworks(); | |
| 76 DeleteRememberedNetworks(); | |
| 77 STLDeleteValues(&device_map_); | |
| 78 STLDeleteValues(&network_device_observers_); | |
| 79 STLDeleteValues(&network_observers_); | |
| 80 STLDeleteValues(&network_onc_map_); | |
| 81 } | |
| 82 | |
| 83 ////////////////////////////////////////////////////////////////////////////// | |
| 84 // NetworkLibrary implementation. | |
| 85 | |
| 86 void NetworkLibraryImplBase::AddNetworkProfileObserver( | |
| 87 NetworkProfileObserver* observer) { | |
| 88 network_profile_observers_.AddObserver(observer); | |
| 89 } | |
| 90 | |
| 91 void NetworkLibraryImplBase::RemoveNetworkProfileObserver( | |
| 92 NetworkProfileObserver* observer) { | |
| 93 network_profile_observers_.RemoveObserver(observer); | |
| 94 } | |
| 95 | |
| 96 void NetworkLibraryImplBase::AddNetworkManagerObserver( | |
| 97 NetworkManagerObserver* observer) { | |
| 98 if (!network_manager_observers_.HasObserver(observer)) | |
| 99 network_manager_observers_.AddObserver(observer); | |
| 100 } | |
| 101 | |
| 102 void NetworkLibraryImplBase::RemoveNetworkManagerObserver( | |
| 103 NetworkManagerObserver* observer) { | |
| 104 network_manager_observers_.RemoveObserver(observer); | |
| 105 } | |
| 106 | |
| 107 void NetworkLibraryImplBase::AddNetworkObserver( | |
| 108 const std::string& service_path, NetworkObserver* observer) { | |
| 109 // First, add the observer to the callback map. | |
| 110 NetworkObserverMap::iterator iter = network_observers_.find(service_path); | |
| 111 NetworkObserverList* oblist; | |
| 112 if (iter != network_observers_.end()) { | |
| 113 oblist = iter->second; | |
| 114 } else { | |
| 115 oblist = new NetworkObserverList(); | |
| 116 network_observers_[service_path] = oblist; | |
| 117 } | |
| 118 if (observer && !oblist->HasObserver(observer)) | |
| 119 oblist->AddObserver(observer); | |
| 120 MonitorNetworkStart(service_path); | |
| 121 } | |
| 122 | |
| 123 void NetworkLibraryImplBase::RemoveNetworkObserver( | |
| 124 const std::string& service_path, NetworkObserver* observer) { | |
| 125 DCHECK(service_path.size()); | |
| 126 NetworkObserverMap::iterator map_iter = | |
| 127 network_observers_.find(service_path); | |
| 128 if (map_iter != network_observers_.end()) { | |
| 129 map_iter->second->RemoveObserver(observer); | |
| 130 if (!map_iter->second->might_have_observers()) { | |
| 131 MonitorNetworkStop(service_path); | |
| 132 delete map_iter->second; | |
| 133 network_observers_.erase(map_iter); | |
| 134 } | |
| 135 } | |
| 136 } | |
| 137 | |
| 138 void NetworkLibraryImplBase::RemoveObserverForAllNetworks( | |
| 139 NetworkObserver* observer) { | |
| 140 DCHECK(observer); | |
| 141 NetworkObserverMap::iterator map_iter = network_observers_.begin(); | |
| 142 while (map_iter != network_observers_.end()) { | |
| 143 map_iter->second->RemoveObserver(observer); | |
| 144 if (!map_iter->second->might_have_observers()) { | |
| 145 MonitorNetworkStop(map_iter->first); | |
| 146 delete map_iter->second; | |
| 147 network_observers_.erase(map_iter++); | |
| 148 } else { | |
| 149 ++map_iter; | |
| 150 } | |
| 151 } | |
| 152 } | |
| 153 | |
| 154 void NetworkLibraryImplBase::AddNetworkDeviceObserver( | |
| 155 const std::string& device_path, NetworkDeviceObserver* observer) { | |
| 156 // First, add the observer to the callback map. | |
| 157 NetworkDeviceObserverMap::iterator iter = | |
| 158 network_device_observers_.find(device_path); | |
| 159 NetworkDeviceObserverList* oblist; | |
| 160 if (iter != network_device_observers_.end()) { | |
| 161 oblist = iter->second; | |
| 162 } else { | |
| 163 oblist = new NetworkDeviceObserverList(); | |
| 164 network_device_observers_[device_path] = oblist; | |
| 165 } | |
| 166 if (!oblist->HasObserver(observer)) | |
| 167 oblist->AddObserver(observer); | |
| 168 MonitorNetworkDeviceStart(device_path); | |
| 169 } | |
| 170 | |
| 171 void NetworkLibraryImplBase::RemoveNetworkDeviceObserver( | |
| 172 const std::string& device_path, NetworkDeviceObserver* observer) { | |
| 173 DCHECK(device_path.size()); | |
| 174 NetworkDeviceObserverMap::iterator map_iter = | |
| 175 network_device_observers_.find(device_path); | |
| 176 if (map_iter != network_device_observers_.end()) { | |
| 177 map_iter->second->RemoveObserver(observer); | |
| 178 } | |
| 179 } | |
| 180 | |
| 181 void NetworkLibraryImplBase::DeleteDeviceFromDeviceObserversMap( | |
| 182 const std::string& device_path) { | |
| 183 // Delete all device observers associated with this device. | |
| 184 NetworkDeviceObserverMap::iterator map_iter = | |
| 185 network_device_observers_.find(device_path); | |
| 186 if (map_iter != network_device_observers_.end()) { | |
| 187 delete map_iter->second; | |
| 188 network_device_observers_.erase(map_iter); | |
| 189 } | |
| 190 } | |
| 191 | |
| 192 ////////////////////////////////////////////////////////////////////////////// | |
| 193 | |
| 194 void NetworkLibraryImplBase::AddPinOperationObserver( | |
| 195 PinOperationObserver* observer) { | |
| 196 if (!pin_operation_observers_.HasObserver(observer)) | |
| 197 pin_operation_observers_.AddObserver(observer); | |
| 198 } | |
| 199 | |
| 200 void NetworkLibraryImplBase::RemovePinOperationObserver( | |
| 201 PinOperationObserver* observer) { | |
| 202 pin_operation_observers_.RemoveObserver(observer); | |
| 203 } | |
| 204 | |
| 205 const EthernetNetwork* NetworkLibraryImplBase::ethernet_network() const { | |
| 206 return ethernet_; | |
| 207 } | |
| 208 | |
| 209 bool NetworkLibraryImplBase::ethernet_connecting() const { | |
| 210 return ethernet_ ? ethernet_->connecting() : false; | |
| 211 } | |
| 212 bool NetworkLibraryImplBase::ethernet_connected() const { | |
| 213 return ethernet_ ? ethernet_->connected() : false; | |
| 214 } | |
| 215 const WifiNetwork* NetworkLibraryImplBase::wifi_network() const { | |
| 216 return active_wifi_; | |
| 217 } | |
| 218 bool NetworkLibraryImplBase::wifi_connecting() const { | |
| 219 return active_wifi_ ? active_wifi_->connecting() : false; | |
| 220 } | |
| 221 bool NetworkLibraryImplBase::wifi_connected() const { | |
| 222 return active_wifi_ ? active_wifi_->connected() : false; | |
| 223 } | |
| 224 const CellularNetwork* NetworkLibraryImplBase::cellular_network() const { | |
| 225 return active_cellular_; | |
| 226 } | |
| 227 bool NetworkLibraryImplBase::cellular_connecting() const { | |
| 228 return active_cellular_ ? active_cellular_->connecting() : false; | |
| 229 } | |
| 230 bool NetworkLibraryImplBase::cellular_connected() const { | |
| 231 return active_cellular_ ? active_cellular_->connected() : false; | |
| 232 } | |
| 233 const WimaxNetwork* NetworkLibraryImplBase::wimax_network() const { | |
| 234 return active_wimax_; | |
| 235 } | |
| 236 bool NetworkLibraryImplBase::wimax_connecting() const { | |
| 237 return active_wimax_ ? active_wimax_->connecting() : false; | |
| 238 } | |
| 239 bool NetworkLibraryImplBase::wimax_connected() const { | |
| 240 return active_wimax_ ? active_wimax_->connected() : false; | |
| 241 } | |
| 242 const VirtualNetwork* NetworkLibraryImplBase::virtual_network() const { | |
| 243 return active_virtual_; | |
| 244 } | |
| 245 bool NetworkLibraryImplBase::virtual_network_connecting() const { | |
| 246 return active_virtual_ ? active_virtual_->connecting() : false; | |
| 247 } | |
| 248 bool NetworkLibraryImplBase::virtual_network_connected() const { | |
| 249 return active_virtual_ ? active_virtual_->connected() : false; | |
| 250 } | |
| 251 bool NetworkLibraryImplBase::Connected() const { | |
| 252 return ethernet_connected() || wifi_connected() || | |
| 253 cellular_connected() || wimax_connected(); | |
| 254 } | |
| 255 bool NetworkLibraryImplBase::Connecting() const { | |
| 256 return ethernet_connecting() || wifi_connecting() || | |
| 257 cellular_connecting() || wimax_connecting(); | |
| 258 } | |
| 259 const WifiNetworkVector& NetworkLibraryImplBase::wifi_networks() const { | |
| 260 return wifi_networks_; | |
| 261 } | |
| 262 const WifiNetworkVector& | |
| 263 NetworkLibraryImplBase::remembered_wifi_networks() const { | |
| 264 return remembered_wifi_networks_; | |
| 265 } | |
| 266 const CellularNetworkVector& NetworkLibraryImplBase::cellular_networks() const { | |
| 267 return cellular_networks_; | |
| 268 } | |
| 269 const WimaxNetworkVector& NetworkLibraryImplBase::wimax_networks() const { | |
| 270 return wimax_networks_; | |
| 271 } | |
| 272 const VirtualNetworkVector& NetworkLibraryImplBase::virtual_networks() const { | |
| 273 return virtual_networks_; | |
| 274 } | |
| 275 const VirtualNetworkVector& | |
| 276 NetworkLibraryImplBase::remembered_virtual_networks() const { | |
| 277 return remembered_virtual_networks_; | |
| 278 } | |
| 279 | |
| 280 namespace { | |
| 281 | |
| 282 // Use shill's ordering of the services to determine which type of | |
| 283 // network to return (i.e. don't assume priority of network types). | |
| 284 // Note: This does not include any virtual networks. | |
| 285 const Network* highest_priority(const Network* a, const Network*b) { | |
| 286 if (!a) | |
| 287 return b; | |
| 288 if (!b) | |
| 289 return a; | |
| 290 if (b->priority_order() < a->priority_order()) | |
| 291 return b; | |
| 292 return a; | |
| 293 } | |
| 294 | |
| 295 } // namespace | |
| 296 | |
| 297 const Network* NetworkLibraryImplBase::active_network() const { | |
| 298 const Network* result = active_nonvirtual_network(); | |
| 299 if (active_virtual_ && active_virtual_->is_active()) | |
| 300 result = highest_priority(result, active_virtual_); | |
| 301 return result; | |
| 302 } | |
| 303 | |
| 304 const Network* NetworkLibraryImplBase::active_nonvirtual_network() const { | |
| 305 const Network* result = NULL; | |
| 306 if (ethernet_ && ethernet_->is_active()) | |
| 307 result = ethernet_; | |
| 308 if (active_wifi_ && active_wifi_->is_active()) | |
| 309 result = highest_priority(result, active_wifi_); | |
| 310 if (active_cellular_ && active_cellular_->is_active()) | |
| 311 result = highest_priority(result, active_cellular_); | |
| 312 if (active_wimax_ && active_wimax_->is_active()) | |
| 313 result = highest_priority(result, active_wimax_); | |
| 314 return result; | |
| 315 } | |
| 316 | |
| 317 const Network* NetworkLibraryImplBase::connected_network() const { | |
| 318 const Network* result = NULL; | |
| 319 if (ethernet_ && ethernet_->connected()) | |
| 320 result = ethernet_; | |
| 321 if (active_wifi_ && active_wifi_->connected()) | |
| 322 result = highest_priority(result, active_wifi_); | |
| 323 if (active_cellular_ && active_cellular_->connected()) | |
| 324 result = highest_priority(result, active_cellular_); | |
| 325 if (active_wimax_ && active_wimax_->connected()) | |
| 326 result = highest_priority(result, active_wimax_); | |
| 327 return result; | |
| 328 } | |
| 329 | |
| 330 // Connecting order in logical preference. | |
| 331 const Network* NetworkLibraryImplBase::connecting_network() const { | |
| 332 if (ethernet_connecting()) | |
| 333 return ethernet_network(); | |
| 334 else if (wifi_connecting()) | |
| 335 return wifi_network(); | |
| 336 else if (cellular_connecting()) | |
| 337 return cellular_network(); | |
| 338 else if (wimax_connecting()) | |
| 339 return wimax_network(); | |
| 340 return NULL; | |
| 341 } | |
| 342 | |
| 343 bool NetworkLibraryImplBase::ethernet_available() const { | |
| 344 return available_devices_ & (1 << TYPE_ETHERNET); | |
| 345 } | |
| 346 | |
| 347 bool NetworkLibraryImplBase::wifi_available() const { | |
| 348 return available_devices_ & (1 << TYPE_WIFI); | |
| 349 } | |
| 350 | |
| 351 bool NetworkLibraryImplBase::wimax_available() const { | |
| 352 return available_devices_ & (1 << TYPE_WIMAX); | |
| 353 } | |
| 354 | |
| 355 bool NetworkLibraryImplBase::cellular_available() const { | |
| 356 return available_devices_ & (1 << TYPE_CELLULAR); | |
| 357 } | |
| 358 | |
| 359 bool NetworkLibraryImplBase::ethernet_enabled() const { | |
| 360 return enabled_devices_ & (1 << TYPE_ETHERNET); | |
| 361 } | |
| 362 | |
| 363 bool NetworkLibraryImplBase::wifi_enabled() const { | |
| 364 return enabled_devices_ & (1 << TYPE_WIFI); | |
| 365 } | |
| 366 | |
| 367 bool NetworkLibraryImplBase::wimax_enabled() const { | |
| 368 return enabled_devices_ & (1 << TYPE_WIMAX); | |
| 369 } | |
| 370 | |
| 371 bool NetworkLibraryImplBase::cellular_enabled() const { | |
| 372 return enabled_devices_ & (1 << TYPE_CELLULAR); | |
| 373 } | |
| 374 | |
| 375 bool NetworkLibraryImplBase::wifi_scanning() const { | |
| 376 return wifi_scanning_; | |
| 377 } | |
| 378 | |
| 379 bool NetworkLibraryImplBase::cellular_initializing() const { | |
| 380 if (uninitialized_devices_ & (1 << TYPE_CELLULAR)) | |
| 381 return true; | |
| 382 const NetworkDevice* device = FindDeviceByType(TYPE_CELLULAR); | |
| 383 if (device && device->scanning()) | |
| 384 return true; | |
| 385 return false; | |
| 386 } | |
| 387 | |
| 388 ///////////////////////////////////////////////////////////////////////////// | |
| 389 | |
| 390 const NetworkDevice* NetworkLibraryImplBase::FindNetworkDeviceByPath( | |
| 391 const std::string& path) const { | |
| 392 NetworkDeviceMap::const_iterator iter = device_map_.find(path); | |
| 393 if (iter != device_map_.end()) | |
| 394 return iter->second; | |
| 395 LOG(WARNING) << "Device path not found: " << path; | |
| 396 return NULL; | |
| 397 } | |
| 398 | |
| 399 NetworkDevice* NetworkLibraryImplBase::FindNetworkDeviceByPath( | |
| 400 const std::string& path) { | |
| 401 NetworkDeviceMap::iterator iter = device_map_.find(path); | |
| 402 if (iter != device_map_.end()) | |
| 403 return iter->second; | |
| 404 LOG(WARNING) << "Device path not found: " << path; | |
| 405 return NULL; | |
| 406 } | |
| 407 | |
| 408 const NetworkDevice* NetworkLibraryImplBase::FindCellularDevice() const { | |
| 409 return FindDeviceByType(TYPE_CELLULAR); | |
| 410 } | |
| 411 | |
| 412 const NetworkDevice* NetworkLibraryImplBase::FindMobileDevice() const { | |
| 413 const NetworkDevice* device = FindDeviceByType(TYPE_CELLULAR); | |
| 414 if (device) | |
| 415 return device; | |
| 416 | |
| 417 return FindDeviceByType(TYPE_WIMAX); | |
| 418 } | |
| 419 | |
| 420 Network* NetworkLibraryImplBase::FindNetworkByPath( | |
| 421 const std::string& path) const { | |
| 422 NetworkMap::const_iterator iter = network_map_.find(path); | |
| 423 if (iter != network_map_.end()) | |
| 424 return iter->second; | |
| 425 return NULL; | |
| 426 } | |
| 427 | |
| 428 Network* NetworkLibraryImplBase::FindNetworkByUniqueId( | |
| 429 const std::string& unique_id) const { | |
| 430 NetworkMap::const_iterator found = network_unique_id_map_.find(unique_id); | |
| 431 if (found != network_unique_id_map_.end()) | |
| 432 return found->second; | |
| 433 return NULL; | |
| 434 } | |
| 435 | |
| 436 WirelessNetwork* NetworkLibraryImplBase::FindWirelessNetworkByPath( | |
| 437 const std::string& path) const { | |
| 438 Network* network = FindNetworkByPath(path); | |
| 439 if (network && | |
| 440 (network->type() == TYPE_WIFI || network->type() == TYPE_WIMAX || | |
| 441 network->type() == TYPE_CELLULAR)) | |
| 442 return static_cast<WirelessNetwork*>(network); | |
| 443 return NULL; | |
| 444 } | |
| 445 | |
| 446 WifiNetwork* NetworkLibraryImplBase::FindWifiNetworkByPath( | |
| 447 const std::string& path) const { | |
| 448 Network* network = FindNetworkByPath(path); | |
| 449 if (network && network->type() == TYPE_WIFI) | |
| 450 return static_cast<WifiNetwork*>(network); | |
| 451 return NULL; | |
| 452 } | |
| 453 | |
| 454 WimaxNetwork* NetworkLibraryImplBase::FindWimaxNetworkByPath( | |
| 455 const std::string& path) const { | |
| 456 Network* network = FindNetworkByPath(path); | |
| 457 if (network && (network->type() == TYPE_WIMAX)) | |
| 458 return static_cast<WimaxNetwork*>(network); | |
| 459 return NULL; | |
| 460 } | |
| 461 | |
| 462 CellularNetwork* NetworkLibraryImplBase::FindCellularNetworkByPath( | |
| 463 const std::string& path) const { | |
| 464 Network* network = FindNetworkByPath(path); | |
| 465 if (network && network->type() == TYPE_CELLULAR) | |
| 466 return static_cast<CellularNetwork*>(network); | |
| 467 return NULL; | |
| 468 } | |
| 469 | |
| 470 VirtualNetwork* NetworkLibraryImplBase::FindVirtualNetworkByPath( | |
| 471 const std::string& path) const { | |
| 472 Network* network = FindNetworkByPath(path); | |
| 473 if (network && network->type() == TYPE_VPN) | |
| 474 return static_cast<VirtualNetwork*>(network); | |
| 475 return NULL; | |
| 476 } | |
| 477 | |
| 478 Network* NetworkLibraryImplBase::FindRememberedFromNetwork( | |
| 479 const Network* network) const { | |
| 480 for (NetworkMap::const_iterator iter = remembered_network_map_.begin(); | |
| 481 iter != remembered_network_map_.end(); ++iter) { | |
| 482 if (iter->second->unique_id() == network->unique_id()) | |
| 483 return iter->second; | |
| 484 } | |
| 485 return NULL; | |
| 486 } | |
| 487 | |
| 488 Network* NetworkLibraryImplBase::FindRememberedNetworkByPath( | |
| 489 const std::string& path) const { | |
| 490 NetworkMap::const_iterator iter = remembered_network_map_.find(path); | |
| 491 if (iter != remembered_network_map_.end()) | |
| 492 return iter->second; | |
| 493 return NULL; | |
| 494 } | |
| 495 | |
| 496 const base::DictionaryValue* NetworkLibraryImplBase::FindOncForNetwork( | |
| 497 const std::string& unique_id) const { | |
| 498 NetworkOncMap::const_iterator iter = network_onc_map_.find(unique_id); | |
| 499 return iter != network_onc_map_.end() ? iter->second : NULL; | |
| 500 } | |
| 501 | |
| 502 void NetworkLibraryImplBase::SignalCellularPlanPayment() { | |
| 503 DCHECK(!HasRecentCellularPlanPayment()); | |
| 504 cellular_plan_payment_time_ = base::Time::Now(); | |
| 505 } | |
| 506 | |
| 507 bool NetworkLibraryImplBase::HasRecentCellularPlanPayment() { | |
| 508 return (base::Time::Now() - | |
| 509 cellular_plan_payment_time_).InHours() < kRecentPlanPaymentHours; | |
| 510 } | |
| 511 | |
| 512 const std::string& NetworkLibraryImplBase::GetCellularHomeCarrierId() const { | |
| 513 const NetworkDevice* cellular = FindCellularDevice(); | |
| 514 if (cellular) | |
| 515 return cellular->home_provider_id(); | |
| 516 return EmptyString(); | |
| 517 } | |
| 518 | |
| 519 bool NetworkLibraryImplBase::CellularDeviceUsesDirectActivation() const { | |
| 520 const NetworkDevice* cellular = FindCellularDevice(); | |
| 521 return cellular && (cellular->carrier() == shill::kCarrierSprint); | |
| 522 } | |
| 523 | |
| 524 ///////////////////////////////////////////////////////////////////////////// | |
| 525 // Profiles. | |
| 526 | |
| 527 bool NetworkLibraryImplBase::HasProfileType(NetworkProfileType type) const { | |
| 528 for (NetworkProfileList::const_iterator iter = profile_list_.begin(); | |
| 529 iter != profile_list_.end(); ++iter) { | |
| 530 if ((*iter).type == type) | |
| 531 return true; | |
| 532 } | |
| 533 return false; | |
| 534 } | |
| 535 | |
| 536 NetworkLibraryImplBase::NetworkProfile::NetworkProfile(const std::string& p, | |
| 537 NetworkProfileType t) | |
| 538 : path(p), | |
| 539 type(t) { | |
| 540 } | |
| 541 | |
| 542 NetworkLibraryImplBase::NetworkProfile::~NetworkProfile() {} | |
| 543 | |
| 544 NetworkLibraryImplBase::ConnectData::ConnectData() | |
| 545 : security(SECURITY_NONE), | |
| 546 eap_method(EAP_METHOD_UNKNOWN), | |
| 547 eap_auth(EAP_PHASE_2_AUTH_AUTO), | |
| 548 eap_use_system_cas(false), | |
| 549 save_credentials(false), | |
| 550 profile_type(PROFILE_NONE) { | |
| 551 } | |
| 552 | |
| 553 NetworkLibraryImplBase::ConnectData::~ConnectData() {} | |
| 554 | |
| 555 const NetworkDevice* NetworkLibraryImplBase::FindDeviceByType( | |
| 556 ConnectionType type) const { | |
| 557 for (NetworkDeviceMap::const_iterator iter = device_map_.begin(); | |
| 558 iter != device_map_.end(); ++iter) { | |
| 559 if (iter->second && iter->second->type() == type) | |
| 560 return iter->second; | |
| 561 } | |
| 562 return NULL; | |
| 563 } | |
| 564 | |
| 565 ///////////////////////////////////////////////////////////////////////////// | |
| 566 // Connect to an existing network. | |
| 567 | |
| 568 bool NetworkLibraryImplBase::CanConnectToNetwork(const Network* network) const { | |
| 569 if (!HasProfileType(PROFILE_USER) && network->RequiresUserProfile()) | |
| 570 return false; | |
| 571 return true; | |
| 572 } | |
| 573 | |
| 574 // 1. Request a connection to an existing wifi network. | |
| 575 // Use |shared| to pass along the desired profile type. | |
| 576 void NetworkLibraryImplBase::ConnectToWifiNetwork( | |
| 577 WifiNetwork* wifi, bool shared) { | |
| 578 NetworkConnectStartWifi(wifi, shared ? PROFILE_SHARED : PROFILE_USER); | |
| 579 } | |
| 580 | |
| 581 // 1. Request a connection to an existing wifi network. | |
| 582 void NetworkLibraryImplBase::ConnectToWifiNetwork(WifiNetwork* wifi) { | |
| 583 NetworkConnectStartWifi(wifi, PROFILE_NONE); | |
| 584 } | |
| 585 | |
| 586 // 1. Request a connection to an existing wimax network. | |
| 587 // Use |shared| to pass along the desired profile type. | |
| 588 void NetworkLibraryImplBase::ConnectToWimaxNetwork( | |
| 589 WimaxNetwork* wimax, bool shared) { | |
| 590 NetworkConnectStart(wimax, shared ? PROFILE_SHARED : PROFILE_USER); | |
| 591 } | |
| 592 | |
| 593 // 1. Request a connection to an existing wimax network. | |
| 594 void NetworkLibraryImplBase::ConnectToWimaxNetwork(WimaxNetwork* wimax) { | |
| 595 NetworkConnectStart(wimax, PROFILE_NONE); | |
| 596 } | |
| 597 | |
| 598 // 1. Connect to a cellular network. | |
| 599 void NetworkLibraryImplBase::ConnectToCellularNetwork( | |
| 600 CellularNetwork* cellular) { | |
| 601 NetworkConnectStart(cellular, PROFILE_NONE); | |
| 602 } | |
| 603 | |
| 604 // 1. Connect to an existing virtual network. | |
| 605 void NetworkLibraryImplBase::ConnectToVirtualNetwork(VirtualNetwork* vpn) { | |
| 606 NetworkConnectStartVPN(vpn); | |
| 607 } | |
| 608 | |
| 609 // 2. Start the connection. | |
| 610 void NetworkLibraryImplBase::NetworkConnectStartWifi( | |
| 611 WifiNetwork* wifi, NetworkProfileType profile_type) { | |
| 612 DCHECK(!wifi->connection_started()); | |
| 613 // This will happen if a network resets, gets out of range or is forgotten. | |
| 614 if (wifi->user_passphrase_ != wifi->passphrase_ || | |
| 615 wifi->passphrase_required()) | |
| 616 wifi->SetPassphrase(wifi->user_passphrase_); | |
| 617 // For enterprise 802.1X networks, always provide TPM PIN when available. | |
| 618 // shill uses the PIN if it needs to access certificates in the TPM and | |
| 619 // ignores it otherwise. | |
| 620 if (wifi->encryption() == SECURITY_8021X) { | |
| 621 // If the TPM initialization has not completed, GetTpmPin() will return | |
| 622 // an empty value, in which case we do not want to clear the PIN since | |
| 623 // that will cause shill to flag the network as unconfigured. | |
| 624 // TODO(stevenjb): We may want to delay attempting to connect, or fail | |
| 625 // immediately, rather than let the network layer attempt a connection. | |
| 626 std::string tpm_pin = GetTpmPin(); | |
| 627 if (!tpm_pin.empty()) | |
| 628 wifi->SetCertificatePin(tpm_pin); | |
| 629 } | |
| 630 NetworkConnectStart(wifi, profile_type); | |
| 631 } | |
| 632 | |
| 633 void NetworkLibraryImplBase::NetworkConnectStartVPN(VirtualNetwork* vpn) { | |
| 634 // shill needs the TPM PIN for some VPN networks to access client | |
| 635 // certificates, and ignores the PIN if it doesn't need them. Only set this | |
| 636 // if the TPM is ready (see comment in NetworkConnectStartWifi). | |
| 637 std::string tpm_pin = GetTpmPin(); | |
| 638 if (!tpm_pin.empty()) { | |
| 639 std::string tpm_slot = GetTpmSlot(); | |
| 640 vpn->SetCertificateSlotAndPin(tpm_slot, tpm_pin); | |
| 641 } | |
| 642 NetworkConnectStart(vpn, PROFILE_NONE); | |
| 643 } | |
| 644 | |
| 645 void NetworkLibraryImplBase::NetworkConnectStart( | |
| 646 Network* network, NetworkProfileType profile_type) { | |
| 647 DCHECK(network); | |
| 648 DCHECK(!network->connection_started()); | |
| 649 // In order to be certain to trigger any notifications, set the connecting | |
| 650 // state locally and notify observers. Otherwise there might be a state | |
| 651 // change without a forced notify. | |
| 652 network->set_connecting(); | |
| 653 // Distinguish between user-initiated connection attempts | |
| 654 // and auto-connect. | |
| 655 network->set_user_connect_state(USER_CONNECT_STARTED); | |
| 656 NotifyNetworkManagerChanged(true); // Forced update. | |
| 657 VLOG(1) << "Requesting connect to network: " << network->name() | |
| 658 << " profile type: " << profile_type; | |
| 659 // Specify the correct profile for wifi networks (if specified or unset). | |
| 660 if ((network->type() == TYPE_WIFI || network->type() == TYPE_WIMAX) && | |
| 661 (profile_type != PROFILE_NONE || | |
| 662 network->profile_type() == PROFILE_NONE)) { | |
| 663 if (network->RequiresUserProfile()) | |
| 664 profile_type = PROFILE_USER; // Networks with certs can not be shared. | |
| 665 else if (profile_type == PROFILE_NONE) | |
| 666 profile_type = PROFILE_SHARED; // Other networks are shared by default. | |
| 667 std::string profile_path = GetProfilePath(profile_type); | |
| 668 if (!profile_path.empty()) { | |
| 669 if (profile_path != network->profile_path()) | |
| 670 SetProfileType(network, profile_type); | |
| 671 } else if (profile_type == PROFILE_USER) { | |
| 672 // The user profile was specified but is not available (i.e. pre-login). | |
| 673 // Add this network to the list of networks to move to the user profile | |
| 674 // when it becomes available. | |
| 675 VLOG(1) << "Queuing: " << network->name() << " to user_networks list."; | |
| 676 user_networks_.push_back(network->service_path()); | |
| 677 } | |
| 678 } | |
| 679 CallConnectToNetwork(network); | |
| 680 } | |
| 681 | |
| 682 // 3. Start the connection attempt for Network. | |
| 683 // Must Call NetworkConnectCompleted when the connection attempt completes. | |
| 684 // virtual void CallConnectToNetwork(Network* network) = 0; | |
| 685 | |
| 686 // 4. Complete the connection. | |
| 687 void NetworkLibraryImplBase::NetworkConnectCompleted( | |
| 688 Network* network, NetworkConnectStatus status) { | |
| 689 DCHECK(network); | |
| 690 if (status != CONNECT_SUCCESS) { | |
| 691 // This will trigger the connection failed notification. | |
| 692 // TODO(stevenjb): Remove if chromium-os:13203 gets fixed. | |
| 693 network->SetState(STATE_FAILURE); | |
| 694 if (status == CONNECT_BAD_PASSPHRASE) { | |
| 695 network->SetError(ERROR_BAD_PASSPHRASE); | |
| 696 } else { | |
| 697 network->SetError(ERROR_CONNECT_FAILED); | |
| 698 } | |
| 699 NotifyNetworkManagerChanged(true); // Forced update. | |
| 700 NotifyNetworkChanged(network); | |
| 701 VLOG(1) << "Error connecting to network: " << network->name() | |
| 702 << " Status: " << status; | |
| 703 return; | |
| 704 } | |
| 705 | |
| 706 VLOG(1) << "Connected to network: " << network->name() | |
| 707 << " State: " << network->state() | |
| 708 << " Status: " << status; | |
| 709 | |
| 710 // If the user asked not to save credentials, shill will have | |
| 711 // forgotten them. Wipe our cache as well. | |
| 712 if (!network->save_credentials()) | |
| 713 network->EraseCredentials(); | |
| 714 | |
| 715 ClearActiveNetwork(network->type()); | |
| 716 UpdateActiveNetwork(network); | |
| 717 | |
| 718 // Notify observers. | |
| 719 NotifyNetworkManagerChanged(true); // Forced update. | |
| 720 NotifyNetworkChanged(network); | |
| 721 } | |
| 722 | |
| 723 ///////////////////////////////////////////////////////////////////////////// | |
| 724 // Request a network and connect to it. | |
| 725 | |
| 726 // 1. Connect to an unconfigured or unlisted wifi network. | |
| 727 // This needs to request information about the named service. | |
| 728 // The connection attempt will occur in the callback. | |
| 729 void NetworkLibraryImplBase::ConnectToUnconfiguredWifiNetwork( | |
| 730 const std::string& ssid, | |
| 731 ConnectionSecurity security, | |
| 732 const std::string& passphrase, | |
| 733 const EAPConfigData* eap_config, | |
| 734 bool save_credentials, | |
| 735 bool shared) { | |
| 736 // Store the connection data to be used by the callback. | |
| 737 connect_data_.security = security; | |
| 738 connect_data_.service_name = ssid; | |
| 739 connect_data_.passphrase = passphrase; | |
| 740 connect_data_.save_credentials = save_credentials; | |
| 741 connect_data_.profile_type = shared ? PROFILE_SHARED : PROFILE_USER; | |
| 742 if (security == SECURITY_8021X) { | |
| 743 DCHECK(eap_config); | |
| 744 connect_data_.service_name = ssid; | |
| 745 connect_data_.eap_method = eap_config->method; | |
| 746 connect_data_.eap_auth = eap_config->auth; | |
| 747 connect_data_.server_ca_cert_pem = eap_config->server_ca_cert_pem; | |
| 748 connect_data_.eap_use_system_cas = eap_config->use_system_cas; | |
| 749 connect_data_.client_cert_pkcs11_id = | |
| 750 eap_config->client_cert_pkcs11_id; | |
| 751 connect_data_.eap_identity = eap_config->identity; | |
| 752 connect_data_.eap_anonymous_identity = eap_config->anonymous_identity; | |
| 753 } | |
| 754 | |
| 755 CallRequestWifiNetworkAndConnect(ssid, security); | |
| 756 } | |
| 757 | |
| 758 // 1. Connect to a virtual network with a PSK. | |
| 759 void NetworkLibraryImplBase::ConnectToUnconfiguredVirtualNetwork( | |
| 760 const std::string& service_name, | |
| 761 const std::string& server_hostname, | |
| 762 ProviderType provider_type, | |
| 763 const VPNConfigData& config) { | |
| 764 // Store the connection data to be used by the callback. | |
| 765 connect_data_.service_name = service_name; | |
| 766 connect_data_.server_hostname = server_hostname; | |
| 767 connect_data_.psk_key = config.psk; | |
| 768 connect_data_.server_ca_cert_pem = config.server_ca_cert_pem; | |
| 769 connect_data_.client_cert_pkcs11_id = config.client_cert_pkcs11_id; | |
| 770 connect_data_.username = config.username; | |
| 771 connect_data_.passphrase = config.user_passphrase; | |
| 772 connect_data_.otp = config.otp; | |
| 773 connect_data_.group_name = config.group_name; | |
| 774 connect_data_.save_credentials = config.save_credentials; | |
| 775 CallRequestVirtualNetworkAndConnect( | |
| 776 service_name, server_hostname, provider_type); | |
| 777 } | |
| 778 | |
| 779 // 2. Requests a WiFi Network by SSID and security. | |
| 780 // Calls ConnectToWifiNetworkUsingConnectData if network request succeeds. | |
| 781 // virtual void CallRequestWifiNetworkAndConnect( | |
| 782 // const std::string& ssid, ConnectionSecurity security) = 0; | |
| 783 | |
| 784 // 2. Requests a Virtual Network by service name, etc. | |
| 785 // Calls ConnectToVirtualNetworkUsingConnectData if network request succeeds. | |
| 786 // virtual void CallRequestVirtualNetworkAndConnect( | |
| 787 // const std::string& service_name, | |
| 788 // const std::string& server_hostname, | |
| 789 // ProviderType provider_type) = 0; | |
| 790 | |
| 791 // 3. Sets network properties stored in ConnectData and calls | |
| 792 // NetworkConnectStart. | |
| 793 void NetworkLibraryImplBase::ConnectToWifiNetworkUsingConnectData( | |
| 794 WifiNetwork* wifi) { | |
| 795 ConnectData& data = connect_data_; | |
| 796 if (wifi->name() != data.service_name) { | |
| 797 LOG(WARNING) << "WiFi network name does not match ConnectData: " | |
| 798 << wifi->name() << " != " << data.service_name; | |
| 799 return; | |
| 800 } | |
| 801 wifi->set_added(true); | |
| 802 if (data.security == SECURITY_8021X) { | |
| 803 // Enterprise 802.1X EAP network. | |
| 804 wifi->SetEAPMethod(data.eap_method); | |
| 805 wifi->SetEAPPhase2Auth(data.eap_auth); | |
| 806 wifi->SetEAPServerCaCertPEM(data.server_ca_cert_pem); | |
| 807 wifi->SetEAPUseSystemCAs(data.eap_use_system_cas); | |
| 808 wifi->SetEAPClientCertPkcs11Id(data.client_cert_pkcs11_id); | |
| 809 wifi->SetEAPIdentity(data.eap_identity); | |
| 810 wifi->SetEAPAnonymousIdentity(data.eap_anonymous_identity); | |
| 811 wifi->SetEAPPassphrase(data.passphrase); | |
| 812 wifi->SetSaveCredentials(data.save_credentials); | |
| 813 } else { | |
| 814 // Ordinary, non-802.1X network. | |
| 815 wifi->SetPassphrase(data.passphrase); | |
| 816 } | |
| 817 | |
| 818 NetworkConnectStartWifi(wifi, data.profile_type); | |
| 819 } | |
| 820 | |
| 821 // 3. Sets network properties stored in ConnectData and calls | |
| 822 // ConnectToVirtualNetwork. | |
| 823 void NetworkLibraryImplBase::ConnectToVirtualNetworkUsingConnectData( | |
| 824 VirtualNetwork* vpn) { | |
| 825 ConnectData& data = connect_data_; | |
| 826 if (vpn->name() != data.service_name) { | |
| 827 LOG(WARNING) << "Virtual network name does not match ConnectData: " | |
| 828 << vpn->name() << " != " << data.service_name; | |
| 829 return; | |
| 830 } | |
| 831 | |
| 832 // When a L2TP/IPsec certificate-based VPN is created, the VirtualNetwork | |
| 833 // instance is created by NativeNetworkParser::CreateNetworkFromInfo(). | |
| 834 // At that point, the provider type is deduced based on the value of | |
| 835 // client_cert_id_ of the VirtualNetwork instance, which hasn't been | |
| 836 // updated to the value of connect_data_.client_cert_pkcs11_id. Thus, | |
| 837 // the provider type is always incorrectly set to L2TP_IPSEC_PSK when | |
| 838 // L2TP_IPSEC_USER_CERT is expected. Here we fix the provider type based | |
| 839 // on connect_data_.client_cert_pkcs11_id. | |
| 840 // | |
| 841 // TODO(benchan): This is a quick and dirty workaround, we should refactor | |
| 842 // the code to make the flow more straightforward. See crosbug.com/24636 | |
| 843 if (vpn->provider_type() == PROVIDER_TYPE_L2TP_IPSEC_PSK && | |
| 844 !connect_data_.client_cert_pkcs11_id.empty()) { | |
| 845 vpn->set_provider_type(PROVIDER_TYPE_L2TP_IPSEC_USER_CERT); | |
| 846 } | |
| 847 | |
| 848 vpn->set_added(true); | |
| 849 if (!data.server_hostname.empty()) | |
| 850 vpn->set_server_hostname(data.server_hostname); | |
| 851 | |
| 852 vpn->SetCACertPEM(data.server_ca_cert_pem); | |
| 853 switch (vpn->provider_type()) { | |
| 854 case PROVIDER_TYPE_L2TP_IPSEC_PSK: | |
| 855 vpn->SetL2TPIPsecPSKCredentials( | |
| 856 data.psk_key, data.username, data.passphrase, data.group_name); | |
| 857 break; | |
| 858 case PROVIDER_TYPE_L2TP_IPSEC_USER_CERT: { | |
| 859 vpn->SetL2TPIPsecCertCredentials( | |
| 860 data.client_cert_pkcs11_id, | |
| 861 data.username, data.passphrase, data.group_name); | |
| 862 break; | |
| 863 } | |
| 864 case PROVIDER_TYPE_OPEN_VPN: { | |
| 865 vpn->SetOpenVPNCredentials( | |
| 866 data.client_cert_pkcs11_id, | |
| 867 data.username, data.passphrase, data.otp); | |
| 868 break; | |
| 869 } | |
| 870 case PROVIDER_TYPE_MAX: | |
| 871 NOTREACHED(); | |
| 872 break; | |
| 873 } | |
| 874 vpn->SetSaveCredentials(data.save_credentials); | |
| 875 | |
| 876 NetworkConnectStartVPN(vpn); | |
| 877 } | |
| 878 | |
| 879 ///////////////////////////////////////////////////////////////////////////// | |
| 880 | |
| 881 void NetworkLibraryImplBase::ForgetNetwork(const std::string& service_path) { | |
| 882 // Remove network from remembered list and notify observers. | |
| 883 DeleteRememberedNetwork(service_path); | |
| 884 NotifyNetworkManagerChanged(true); // Forced update. | |
| 885 } | |
| 886 | |
| 887 ///////////////////////////////////////////////////////////////////////////// | |
| 888 | |
| 889 void NetworkLibraryImplBase::EnableEthernetNetworkDevice(bool enable) { | |
| 890 if (is_locked_) | |
| 891 return; | |
| 892 CallEnableNetworkDeviceType(TYPE_ETHERNET, enable); | |
| 893 } | |
| 894 | |
| 895 void NetworkLibraryImplBase::EnableWifiNetworkDevice(bool enable) { | |
| 896 if (is_locked_) | |
| 897 return; | |
| 898 CallEnableNetworkDeviceType(TYPE_WIFI, enable); | |
| 899 } | |
| 900 | |
| 901 void NetworkLibraryImplBase::EnableWimaxNetworkDevice(bool enable) { | |
| 902 if (is_locked_) | |
| 903 return; | |
| 904 CallEnableNetworkDeviceType(TYPE_WIMAX, enable); | |
| 905 } | |
| 906 | |
| 907 void NetworkLibraryImplBase::EnableCellularNetworkDevice(bool enable) { | |
| 908 if (is_locked_) | |
| 909 return; | |
| 910 CallEnableNetworkDeviceType(TYPE_CELLULAR, enable); | |
| 911 } | |
| 912 | |
| 913 void NetworkLibraryImplBase::SwitchToPreferredNetwork() { | |
| 914 // If current network (if any) is not preferred, check network service list to | |
| 915 // see if the first not connected network is preferred and set to autoconnect. | |
| 916 // If so, connect to it. | |
| 917 if (!wifi_enabled() || (active_wifi_ && active_wifi_->preferred())) | |
| 918 return; | |
| 919 for (WifiNetworkVector::const_iterator it = wifi_networks_.begin(); | |
| 920 it != wifi_networks_.end(); ++it) { | |
| 921 WifiNetwork* wifi = *it; | |
| 922 if (wifi->connected() || wifi->connecting()) // Skip connected/connecting. | |
| 923 continue; | |
| 924 if (!wifi->preferred()) // All preferred networks are sorted in front. | |
| 925 break; | |
| 926 if (wifi->auto_connect()) { | |
| 927 ConnectToWifiNetwork(wifi); | |
| 928 break; | |
| 929 } | |
| 930 } | |
| 931 } | |
| 932 | |
| 933 namespace { | |
| 934 | |
| 935 class UserStringSubstitution : public onc::StringSubstitution { | |
| 936 public: | |
| 937 UserStringSubstitution() {} | |
| 938 virtual bool GetSubstitute(const std::string& placeholder, | |
| 939 std::string* substitute) const OVERRIDE { | |
| 940 if (!UserManager::Get()->IsUserLoggedIn()) | |
| 941 return false; | |
| 942 const User* logged_in_user = UserManager::Get()->GetLoggedInUser(); | |
| 943 if (placeholder == onc::substitutes::kLoginIDField) | |
| 944 *substitute = logged_in_user->GetAccountName(false); | |
| 945 else if (placeholder == onc::substitutes::kEmailField) | |
| 946 *substitute = logged_in_user->email(); | |
| 947 else | |
| 948 return false; | |
| 949 return true; | |
| 950 } | |
| 951 }; | |
| 952 | |
| 953 } // namespace | |
| 954 | |
| 955 void NetworkLibraryImplBase::LoadOncNetworks( | |
| 956 const base::ListValue& network_configs, | |
| 957 onc::ONCSource source) { | |
| 958 VLOG(2) << __func__ << ": called on " << network_configs; | |
| 959 NetworkProfile* profile = NULL; | |
| 960 bool from_policy = (source == onc::ONC_SOURCE_USER_POLICY || | |
| 961 source == onc::ONC_SOURCE_DEVICE_POLICY); | |
| 962 | |
| 963 // Policies are applied to a specific Shill profile. User ONC import however | |
| 964 // is applied to whatever profile Shill chooses. This should be the profile | |
| 965 // that is already associated with a network and if no profile is associated | |
| 966 // yet, it should be the user profile. | |
| 967 if (from_policy) { | |
| 968 profile = GetProfileForType(GetProfileTypeForSource(source)); | |
| 969 if (profile == NULL) { | |
| 970 VLOG(2) << "Profile for ONC source " << onc::GetSourceAsString(source) | |
| 971 << " doesn't exist."; | |
| 972 return; | |
| 973 } | |
| 974 } | |
| 975 | |
| 976 std::set<std::string> removal_ids; | |
| 977 std::set<std::string>& network_ids(network_source_map_[source]); | |
| 978 network_ids.clear(); | |
| 979 VLOG(2) << "ONC file has " << network_configs.GetSize() << " networks"; | |
| 980 for (base::ListValue::const_iterator it(network_configs.begin()); | |
| 981 it != network_configs.end(); ++it) { | |
| 982 const base::DictionaryValue* network; | |
| 983 (*it)->GetAsDictionary(&network); | |
| 984 | |
| 985 bool marked_for_removal = false; | |
| 986 network->GetBooleanWithoutPathExpansion(onc::kRemove, | |
| 987 &marked_for_removal); | |
| 988 | |
| 989 std::string type; | |
| 990 network->GetStringWithoutPathExpansion(onc::network_config::kType, &type); | |
| 991 | |
| 992 std::string guid; | |
| 993 network->GetStringWithoutPathExpansion(onc::network_config::kGUID, &guid); | |
| 994 | |
| 995 if (source == onc::ONC_SOURCE_USER_IMPORT && marked_for_removal) { | |
| 996 // User import supports the removal of networks by ID. | |
| 997 removal_ids.insert(guid); | |
| 998 continue; | |
| 999 } | |
| 1000 | |
| 1001 // Don't configure a network that is supposed to be removed. For | |
| 1002 // policy-managed networks, the "remove" functionality of ONC is | |
| 1003 // irrelevant. Instead, in general, all previously configured networks | |
| 1004 // that are no longer configured are removed. | |
| 1005 if (marked_for_removal) | |
| 1006 continue; | |
| 1007 | |
| 1008 // Store the network's identifier. The identifiers are later used to clean | |
| 1009 // out any previously-existing networks that had been configured through | |
| 1010 // policy but are no longer specified in the updated ONC blob. | |
| 1011 network_ids.insert(guid); | |
| 1012 | |
| 1013 // Expand strings like LoginID | |
| 1014 base::DictionaryValue* expanded_network = network->DeepCopy(); | |
| 1015 UserStringSubstitution substitution; | |
| 1016 onc::ExpandStringsInOncObject(onc::kNetworkConfigurationSignature, | |
| 1017 substitution, | |
| 1018 expanded_network); | |
| 1019 | |
| 1020 // Update the ONC map. | |
| 1021 const base::DictionaryValue*& entry = network_onc_map_[guid]; | |
| 1022 if (entry && entry->Equals(expanded_network)) | |
| 1023 continue; | |
| 1024 | |
| 1025 delete entry; | |
| 1026 entry = expanded_network; | |
| 1027 | |
| 1028 // Normalize the ONC: Remove irrelevant fields. | |
| 1029 onc::Normalizer normalizer(true /* remove recommended fields */); | |
| 1030 scoped_ptr<base::DictionaryValue> normalized_network = | |
| 1031 normalizer.NormalizeObject(&onc::kNetworkConfigurationSignature, | |
| 1032 *expanded_network); | |
| 1033 | |
| 1034 // Configure the network. | |
| 1035 scoped_ptr<base::DictionaryValue> shill_dict = | |
| 1036 onc::TranslateONCObjectToShill(&onc::kNetworkConfigurationSignature, | |
| 1037 *normalized_network); | |
| 1038 | |
| 1039 // Set the UIData. | |
| 1040 scoped_ptr<NetworkUIData> ui_data = | |
| 1041 NetworkUIData::CreateFromONC(source, *normalized_network); | |
| 1042 base::DictionaryValue ui_data_dict; | |
| 1043 ui_data->FillDictionary(&ui_data_dict); | |
| 1044 std::string ui_data_json; | |
| 1045 base::JSONWriter::Write(&ui_data_dict, &ui_data_json); | |
| 1046 shill_dict->SetStringWithoutPathExpansion(flimflam::kUIDataProperty, | |
| 1047 ui_data_json); | |
| 1048 | |
| 1049 // Set the appropriate profile for |source|. | |
| 1050 if (profile != NULL) { | |
| 1051 shill_dict->SetStringWithoutPathExpansion(flimflam::kProfileProperty, | |
| 1052 profile->path); | |
| 1053 } | |
| 1054 | |
| 1055 // For Ethernet networks, apply them to the current Ethernet service. | |
| 1056 if (type == onc::network_type::kEthernet) { | |
| 1057 const EthernetNetwork* ethernet = ethernet_network(); | |
| 1058 if (ethernet) { | |
| 1059 CallConfigureService(ethernet->unique_id(), shill_dict.get()); | |
| 1060 } else { | |
| 1061 LOG(WARNING) << "Tried to import ONC with an Ethernet network when " | |
| 1062 << "there is no active Ethernet connection."; | |
| 1063 } | |
| 1064 } else { | |
| 1065 CallConfigureService(guid, shill_dict.get()); | |
| 1066 } | |
| 1067 } | |
| 1068 | |
| 1069 if (from_policy) { | |
| 1070 // For policy-managed networks, go through the list of existing remembered | |
| 1071 // networks and clean out the ones that no longer have a definition in the | |
| 1072 // ONC blob. We first collect the networks and do the actual deletion later | |
| 1073 // because ForgetNetwork() changes the remembered network vectors. | |
| 1074 ForgetNetworksById(source, network_ids, false); | |
| 1075 } else if (source == onc::ONC_SOURCE_USER_IMPORT && !removal_ids.empty()) { | |
| 1076 ForgetNetworksById(source, removal_ids, true); | |
| 1077 } | |
| 1078 // Ensure NetworkStateHandler properties are up-to-date. | |
| 1079 if (NetworkHandler::IsInitialized()) { | |
| 1080 NetworkHandler::Get()->network_state_handler()-> | |
| 1081 RequestUpdateForAllNetworks(); | |
| 1082 } | |
| 1083 } | |
| 1084 | |
| 1085 //////////////////////////////////////////////////////////////////////////// | |
| 1086 // Testing functions. | |
| 1087 | |
| 1088 bool NetworkLibraryImplBase::SetActiveNetwork( | |
| 1089 ConnectionType type, const std::string& service_path) { | |
| 1090 Network* network = NULL; | |
| 1091 if (!service_path.empty()) | |
| 1092 network = FindNetworkByPath(service_path); | |
| 1093 if (network && network->type() != type) { | |
| 1094 LOG(WARNING) << "SetActiveNetwork type mismatch for: " << network->name(); | |
| 1095 return false; | |
| 1096 } | |
| 1097 | |
| 1098 ClearActiveNetwork(type); | |
| 1099 | |
| 1100 if (!network) | |
| 1101 return true; | |
| 1102 | |
| 1103 // Set |network| to active. | |
| 1104 UpdateActiveNetwork(network); | |
| 1105 return true; | |
| 1106 } | |
| 1107 | |
| 1108 //////////////////////////////////////////////////////////////////////////// | |
| 1109 // Network list management functions. | |
| 1110 | |
| 1111 // Note: sometimes shill still returns networks when the device type is | |
| 1112 // disabled. Always check the appropriate enabled() state before adding | |
| 1113 // networks to a list or setting an active network so that we do not show them | |
| 1114 // in the UI. | |
| 1115 | |
| 1116 // This relies on services being requested from shill in priority order, | |
| 1117 // and the updates getting processed and received in order. | |
| 1118 void NetworkLibraryImplBase::UpdateActiveNetwork(Network* network) { | |
| 1119 network->set_is_active(true); | |
| 1120 ConnectionType type(network->type()); | |
| 1121 if (type == TYPE_ETHERNET) { | |
| 1122 if (ethernet_enabled()) { | |
| 1123 // Set ethernet_ to the first connected ethernet service, or the first | |
| 1124 // disconnected ethernet service if none are connected. | |
| 1125 if (ethernet_ == NULL || !ethernet_->connected()) { | |
| 1126 ethernet_ = static_cast<EthernetNetwork*>(network); | |
| 1127 VLOG(2) << "Active ethernet -> " << ethernet_->name(); | |
| 1128 } | |
| 1129 } | |
| 1130 } else if (type == TYPE_WIFI) { | |
| 1131 if (wifi_enabled()) { | |
| 1132 // Set active_wifi_ to the first connected or connecting wifi service. | |
| 1133 if (active_wifi_ == NULL && network->connecting_or_connected()) { | |
| 1134 active_wifi_ = static_cast<WifiNetwork*>(network); | |
| 1135 VLOG(2) << "Active wifi -> " << active_wifi_->name(); | |
| 1136 } | |
| 1137 } | |
| 1138 } else if (type == TYPE_CELLULAR) { | |
| 1139 if (cellular_enabled()) { | |
| 1140 // Set active_cellular_ to first connected/connecting celluar service. | |
| 1141 if (active_cellular_ == NULL && network->connecting_or_connected()) { | |
| 1142 active_cellular_ = static_cast<CellularNetwork*>(network); | |
| 1143 VLOG(2) << "Active cellular -> " << active_cellular_->name(); | |
| 1144 } | |
| 1145 } | |
| 1146 } else if (type == TYPE_WIMAX) { | |
| 1147 if (wimax_enabled()) { | |
| 1148 // Set active_wimax_ to first connected/connecting wimax service. | |
| 1149 if (active_wimax_ == NULL && network->connecting_or_connected()) { | |
| 1150 active_wimax_ = static_cast<WimaxNetwork*>(network); | |
| 1151 VLOG(2) << "Active wimax -> " << active_wimax_->name(); | |
| 1152 } | |
| 1153 } | |
| 1154 } else if (type == TYPE_VPN) { | |
| 1155 // Set active_virtual_ to the first connected or connecting vpn service. { | |
| 1156 if (active_virtual_ == NULL && network->connecting_or_connected()) { | |
| 1157 active_virtual_ = static_cast<VirtualNetwork*>(network); | |
| 1158 VLOG(2) << "Active virtual -> " << active_virtual_->name(); | |
| 1159 } | |
| 1160 } | |
| 1161 } | |
| 1162 | |
| 1163 void NetworkLibraryImplBase::ClearActiveNetwork(ConnectionType type) { | |
| 1164 // Clear any existing active network matching |type|. | |
| 1165 for (NetworkMap::iterator iter = network_map_.begin(); | |
| 1166 iter != network_map_.end(); ++iter) { | |
| 1167 Network* other = iter->second; | |
| 1168 if (other->type() == type) | |
| 1169 other->set_is_active(false); | |
| 1170 } | |
| 1171 switch (type) { | |
| 1172 case TYPE_ETHERNET: | |
| 1173 ethernet_ = NULL; | |
| 1174 break; | |
| 1175 case TYPE_WIFI: | |
| 1176 active_wifi_ = NULL; | |
| 1177 break; | |
| 1178 case TYPE_CELLULAR: | |
| 1179 active_cellular_ = NULL; | |
| 1180 break; | |
| 1181 case TYPE_WIMAX: | |
| 1182 active_wimax_ = NULL; | |
| 1183 break; | |
| 1184 case TYPE_VPN: | |
| 1185 active_virtual_ = NULL; | |
| 1186 break; | |
| 1187 default: | |
| 1188 break; | |
| 1189 } | |
| 1190 } | |
| 1191 | |
| 1192 void NetworkLibraryImplBase::AddNetwork(Network* network) { | |
| 1193 std::pair<NetworkMap::iterator, bool> result = | |
| 1194 network_map_.insert(std::make_pair(network->service_path(), network)); | |
| 1195 DCHECK(result.second); // Should only get called with new network. | |
| 1196 VLOG(2) << "Adding Network: " << network->service_path() | |
| 1197 << " (" << network->name() << ")"; | |
| 1198 ConnectionType type(network->type()); | |
| 1199 if (type == TYPE_WIFI) { | |
| 1200 if (wifi_enabled()) | |
| 1201 wifi_networks_.push_back(static_cast<WifiNetwork*>(network)); | |
| 1202 } else if (type == TYPE_CELLULAR) { | |
| 1203 if (cellular_enabled()) | |
| 1204 cellular_networks_.push_back(static_cast<CellularNetwork*>(network)); | |
| 1205 } else if (type == TYPE_WIMAX) { | |
| 1206 if (wimax_enabled()) | |
| 1207 wimax_networks_.push_back(static_cast<WimaxNetwork*>(network)); | |
| 1208 } else if (type == TYPE_VPN) { | |
| 1209 virtual_networks_.push_back(static_cast<VirtualNetwork*>(network)); | |
| 1210 } | |
| 1211 // Do not set the active network here. Wait until we parse the network. | |
| 1212 } | |
| 1213 | |
| 1214 // Deletes a network. It must already be removed from any lists. | |
| 1215 void NetworkLibraryImplBase::DeleteNetwork(Network* network) { | |
| 1216 CHECK(network_map_.find(network->service_path()) == network_map_.end()); | |
| 1217 delete network; | |
| 1218 } | |
| 1219 | |
| 1220 void NetworkLibraryImplBase::ForgetNetworksById( | |
| 1221 onc::ONCSource source, | |
| 1222 std::set<std::string> ids, | |
| 1223 bool if_found) { | |
| 1224 std::vector<std::string> to_be_forgotten; | |
| 1225 for (WifiNetworkVector::iterator i = remembered_wifi_networks_.begin(); | |
| 1226 i != remembered_wifi_networks_.end(); ++i) { | |
| 1227 WifiNetwork* wifi_network = *i; | |
| 1228 if (wifi_network->ui_data().onc_source() == source && | |
| 1229 if_found == (ids.find(wifi_network->unique_id()) != ids.end())) | |
| 1230 to_be_forgotten.push_back(wifi_network->service_path()); | |
| 1231 } | |
| 1232 | |
| 1233 for (VirtualNetworkVector::iterator i = remembered_virtual_networks_.begin(); | |
| 1234 i != remembered_virtual_networks_.end(); ++i) { | |
| 1235 VirtualNetwork* virtual_network = *i; | |
| 1236 if (virtual_network->ui_data().onc_source() == source && | |
| 1237 if_found == (ids.find(virtual_network->unique_id()) != ids.end())) | |
| 1238 to_be_forgotten.push_back(virtual_network->service_path()); | |
| 1239 } | |
| 1240 | |
| 1241 for (std::vector<std::string>::const_iterator i = to_be_forgotten.begin(); | |
| 1242 i != to_be_forgotten.end(); ++i) { | |
| 1243 ForgetNetwork(*i); | |
| 1244 } | |
| 1245 } | |
| 1246 | |
| 1247 bool NetworkLibraryImplBase::ValidateRememberedNetwork(Network* network) { | |
| 1248 std::pair<NetworkMap::iterator, bool> result = | |
| 1249 remembered_network_map_.insert( | |
| 1250 std::make_pair(network->service_path(), network)); | |
| 1251 DCHECK(result.second); // Should only get called with new network. | |
| 1252 | |
| 1253 // See if this is a policy-configured network that has meanwhile been removed. | |
| 1254 // This situation may arise when the full list of remembered networks is not | |
| 1255 // available to LoadOncNetworks(), which can happen due to the asynchronous | |
| 1256 // communication between shill and NetworkLibrary. Just tell shill to | |
| 1257 // delete the network now. | |
| 1258 const onc::ONCSource source = network->ui_data().onc_source(); | |
| 1259 if (source == onc::ONC_SOURCE_USER_POLICY || | |
| 1260 source == onc::ONC_SOURCE_DEVICE_POLICY) { | |
| 1261 NetworkSourceMap::const_iterator network_id_set( | |
| 1262 network_source_map_.find(source)); | |
| 1263 if (network_id_set != network_source_map_.end() && | |
| 1264 network_id_set->second.find(network->unique_id()) == | |
| 1265 network_id_set->second.end()) { | |
| 1266 DeleteRememberedNetwork(network->service_path()); | |
| 1267 return false; | |
| 1268 } | |
| 1269 } | |
| 1270 | |
| 1271 return true; | |
| 1272 } | |
| 1273 | |
| 1274 bool NetworkLibraryImplBase::ValidateAndAddRememberedNetwork(Network* network) { | |
| 1275 if (!ValidateRememberedNetwork(network)) | |
| 1276 return false; | |
| 1277 | |
| 1278 if (network->type() == TYPE_WIFI) { | |
| 1279 remembered_wifi_networks_.push_back( | |
| 1280 static_cast<WifiNetwork*>(network)); | |
| 1281 } else if (network->type() == TYPE_VPN) { | |
| 1282 remembered_virtual_networks_.push_back( | |
| 1283 static_cast<VirtualNetwork*>(network)); | |
| 1284 } else { | |
| 1285 NOTREACHED(); | |
| 1286 } | |
| 1287 | |
| 1288 VLOG(1) << "ValidateAndAddRememberedNetwork: " << network->service_path(); | |
| 1289 return true; | |
| 1290 } | |
| 1291 | |
| 1292 void NetworkLibraryImplBase::DeleteRememberedNetwork( | |
| 1293 const std::string& service_path) { | |
| 1294 NetworkMap::iterator found = remembered_network_map_.find(service_path); | |
| 1295 if (found == remembered_network_map_.end()) { | |
| 1296 LOG(WARNING) << "Attempt to delete non-existent remembered network: " | |
| 1297 << service_path; | |
| 1298 return; | |
| 1299 } | |
| 1300 Network* remembered_network = found->second; | |
| 1301 VLOG(1) << "Deleting remembered network: " | |
| 1302 << remembered_network->service_path(); | |
| 1303 | |
| 1304 // Update any associated network service before removing from profile | |
| 1305 // so that shill doesn't recreate the service (e.g. when we disconenct it). | |
| 1306 Network* network = FindNetworkByUniqueId(remembered_network->unique_id()); | |
| 1307 if (network) { | |
| 1308 // Clear the stored credentials for any forgotten networks. | |
| 1309 network->EraseCredentials(); | |
| 1310 network->ClearUIData(); | |
| 1311 SetProfileType(network, PROFILE_NONE); | |
| 1312 // Remove VPN from list of networks. | |
| 1313 if (network->type() == TYPE_VPN) | |
| 1314 CallRemoveNetwork(network); | |
| 1315 } else { | |
| 1316 // Network is not in service list. | |
| 1317 VLOG(2) << "Remembered Network not in service list: " | |
| 1318 << remembered_network->unique_id(); | |
| 1319 } | |
| 1320 | |
| 1321 // Delete remembered network from lists. | |
| 1322 remembered_network_map_.erase(found); | |
| 1323 | |
| 1324 if (remembered_network->type() == TYPE_WIFI) { | |
| 1325 WifiNetworkVector::iterator iter = std::find( | |
| 1326 remembered_wifi_networks_.begin(), | |
| 1327 remembered_wifi_networks_.end(), | |
| 1328 remembered_network); | |
| 1329 if (iter != remembered_wifi_networks_.end()) | |
| 1330 remembered_wifi_networks_.erase(iter); | |
| 1331 } else if (remembered_network->type() == TYPE_VPN) { | |
| 1332 VirtualNetworkVector::iterator iter = std::find( | |
| 1333 remembered_virtual_networks_.begin(), | |
| 1334 remembered_virtual_networks_.end(), | |
| 1335 remembered_network); | |
| 1336 if (iter != remembered_virtual_networks_.end()) | |
| 1337 remembered_virtual_networks_.erase(iter); | |
| 1338 } | |
| 1339 | |
| 1340 // Delete remembered network from all profiles it is in. | |
| 1341 for (NetworkProfileList::iterator iter = profile_list_.begin(); | |
| 1342 iter != profile_list_.end(); ++iter) { | |
| 1343 NetworkProfile& profile = *iter; | |
| 1344 NetworkProfile::ServiceList::iterator found = | |
| 1345 profile.services.find(remembered_network->service_path()); | |
| 1346 if (found != profile.services.end()) { | |
| 1347 VLOG(1) << "Deleting: " << remembered_network->service_path() | |
| 1348 << " From: " << profile.path; | |
| 1349 CallDeleteRememberedNetwork(profile.path, | |
| 1350 remembered_network->service_path()); | |
| 1351 profile.services.erase(found); | |
| 1352 } | |
| 1353 } | |
| 1354 | |
| 1355 // Remove the ONC blob for the network, if present. | |
| 1356 NetworkOncMap::iterator onc_map_entry = | |
| 1357 network_onc_map_.find(remembered_network->unique_id()); | |
| 1358 if (onc_map_entry != network_onc_map_.end()) { | |
| 1359 delete onc_map_entry->second; | |
| 1360 network_onc_map_.erase(onc_map_entry); | |
| 1361 } | |
| 1362 | |
| 1363 delete remembered_network; | |
| 1364 } | |
| 1365 | |
| 1366 //////////////////////////////////////////////////////////////////////////// | |
| 1367 | |
| 1368 void NetworkLibraryImplBase::ClearNetworks() { | |
| 1369 network_map_.clear(); | |
| 1370 network_unique_id_map_.clear(); | |
| 1371 ethernet_ = NULL; | |
| 1372 active_wifi_ = NULL; | |
| 1373 active_cellular_ = NULL; | |
| 1374 active_wimax_ = NULL; | |
| 1375 active_virtual_ = NULL; | |
| 1376 wifi_networks_.clear(); | |
| 1377 cellular_networks_.clear(); | |
| 1378 wimax_networks_.clear(); | |
| 1379 virtual_networks_.clear(); | |
| 1380 } | |
| 1381 | |
| 1382 void NetworkLibraryImplBase::DeleteRememberedNetworks() { | |
| 1383 STLDeleteValues(&remembered_network_map_); | |
| 1384 remembered_network_map_.clear(); | |
| 1385 remembered_wifi_networks_.clear(); | |
| 1386 remembered_virtual_networks_.clear(); | |
| 1387 } | |
| 1388 | |
| 1389 void NetworkLibraryImplBase::DeleteDevice(const std::string& device_path) { | |
| 1390 NetworkDeviceMap::iterator found = device_map_.find(device_path); | |
| 1391 if (found == device_map_.end()) { | |
| 1392 LOG(WARNING) << "Attempt to delete non-existent device: " | |
| 1393 << device_path; | |
| 1394 return; | |
| 1395 } | |
| 1396 VLOG(2) << " Deleting device: " << device_path; | |
| 1397 NetworkDevice* device = found->second; | |
| 1398 device_map_.erase(found); | |
| 1399 delete device; | |
| 1400 DeleteDeviceFromDeviceObserversMap(device_path); | |
| 1401 } | |
| 1402 | |
| 1403 //////////////////////////////////////////////////////////////////////////// | |
| 1404 | |
| 1405 void NetworkLibraryImplBase::AddProfile(const std::string& profile_path, | |
| 1406 NetworkProfileType profile_type) { | |
| 1407 VLOG(1) << "Adding profile " << profile_path; | |
| 1408 profile_list_.push_back(NetworkProfile(profile_path, profile_type)); | |
| 1409 // Check to see if we connected to any networks before a user profile was | |
| 1410 // available (i.e. before login), but unchecked the "Share" option (i.e. | |
| 1411 // the desired pofile is the user profile). Move these networks to the | |
| 1412 // user profile when it becomes available. | |
| 1413 if (profile_type == PROFILE_USER && !user_networks_.empty()) { | |
| 1414 for (std::list<std::string>::iterator iter2 = user_networks_.begin(); | |
| 1415 iter2 != user_networks_.end(); ++iter2) { | |
| 1416 Network* network = FindNetworkByPath(*iter2); | |
| 1417 if (network && network->profile_path() != profile_path) | |
| 1418 network->SetProfilePath(profile_path); | |
| 1419 } | |
| 1420 user_networks_.clear(); | |
| 1421 } | |
| 1422 } | |
| 1423 | |
| 1424 NetworkLibraryImplBase::NetworkProfile* | |
| 1425 NetworkLibraryImplBase::GetProfileForType(NetworkProfileType type) { | |
| 1426 for (NetworkProfileList::iterator iter = profile_list_.begin(); | |
| 1427 iter != profile_list_.end(); ++iter) { | |
| 1428 NetworkProfile& profile = *iter; | |
| 1429 if (profile.type == type) | |
| 1430 return &profile; | |
| 1431 } | |
| 1432 return NULL; | |
| 1433 } | |
| 1434 | |
| 1435 void NetworkLibraryImplBase::SetProfileType( | |
| 1436 Network* network, NetworkProfileType type) { | |
| 1437 if (type == PROFILE_NONE) { | |
| 1438 network->SetProfilePath(std::string()); | |
| 1439 network->set_profile_type(PROFILE_NONE); | |
| 1440 } else { | |
| 1441 std::string profile_path = GetProfilePath(type); | |
| 1442 if (!profile_path.empty()) { | |
| 1443 network->SetProfilePath(profile_path); | |
| 1444 network->set_profile_type(type); | |
| 1445 } else { | |
| 1446 LOG(WARNING) << "Profile type not found: " << type; | |
| 1447 network->set_profile_type(PROFILE_NONE); | |
| 1448 } | |
| 1449 } | |
| 1450 } | |
| 1451 | |
| 1452 void NetworkLibraryImplBase::SetProfileTypeFromPath(Network* network) { | |
| 1453 if (network->profile_path().empty()) { | |
| 1454 network->set_profile_type(PROFILE_NONE); | |
| 1455 return; | |
| 1456 } | |
| 1457 for (NetworkProfileList::iterator iter = profile_list_.begin(); | |
| 1458 iter != profile_list_.end(); ++iter) { | |
| 1459 NetworkProfile& profile = *iter; | |
| 1460 if (profile.path == network->profile_path()) { | |
| 1461 network->set_profile_type(profile.type); | |
| 1462 return; | |
| 1463 } | |
| 1464 } | |
| 1465 LOG(WARNING) << "Profile path not found: " << network->profile_path(); | |
| 1466 network->set_profile_type(PROFILE_NONE); | |
| 1467 } | |
| 1468 | |
| 1469 std::string NetworkLibraryImplBase::GetProfilePath(NetworkProfileType type) { | |
| 1470 std::string profile_path; | |
| 1471 NetworkProfile* profile = GetProfileForType(type); | |
| 1472 if (profile) | |
| 1473 profile_path = profile->path; | |
| 1474 return profile_path; | |
| 1475 } | |
| 1476 | |
| 1477 //////////////////////////////////////////////////////////////////////////// | |
| 1478 // Notifications. | |
| 1479 | |
| 1480 void NetworkLibraryImplBase::NotifyNetworkProfileObservers() { | |
| 1481 FOR_EACH_OBSERVER(NetworkProfileObserver, | |
| 1482 network_profile_observers_, | |
| 1483 OnProfileListChanged()); | |
| 1484 } | |
| 1485 | |
| 1486 // We call this any time something in NetworkLibrary changes. | |
| 1487 // TODO(stevenjb): We should consider breaking this into multiple | |
| 1488 // notifications, e.g. connection state, devices, services, etc. | |
| 1489 void NetworkLibraryImplBase::NotifyNetworkManagerChanged(bool force_update) { | |
| 1490 // Cancel any pending signals. | |
| 1491 notify_manager_weak_factory_.InvalidateWeakPtrs(); | |
| 1492 if (force_update) { | |
| 1493 // Signal observers now. | |
| 1494 SignalNetworkManagerObservers(); | |
| 1495 } else { | |
| 1496 // Schedule a delayed signal to limit the frequency of notifications. | |
| 1497 BrowserThread::PostDelayedTask( | |
| 1498 BrowserThread::UI, | |
| 1499 FROM_HERE, | |
| 1500 base::Bind(&NetworkLibraryImplBase::SignalNetworkManagerObservers, | |
| 1501 notify_manager_weak_factory_.GetWeakPtr()), | |
| 1502 base::TimeDelta::FromMilliseconds(kNetworkNotifyDelayMs)); | |
| 1503 } | |
| 1504 } | |
| 1505 | |
| 1506 void NetworkLibraryImplBase::SignalNetworkManagerObservers() { | |
| 1507 FOR_EACH_OBSERVER(NetworkManagerObserver, | |
| 1508 network_manager_observers_, | |
| 1509 OnNetworkManagerChanged(this)); | |
| 1510 // Clear notification flags. | |
| 1511 for (NetworkMap::iterator iter = network_map_.begin(); | |
| 1512 iter != network_map_.end(); ++iter) { | |
| 1513 iter->second->set_notify_failure(false); | |
| 1514 } | |
| 1515 } | |
| 1516 | |
| 1517 void NetworkLibraryImplBase::NotifyNetworkChanged(const Network* network) { | |
| 1518 DCHECK(network); | |
| 1519 VLOG(2) << "Network changed: " << network->name(); | |
| 1520 NetworkObserverMap::const_iterator iter = network_observers_.find( | |
| 1521 network->service_path()); | |
| 1522 if (iter != network_observers_.end()) { | |
| 1523 FOR_EACH_OBSERVER(NetworkObserver, | |
| 1524 *(iter->second), | |
| 1525 OnNetworkChanged(this, network)); | |
| 1526 } else if (IsCros()) { | |
| 1527 LOG(ERROR) << "Unexpected signal for unobserved network: " | |
| 1528 << network->name(); | |
| 1529 } | |
| 1530 } | |
| 1531 | |
| 1532 void NetworkLibraryImplBase::NotifyNetworkDeviceChanged( | |
| 1533 NetworkDevice* device, PropertyIndex index) { | |
| 1534 DCHECK(device); | |
| 1535 VLOG(2) << "Network device changed: " << device->name(); | |
| 1536 NetworkDeviceObserverMap::const_iterator iter = | |
| 1537 network_device_observers_.find(device->device_path()); | |
| 1538 if (iter != network_device_observers_.end()) { | |
| 1539 NetworkDeviceObserverList* device_observer_list = iter->second; | |
| 1540 if (index == PROPERTY_INDEX_FOUND_NETWORKS) { | |
| 1541 FOR_EACH_OBSERVER(NetworkDeviceObserver, | |
| 1542 *device_observer_list, | |
| 1543 OnNetworkDeviceFoundNetworks(this, device)); | |
| 1544 } else if (index == PROPERTY_INDEX_SIM_LOCK) { | |
| 1545 FOR_EACH_OBSERVER(NetworkDeviceObserver, | |
| 1546 *device_observer_list, | |
| 1547 OnNetworkDeviceSimLockChanged(this, device)); | |
| 1548 } | |
| 1549 } else { | |
| 1550 LOG(ERROR) << "Unexpected signal for unobserved device: " | |
| 1551 << device->name(); | |
| 1552 } | |
| 1553 } | |
| 1554 | |
| 1555 void NetworkLibraryImplBase::NotifyPinOperationCompleted( | |
| 1556 PinOperationError error) { | |
| 1557 FOR_EACH_OBSERVER(PinOperationObserver, | |
| 1558 pin_operation_observers_, | |
| 1559 OnPinOperationCompleted(this, error)); | |
| 1560 sim_operation_ = SIM_OPERATION_NONE; | |
| 1561 } | |
| 1562 | |
| 1563 ////////////////////////////////////////////////////////////////////////////// | |
| 1564 // Pin related functions. | |
| 1565 | |
| 1566 void NetworkLibraryImplBase::GetTpmInfo() { | |
| 1567 // Avoid making multiple synchronous D-Bus calls to cryptohome by caching | |
| 1568 // the TPM PIN, which does not change during a session. | |
| 1569 if (tpm_pin_.empty()) { | |
| 1570 if (crypto::IsTPMTokenReady()) { | |
| 1571 std::string tpm_label; | |
| 1572 crypto::GetTPMTokenInfo(&tpm_label, &tpm_pin_); | |
| 1573 // VLOG(1) << "TPM Label: " << tpm_label << ", PIN: " << tpm_pin_; | |
| 1574 // TODO(stevenjb): GetTPMTokenInfo returns a label, but the network | |
| 1575 // code expects a slot ID. See chromium-os:17998. | |
| 1576 // For now, use a hard coded, well known slot instead. | |
| 1577 const char kHardcodedTpmSlot[] = "0"; | |
| 1578 tpm_slot_ = kHardcodedTpmSlot; | |
| 1579 } else if (IsCros()) { | |
| 1580 LOG(WARNING) << "TPM token not ready"; | |
| 1581 } | |
| 1582 } | |
| 1583 } | |
| 1584 | |
| 1585 const std::string& NetworkLibraryImplBase::GetTpmSlot() { | |
| 1586 GetTpmInfo(); | |
| 1587 return tpm_slot_; | |
| 1588 } | |
| 1589 | |
| 1590 const std::string& NetworkLibraryImplBase::GetTpmPin() { | |
| 1591 GetTpmInfo(); | |
| 1592 return tpm_pin_; | |
| 1593 } | |
| 1594 | |
| 1595 } // namespace chromeos | |
| OLD | NEW |