network_library.cc revision 72a454cd3513ac24fbdd0e0cb9ad70b86a99b801
1 // Copyright (c) 2010 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.h" 6 7#include <algorithm> 8#include <map> 9 10#include "base/i18n/time_formatting.h" 11#include "base/stl_util-inl.h" 12#include "base/string_number_conversions.h" 13#include "base/string_util.h" 14#include "base/utf_string_conversions.h" 15#include "base/values.h" 16#include "chrome/browser/browser_thread.h" 17#include "chrome/browser/chromeos/network_login_observer.h" 18#include "chrome/browser/chromeos/cros/cros_library.h" 19#include "chrome/browser/chromeos/login/user_manager.h" 20#include "chrome/common/time_format.h" 21#include "grit/generated_resources.h" 22#include "ui/base/l10n/l10n_util.h" 23 24namespace { 25 26// FlimFlam may send multiple notifications for single network change. 27// We wait small amount of time before retrieving the status to 28// avoid send multiple sync request to flim flam. 29const int kNetworkUpdateDelayMs = 50; 30 31} // namespace 32 33namespace chromeos { 34 35namespace { 36// TODO(ers) These string constants and Parse functions are copied 37// straight out of libcros:chromeos_network.cc. Fix this by moving 38// all handling of properties into libcros. 39// Network service properties we are interested in monitoring 40static const char* kConnectableProperty = "Connectable"; 41static const char* kIsActiveProperty = "IsActive"; 42static const char* kStateProperty = "State"; 43static const char* kConnectivityStateProperty = "ConnectivityState"; 44static const char* kSignalStrengthProperty = "Strength"; 45static const char* kActivationStateProperty = "Cellular.ActivationState"; 46static const char* kNetworkTechnologyProperty = "Cellular.NetworkTechnology"; 47static const char* kPaymentURLProperty = "Cellular.OlpUrl"; 48 static const char* kRoamingStateProperty = "Cellular.RoamingState"; 49 50// Connman state options. 51static const char* kStateIdle = "idle"; 52static const char* kStateCarrier = "carrier"; 53static const char* kStateAssociation = "association"; 54static const char* kStateConfiguration = "configuration"; 55static const char* kStateReady = "ready"; 56 static const char* kStateDisconnect = "disconnect"; 57static const char* kStateFailure = "failure"; 58static const char* kStateActivationFailure = "activation-failure"; 59 60// Connman activation state options 61static const char* kActivationStateActivated = "activated"; 62static const char* kActivationStateActivating = "activating"; 63static const char* kActivationStateNotActivated = "not-activated"; 64static const char* kActivationStatePartiallyActivated = "partially-activated"; 65static const char* kActivationStateUnknown = "unknown"; 66 67// Connman connectivity state options 68static const char* kConnStateUnrestricted = "unrestricted"; 69static const char* kConnStateRestricted = "restricted"; 70static const char* kConnStateNone = "none"; 71 72// Connman network technology options. 73static const char* kNetworkTechnology1Xrtt = "1xRTT"; 74static const char* kNetworkTechnologyEvdo = "EVDO"; 75static const char* kNetworkTechnologyGprs = "GPRS"; 76static const char* kNetworkTechnologyEdge = "EDGE"; 77static const char* kNetworkTechnologyUmts = "UMTS"; 78static const char* kNetworkTechnologyHspa = "HSPA"; 79static const char* kNetworkTechnologyHspaPlus = "HSPA+"; 80static const char* kNetworkTechnologyLte = "LTE"; 81static const char* kNetworkTechnologyLteAdvanced = "LTE Advanced"; 82 83// Connman roaming state options 84static const char* kRoamingStateHome = "home"; 85static const char* kRoamingStateRoaming = "roaming"; 86static const char* kRoamingStateUnknown = "unknown"; 87 88// How long we should remember that cellular plan payment was received. 89const int kRecentPlanPaymentHours = 6; 90 91static ConnectionState ParseState(const std::string& state) { 92 if (state == kStateIdle) 93 return STATE_IDLE; 94 if (state == kStateCarrier) 95 return STATE_CARRIER; 96 if (state == kStateAssociation) 97 return STATE_ASSOCIATION; 98 if (state == kStateConfiguration) 99 return STATE_CONFIGURATION; 100 if (state == kStateReady) 101 return STATE_READY; 102 if (state == kStateDisconnect) 103 return STATE_DISCONNECT; 104 if (state == kStateFailure) 105 return STATE_FAILURE; 106 if (state == kStateActivationFailure) 107 return STATE_ACTIVATION_FAILURE; 108 return STATE_UNKNOWN; 109} 110 111static ActivationState ParseActivationState( 112 const std::string& activation_state) { 113 if (activation_state == kActivationStateActivated) 114 return ACTIVATION_STATE_ACTIVATED; 115 if (activation_state == kActivationStateActivating) 116 return ACTIVATION_STATE_ACTIVATING; 117 if (activation_state == kActivationStateNotActivated) 118 return ACTIVATION_STATE_NOT_ACTIVATED; 119 if (activation_state == kActivationStateUnknown) 120 return ACTIVATION_STATE_UNKNOWN; 121 if (activation_state == kActivationStatePartiallyActivated) 122 return ACTIVATION_STATE_PARTIALLY_ACTIVATED; 123 return ACTIVATION_STATE_UNKNOWN; 124} 125 126static ConnectivityState ParseConnectivityState(const std::string& state) { 127 if (state == kConnStateUnrestricted) 128 return CONN_STATE_UNRESTRICTED; 129 if (state == kConnStateRestricted) 130 return CONN_STATE_RESTRICTED; 131 if (state == kConnStateNone) 132 return CONN_STATE_NONE; 133 return CONN_STATE_UNKNOWN; 134} 135 136static NetworkTechnology ParseNetworkTechnology( 137 const std::string& technology) { 138 if (technology == kNetworkTechnology1Xrtt) 139 return NETWORK_TECHNOLOGY_1XRTT; 140 if (technology == kNetworkTechnologyEvdo) 141 return NETWORK_TECHNOLOGY_EVDO; 142 if (technology == kNetworkTechnologyGprs) 143 return NETWORK_TECHNOLOGY_GPRS; 144 if (technology == kNetworkTechnologyEdge) 145 return NETWORK_TECHNOLOGY_EDGE; 146 if (technology == kNetworkTechnologyUmts) 147 return NETWORK_TECHNOLOGY_UMTS; 148 if (technology == kNetworkTechnologyHspa) 149 return NETWORK_TECHNOLOGY_HSPA; 150 if (technology == kNetworkTechnologyHspaPlus) 151 return NETWORK_TECHNOLOGY_HSPA_PLUS; 152 if (technology == kNetworkTechnologyLte) 153 return NETWORK_TECHNOLOGY_LTE; 154 if (technology == kNetworkTechnologyLteAdvanced) 155 return NETWORK_TECHNOLOGY_LTE_ADVANCED; 156 return NETWORK_TECHNOLOGY_UNKNOWN; 157} 158 159static NetworkRoamingState ParseRoamingState( 160 const std::string& roaming_state) { 161 if (roaming_state == kRoamingStateHome) 162 return ROAMING_STATE_HOME; 163 if (roaming_state == kRoamingStateRoaming) 164 return ROAMING_STATE_ROAMING; 165 if (roaming_state == kRoamingStateUnknown) 166 return ROAMING_STATE_UNKNOWN; 167 return ROAMING_STATE_UNKNOWN; 168} 169 170} // namespace 171 172// Helper function to wrap Html with <th> tag. 173static std::string WrapWithTH(std::string text) { 174 return "<th>" + text + "</th>"; 175} 176 177// Helper function to wrap Html with <td> tag. 178static std::string WrapWithTD(std::string text) { 179 return "<td>" + text + "</td>"; 180} 181 182// Helper function to create an Html table header for a Network. 183static std::string ToHtmlTableHeader(Network* network) { 184 std::string str; 185 if (network->type() == TYPE_ETHERNET) { 186 str += WrapWithTH("Active"); 187 } else if (network->type() == TYPE_WIFI || network->type() == TYPE_CELLULAR) { 188 str += WrapWithTH("Name") + WrapWithTH("Active") + 189 WrapWithTH("Auto-Connect") + WrapWithTH("Strength"); 190 if (network->type() == TYPE_WIFI) 191 str += WrapWithTH("Encryption") + WrapWithTH("Passphrase") + 192 WrapWithTH("Identity") + WrapWithTH("Certificate"); 193 } 194 str += WrapWithTH("State") + WrapWithTH("Error") + WrapWithTH("IP Address"); 195 return str; 196} 197 198// Helper function to create an Html table row for a Network. 199static std::string ToHtmlTableRow(Network* network) { 200 std::string str; 201 if (network->type() == TYPE_ETHERNET) { 202 str += WrapWithTD(base::IntToString(network->is_active())); 203 } else if (network->type() == TYPE_WIFI || network->type() == TYPE_CELLULAR) { 204 WirelessNetwork* wireless = static_cast<WirelessNetwork*>(network); 205 str += WrapWithTD(wireless->name()) + 206 WrapWithTD(base::IntToString(network->is_active())) + 207 WrapWithTD(base::IntToString(wireless->auto_connect())) + 208 WrapWithTD(base::IntToString(wireless->strength())); 209 if (network->type() == TYPE_WIFI) { 210 WifiNetwork* wifi = static_cast<WifiNetwork*>(network); 211 str += WrapWithTD(wifi->GetEncryptionString()) + 212 WrapWithTD(std::string(wifi->passphrase().length(), '*')) + 213 WrapWithTD(wifi->identity()) + WrapWithTD(wifi->cert_path()); 214 } 215 } 216 str += WrapWithTD(network->GetStateString()) + 217 WrapWithTD(network->failed() ? network->GetErrorString() : "") + 218 WrapWithTD(network->ip_address()); 219 return str; 220} 221 222// Safe string constructor since we can't rely on non NULL pointers 223// for string values from libcros. 224static std::string SafeString(const char* s) { 225 return s ? std::string(s) : std::string(); 226} 227 228static bool EnsureCrosLoaded() { 229 if (!CrosLibrary::Get()->EnsureLoaded()) { 230 return false; 231 } else { 232 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { 233 LOG(ERROR) << "chromeos_library calls made from non UI thread!"; 234 NOTREACHED(); 235 } 236 return true; 237 } 238} 239 240//////////////////////////////////////////////////////////////////////////////// 241// Network 242 243Network::Network(const Network& network) { 244 service_path_ = network.service_path_; 245 device_path_ = network.device_path_; 246 ip_address_ = network.ip_address_; 247 type_ = network.type_; 248 state_ = network.state_; 249 error_ = network.error_; 250 connectable_ = network.connectable_; 251 is_active_ = network.is_active_; 252} 253 254void Network::Clear() { 255 service_path_.clear(); 256 device_path_.clear(); 257 ip_address_.clear(); 258 type_ = TYPE_UNKNOWN; 259 state_ = STATE_UNKNOWN; 260 error_ = ERROR_UNKNOWN; 261 connectable_ = true; 262 is_active_ = false; 263} 264 265Network::Network(const ServiceInfo* service) { 266 type_ = service->type; 267 state_ = service->state; 268 error_ = service->error; 269 service_path_ = SafeString(service->service_path); 270 device_path_ = SafeString(service->device_path); 271 connectable_ = service->connectable; 272 is_active_ = service->is_active; 273 InitIPAddress(); 274} 275 276// Used by GetHtmlInfo() which is called from the about:network handler. 277std::string Network::GetStateString() const { 278 switch (state_) { 279 case STATE_UNKNOWN: 280 return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_STATE_UNKNOWN); 281 case STATE_IDLE: 282 return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_STATE_IDLE); 283 case STATE_CARRIER: 284 return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_STATE_CARRIER); 285 case STATE_ASSOCIATION: 286 return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_STATE_ASSOCIATION); 287 case STATE_CONFIGURATION: 288 return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_STATE_CONFIGURATION); 289 case STATE_READY: 290 return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_STATE_READY); 291 case STATE_DISCONNECT: 292 return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_STATE_DISCONNECT); 293 case STATE_FAILURE: 294 return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_STATE_FAILURE); 295 case STATE_ACTIVATION_FAILURE: 296 return l10n_util::GetStringUTF8( 297 IDS_CHROMEOS_NETWORK_STATE_ACTIVATION_FAILURE); 298 default: 299 // Usually no default, but changes to libcros may add states. 300 break; 301 } 302 return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_STATE_UNRECOGNIZED); 303} 304 305std::string Network::GetErrorString() const { 306 switch (error_) { 307 case ERROR_UNKNOWN: 308 return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_ERROR_UNKNOWN); 309 case ERROR_OUT_OF_RANGE: 310 return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_ERROR_OUT_OF_RANGE); 311 case ERROR_PIN_MISSING: 312 return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_ERROR_PIN_MISSING); 313 case ERROR_DHCP_FAILED: 314 return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_ERROR_DHCP_FAILED); 315 case ERROR_CONNECT_FAILED: 316 return l10n_util::GetStringUTF8( 317 IDS_CHROMEOS_NETWORK_ERROR_CONNECT_FAILED); 318 case ERROR_BAD_PASSPHRASE: 319 return l10n_util::GetStringUTF8( 320 IDS_CHROMEOS_NETWORK_ERROR_BAD_PASSPHRASE); 321 case ERROR_BAD_WEPKEY: 322 return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_ERROR_BAD_WEPKEY); 323 case ERROR_ACTIVATION_FAILED: 324 return l10n_util::GetStringUTF8( 325 IDS_CHROMEOS_NETWORK_ERROR_ACTIVATION_FAILED); 326 case ERROR_NEED_EVDO: 327 return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_ERROR_NEED_EVDO); 328 case ERROR_NEED_HOME_NETWORK: 329 return l10n_util::GetStringUTF8( 330 IDS_CHROMEOS_NETWORK_ERROR_NEED_HOME_NETWORK); 331 case ERROR_OTASP_FAILED: 332 return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_ERROR_OTASP_FAILED); 333 case ERROR_AAA_FAILED: 334 return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_ERROR_AAA_FAILED); 335 default: 336 // Usually no default, but changes to libcros may add errors. 337 break; 338 } 339 return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_STATE_UNRECOGNIZED); 340} 341 342void Network::InitIPAddress() { 343 ip_address_.clear(); 344 // If connected, get ip config. 345 if (EnsureCrosLoaded() && connected() && !device_path_.empty()) { 346 IPConfigStatus* ipconfig_status = ListIPConfigs(device_path_.c_str()); 347 if (ipconfig_status) { 348 for (int i = 0; i < ipconfig_status->size; i++) { 349 IPConfig ipconfig = ipconfig_status->ips[i]; 350 if (strlen(ipconfig.address) > 0) { 351 ip_address_ = ipconfig.address; 352 break; 353 } 354 } 355 FreeIPConfigStatus(ipconfig_status); 356 } 357 } 358} 359 360//////////////////////////////////////////////////////////////////////////////// 361// WirelessNetwork 362WirelessNetwork::WirelessNetwork(const WirelessNetwork& network) 363 : Network(network) { 364 name_ = network.name_; 365 strength_ = network.strength_; 366 auto_connect_ = network.auto_connect_; 367 favorite_ = network.favorite_; 368} 369 370WirelessNetwork::WirelessNetwork(const ServiceInfo* service) 371 : Network(service) { 372 name_ = SafeString(service->name); 373 strength_ = service->strength; 374 auto_connect_ = service->auto_connect; 375 favorite_ = service->favorite; 376} 377 378void WirelessNetwork::Clear() { 379 Network::Clear(); 380 name_.clear(); 381 strength_ = 0; 382 auto_connect_ = false; 383 favorite_ = false; 384} 385 386//////////////////////////////////////////////////////////////////////////////// 387// CellularDataPlan 388 389string16 CellularDataPlan::GetPlanDesciption() const { 390 switch (plan_type) { 391 case chromeos::CELLULAR_DATA_PLAN_UNLIMITED: { 392 return l10n_util::GetStringFUTF16( 393 IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PURCHASE_UNLIMITED_DATA, 394 base::TimeFormatFriendlyDate(plan_start_time)); 395 break; 396 } 397 case chromeos::CELLULAR_DATA_PLAN_METERED_PAID: { 398 return l10n_util::GetStringFUTF16( 399 IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PURCHASE_DATA, 400 FormatBytes(plan_data_bytes, 401 GetByteDisplayUnits(plan_data_bytes), 402 true), 403 base::TimeFormatFriendlyDate(plan_start_time)); 404 } 405 case chromeos::CELLULAR_DATA_PLAN_METERED_BASE: { 406 return l10n_util::GetStringFUTF16( 407 IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_RECEIVED_FREE_DATA, 408 FormatBytes(plan_data_bytes, 409 GetByteDisplayUnits(plan_data_bytes), 410 true), 411 base::TimeFormatFriendlyDate(plan_start_time)); 412 default: 413 break; 414 } 415 } 416 return string16(); 417} 418 419string16 CellularDataPlan::GetRemainingWarning() const { 420 if (plan_type == chromeos::CELLULAR_DATA_PLAN_UNLIMITED) { 421 // Time based plan. Show nearing expiration and data expiration. 422 if (remaining_time().InSeconds() <= chromeos::kCellularDataVeryLowSecs) { 423 return GetPlanExpiration(); 424 } 425 } else if (plan_type == chromeos::CELLULAR_DATA_PLAN_METERED_PAID || 426 plan_type == chromeos::CELLULAR_DATA_PLAN_METERED_BASE) { 427 // Metered plan. Show low data and out of data. 428 if (remaining_data() <= chromeos::kCellularDataVeryLowBytes) { 429 return l10n_util::GetStringFUTF16( 430 IDS_NETWORK_DATA_REMAINING_MESSAGE, 431 UTF8ToUTF16(base::Int64ToString(remaining_mbytes()))); 432 } 433 } 434 return string16(); 435} 436 437string16 CellularDataPlan::GetDataRemainingDesciption() const { 438 int64 remaining_bytes = remaining_data(); 439 switch (plan_type) { 440 case chromeos::CELLULAR_DATA_PLAN_UNLIMITED: { 441 return l10n_util::GetStringUTF16( 442 IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_UNLIMITED); 443 } 444 case chromeos::CELLULAR_DATA_PLAN_METERED_PAID: { 445 return FormatBytes(remaining_bytes, 446 GetByteDisplayUnits(remaining_bytes), 447 true); 448 } 449 case chromeos::CELLULAR_DATA_PLAN_METERED_BASE: { 450 return FormatBytes(remaining_bytes, 451 GetByteDisplayUnits(remaining_bytes), 452 true); 453 } 454 default: 455 break; 456 } 457 return string16(); 458} 459 460string16 CellularDataPlan::GetUsageInfo() const { 461 if (plan_type == chromeos::CELLULAR_DATA_PLAN_UNLIMITED) { 462 // Time based plan. Show nearing expiration and data expiration. 463 return GetPlanExpiration(); 464 } else if (plan_type == chromeos::CELLULAR_DATA_PLAN_METERED_PAID || 465 plan_type == chromeos::CELLULAR_DATA_PLAN_METERED_BASE) { 466 // Metered plan. Show low data and out of data. 467 return l10n_util::GetStringFUTF16( 468 IDS_NETWORK_DATA_AVAILABLE_MESSAGE, 469 UTF8ToUTF16(base::Int64ToString(remaining_mbytes()))); 470 } 471 return string16(); 472} 473 474std::string CellularDataPlan::GetUniqueIdentifier() const { 475 // A cellular plan is uniquely described by the union of name, type, 476 // start time, end time, and max bytes. 477 // So we just return a union of all these variables. 478 return plan_name + "|" + 479 base::Int64ToString(plan_type) + "|" + 480 base::Int64ToString(plan_start_time.ToInternalValue()) + "|" + 481 base::Int64ToString(plan_end_time.ToInternalValue()) + "|" + 482 base::Int64ToString(plan_data_bytes); 483} 484 485base::TimeDelta CellularDataPlan::remaining_time() const { 486 base::TimeDelta time = plan_end_time - base::Time::Now(); 487 return time.InMicroseconds() < 0 ? base::TimeDelta() : time; 488} 489 490int64 CellularDataPlan::remaining_minutes() const { 491 return remaining_time().InMinutes(); 492} 493 494int64 CellularDataPlan::remaining_data() const { 495 int64 data = plan_data_bytes - data_bytes_used; 496 return data < 0 ? 0 : data; 497} 498 499int64 CellularDataPlan::remaining_mbytes() const { 500 return remaining_data() / (1024 * 1024); 501} 502 503string16 CellularDataPlan::GetPlanExpiration() const { 504 return TimeFormat::TimeRemaining(remaining_time()); 505} 506 507//////////////////////////////////////////////////////////////////////////////// 508// CellularNetwork 509 510CellularNetwork::CellularNetwork() 511 : WirelessNetwork(), 512 activation_state_(ACTIVATION_STATE_UNKNOWN), 513 network_technology_(NETWORK_TECHNOLOGY_UNKNOWN), 514 roaming_state_(ROAMING_STATE_UNKNOWN), 515 connectivity_state_(CONN_STATE_UNKNOWN), 516 prl_version_(0) { 517 type_ = TYPE_CELLULAR; 518} 519 520CellularNetwork::CellularNetwork(const CellularNetwork& network) 521 : WirelessNetwork(network) { 522 activation_state_ = network.activation_state_; 523 network_technology_ = network.network_technology_; 524 roaming_state_ = network.roaming_state_; 525 connectivity_state_ = network.connectivity_state_; 526 service_name_ = network.service_name_; 527 operator_name_ = network.operator_name_; 528 operator_code_ = network.operator_code_; 529 payment_url_ = network.payment_url_; 530 meid_ = network.meid_; 531 imei_ = network.imei_; 532 imsi_ = network.imsi_; 533 esn_ = network.esn_; 534 mdn_ = network.mdn_; 535 min_ = network.min_; 536 model_id_ = network.model_id_; 537 manufacturer_ = network.manufacturer_; 538 firmware_revision_ = network.firmware_revision_; 539 hardware_revision_ = network.hardware_revision_; 540 last_update_ = network.last_update_; 541 prl_version_ = network.prl_version_; 542 type_ = TYPE_CELLULAR; 543} 544 545CellularNetwork::CellularNetwork(const ServiceInfo* service) 546 : WirelessNetwork(service) { 547 service_name_ = SafeString(service->name); 548 activation_state_ = service->activation_state; 549 network_technology_ = service->network_technology; 550 roaming_state_ = service->roaming_state; 551 connectivity_state_ = service->connectivity_state; 552 // Carrier Info 553 if (service->carrier_info) { 554 operator_name_ = SafeString(service->carrier_info->operator_name); 555 operator_code_ = SafeString(service->carrier_info->operator_code); 556 payment_url_ = SafeString(service->carrier_info->payment_url); 557 } 558 // Device Info 559 if (service->device_info) { 560 meid_ = SafeString(service->device_info->MEID); 561 imei_ = SafeString(service->device_info->IMEI); 562 imsi_ = SafeString(service->device_info->IMSI); 563 esn_ = SafeString(service->device_info->ESN); 564 mdn_ = SafeString(service->device_info->MDN); 565 min_ = SafeString(service->device_info->MIN); 566 model_id_ = SafeString(service->device_info->model_id); 567 manufacturer_ = SafeString(service->device_info->manufacturer); 568 firmware_revision_ = SafeString(service->device_info->firmware_revision); 569 hardware_revision_ = SafeString(service->device_info->hardware_revision); 570 last_update_ = SafeString(service->device_info->last_update); 571 prl_version_ = service->device_info->PRL_version; 572 } 573 type_ = TYPE_CELLULAR; 574} 575 576CellularNetwork::~CellularNetwork() { 577} 578 579bool CellularNetwork::StartActivation() const { 580 if (!EnsureCrosLoaded()) 581 return false; 582 return ActivateCellularModem(service_path_.c_str(), NULL); 583} 584 585void CellularNetwork::Clear() { 586 WirelessNetwork::Clear(); 587 activation_state_ = ACTIVATION_STATE_UNKNOWN; 588 roaming_state_ = ROAMING_STATE_UNKNOWN; 589 network_technology_ = NETWORK_TECHNOLOGY_UNKNOWN; 590 connectivity_state_ = CONN_STATE_UNKNOWN; 591 service_name_.clear(); 592 operator_name_.clear(); 593 operator_code_.clear(); 594 payment_url_.clear(); 595 meid_.clear(); 596 imei_.clear(); 597 imsi_.clear(); 598 esn_.clear(); 599 mdn_.clear(); 600 min_.clear(); 601 model_id_.clear(); 602 manufacturer_.clear(); 603 firmware_revision_.clear(); 604 hardware_revision_.clear(); 605 last_update_.clear(); 606 prl_version_ = 0; 607} 608 609const CellularDataPlan* CellularNetwork::GetSignificantDataPlan() const { 610 const CellularDataPlan* significant = NULL; 611 const CellularDataPlanVector& plans = GetDataPlans(); 612 for (CellularDataPlanVector::const_iterator iter = plans.begin(); 613 iter != plans.end(); 614 ++iter) { 615 // Set significant to the first plan or to first non metered base plan. 616 if (significant == NULL || 617 significant->plan_type == CELLULAR_DATA_PLAN_METERED_BASE) 618 significant = *iter; 619 } 620 return significant; 621} 622 623CellularNetwork::DataLeft CellularNetwork::GetDataLeft() const { 624 // If we need a new plan, then there's no data. 625 if (needs_new_plan()) 626 return DATA_NONE; 627 const CellularDataPlan* plan = GetSignificantDataPlan(); 628 if (!plan) 629 return DATA_UNKNOWN; 630 if (plan->plan_type == CELLULAR_DATA_PLAN_UNLIMITED) { 631 base::TimeDelta remaining = plan->remaining_time(); 632 if (remaining <= base::TimeDelta::FromSeconds(0)) 633 return DATA_NONE; 634 if (remaining <= base::TimeDelta::FromSeconds(kCellularDataVeryLowSecs)) 635 return DATA_VERY_LOW; 636 if (remaining <= base::TimeDelta::FromSeconds(kCellularDataLowSecs)) 637 return DATA_LOW; 638 return DATA_NORMAL; 639 } else if (plan->plan_type == CELLULAR_DATA_PLAN_METERED_PAID || 640 plan->plan_type == CELLULAR_DATA_PLAN_METERED_BASE) { 641 int64 remaining = plan->remaining_data(); 642 if (remaining <= 0) 643 return DATA_NONE; 644 if (remaining <= kCellularDataVeryLowBytes) 645 return DATA_VERY_LOW; 646 // For base plans, we do not care about low data. 647 if (remaining <= kCellularDataLowBytes && 648 plan->plan_type != CELLULAR_DATA_PLAN_METERED_BASE) 649 return DATA_LOW; 650 return DATA_NORMAL; 651 } 652 return DATA_UNKNOWN; 653} 654 655std::string CellularNetwork::GetNetworkTechnologyString() const { 656 // No need to localize these cellular technology abbreviations. 657 switch (network_technology_) { 658 case NETWORK_TECHNOLOGY_1XRTT: 659 return "1xRTT"; 660 break; 661 case NETWORK_TECHNOLOGY_EVDO: 662 return "EVDO"; 663 break; 664 case NETWORK_TECHNOLOGY_GPRS: 665 return "GPRS"; 666 break; 667 case NETWORK_TECHNOLOGY_EDGE: 668 return "EDGE"; 669 break; 670 case NETWORK_TECHNOLOGY_UMTS: 671 return "UMTS"; 672 break; 673 case NETWORK_TECHNOLOGY_HSPA: 674 return "HSPA"; 675 break; 676 case NETWORK_TECHNOLOGY_HSPA_PLUS: 677 return "HSPA Plus"; 678 break; 679 case NETWORK_TECHNOLOGY_LTE: 680 return "LTE"; 681 break; 682 case NETWORK_TECHNOLOGY_LTE_ADVANCED: 683 return "LTE Advanced"; 684 break; 685 default: 686 return l10n_util::GetStringUTF8( 687 IDS_CHROMEOS_NETWORK_CELLULAR_TECHNOLOGY_UNKNOWN); 688 break; 689 } 690} 691 692std::string CellularNetwork::GetConnectivityStateString() const { 693 // These strings do not appear in the UI, so no need to localize them 694 switch (connectivity_state_) { 695 case CONN_STATE_UNRESTRICTED: 696 return "unrestricted"; 697 break; 698 case CONN_STATE_RESTRICTED: 699 return "restricted"; 700 break; 701 case CONN_STATE_NONE: 702 return "none"; 703 break; 704 case CONN_STATE_UNKNOWN: 705 default: 706 return "unknown"; 707 } 708} 709 710std::string CellularNetwork::ActivationStateToString( 711 ActivationState activation_state) { 712 switch (activation_state) { 713 case ACTIVATION_STATE_ACTIVATED: 714 return l10n_util::GetStringUTF8( 715 IDS_CHROMEOS_NETWORK_ACTIVATION_STATE_ACTIVATED); 716 break; 717 case ACTIVATION_STATE_ACTIVATING: 718 return l10n_util::GetStringUTF8( 719 IDS_CHROMEOS_NETWORK_ACTIVATION_STATE_ACTIVATING); 720 break; 721 case ACTIVATION_STATE_NOT_ACTIVATED: 722 return l10n_util::GetStringUTF8( 723 IDS_CHROMEOS_NETWORK_ACTIVATION_STATE_NOT_ACTIVATED); 724 break; 725 case ACTIVATION_STATE_PARTIALLY_ACTIVATED: 726 return l10n_util::GetStringUTF8( 727 IDS_CHROMEOS_NETWORK_ACTIVATION_STATE_PARTIALLY_ACTIVATED); 728 break; 729 default: 730 return l10n_util::GetStringUTF8( 731 IDS_CHROMEOS_NETWORK_ACTIVATION_STATE_UNKNOWN); 732 break; 733 } 734} 735 736std::string CellularNetwork::GetActivationStateString() const { 737 return ActivationStateToString(this->activation_state_); 738} 739 740std::string CellularNetwork::GetRoamingStateString() const { 741 switch (this->roaming_state_) { 742 case ROAMING_STATE_HOME: 743 return l10n_util::GetStringUTF8( 744 IDS_CHROMEOS_NETWORK_ROAMING_STATE_HOME); 745 break; 746 case ROAMING_STATE_ROAMING: 747 return l10n_util::GetStringUTF8( 748 IDS_CHROMEOS_NETWORK_ROAMING_STATE_ROAMING); 749 break; 750 default: 751 return l10n_util::GetStringUTF8( 752 IDS_CHROMEOS_NETWORK_ROAMING_STATE_UNKNOWN); 753 break; 754 }; 755} 756 757 758//////////////////////////////////////////////////////////////////////////////// 759// WifiNetwork 760 761WifiNetwork::WifiNetwork() 762 : WirelessNetwork(), 763 encryption_(SECURITY_NONE) { 764 type_ = TYPE_WIFI; 765} 766 767WifiNetwork::WifiNetwork(const WifiNetwork& network) 768 : WirelessNetwork(network) { 769 encryption_ = network.encryption_; 770 passphrase_ = network.passphrase_; 771 passphrase_required_ = network.passphrase_required_; 772 identity_ = network.identity_; 773 cert_path_ = network.cert_path_; 774} 775 776WifiNetwork::WifiNetwork(const ServiceInfo* service) 777 : WirelessNetwork(service) { 778 encryption_ = service->security; 779 // TODO(stevenjb): Remove this if/when flimflam handles multiple profiles. 780 if (UserManager::Get()->current_user_is_owner()) 781 passphrase_ = SafeString(service->passphrase); 782 else 783 passphrase_.clear(); 784 passphrase_required_ = service->passphrase_required; 785 identity_ = SafeString(service->identity); 786 cert_path_ = SafeString(service->cert_path); 787 type_ = TYPE_WIFI; 788} 789 790void WifiNetwork::Clear() { 791 WirelessNetwork::Clear(); 792 encryption_ = SECURITY_NONE; 793 passphrase_.clear(); 794 identity_.clear(); 795 cert_path_.clear(); 796} 797 798std::string WifiNetwork::GetEncryptionString() { 799 switch (encryption_) { 800 case SECURITY_UNKNOWN: 801 break; 802 case SECURITY_NONE: 803 return ""; 804 case SECURITY_WEP: 805 return "WEP"; 806 case SECURITY_WPA: 807 return "WPA"; 808 case SECURITY_RSN: 809 return "RSN"; 810 case SECURITY_8021X: 811 return "8021X"; 812 } 813 return "Unknown"; 814} 815 816bool WifiNetwork::IsPassphraseRequired() const { 817 // TODO(stevenjb): Remove error_ tests when fixed in flimflam 818 // (http://crosbug.com/10135). 819 if (error_ == ERROR_BAD_PASSPHRASE || error_ == ERROR_BAD_WEPKEY) 820 return true; 821 return passphrase_required_; 822} 823 824// Parse 'path' to determine if the certificate is stored in a pkcs#11 device. 825// flimflam recognizes the string "SETTINGS:" to specify authentication 826// parameters. 'key_id=' indicates that the certificate is stored in a pkcs#11 827// device. See src/third_party/flimflam/files/doc/service-api.txt. 828bool WifiNetwork::IsCertificateLoaded() const { 829 static const std::string settings_string("SETTINGS:"); 830 static const std::string pkcs11_key("key_id"); 831 if (cert_path_.find(settings_string) == 0) { 832 std::string::size_type idx = cert_path_.find(pkcs11_key); 833 if (idx != std::string::npos) 834 idx = cert_path_.find_first_not_of(kWhitespaceASCII, 835 idx + pkcs11_key.length()); 836 if (idx != std::string::npos && cert_path_[idx] == '=') 837 return true; 838 } 839 return false; 840} 841 842//////////////////////////////////////////////////////////////////////////////// 843// NetworkLibrary 844 845class NetworkLibraryImpl : public NetworkLibrary { 846 public: 847 NetworkLibraryImpl() 848 : network_manager_monitor_(NULL), 849 data_plan_monitor_(NULL), 850 ethernet_(NULL), 851 wifi_(NULL), 852 cellular_(NULL), 853 available_devices_(0), 854 enabled_devices_(0), 855 connected_devices_(0), 856 wifi_scanning_(false), 857 offline_mode_(false), 858 is_locked_(false), 859 update_task_(NULL) { 860 if (EnsureCrosLoaded()) { 861 Init(); 862 network_manager_monitor_ = 863 MonitorNetworkManager(&NetworkManagerStatusChangedHandler, 864 this); 865 data_plan_monitor_ = MonitorCellularDataPlan(&DataPlanUpdateHandler, 866 this); 867 network_login_observer_.reset(new NetworkLoginObserver(this)); 868 } else { 869 InitTestData(); 870 } 871 } 872 873 ~NetworkLibraryImpl() { 874 network_manager_observers_.Clear(); 875 if (network_manager_monitor_) 876 DisconnectPropertyChangeMonitor(network_manager_monitor_); 877 data_plan_observers_.Clear(); 878 if (data_plan_monitor_) 879 DisconnectDataPlanUpdateMonitor(data_plan_monitor_); 880 STLDeleteValues(&network_observers_); 881 ClearNetworks(); 882 } 883 884 virtual void AddNetworkManagerObserver(NetworkManagerObserver* observer) { 885 if (!network_manager_observers_.HasObserver(observer)) 886 network_manager_observers_.AddObserver(observer); 887 } 888 889 void NetworkStatusChanged() { 890 DVLOG(1) << "Got NetworkStatusChanged"; 891 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 892 if (update_task_) { 893 DVLOG(1) << " found previous task"; 894 update_task_->Cancel(); 895 } 896 update_task_ = 897 NewRunnableMethod(this, 898 &NetworkLibraryImpl::UpdateNetworkManagerStatus); 899 BrowserThread::PostDelayedTask( 900 BrowserThread::UI, FROM_HERE, update_task_, 901 kNetworkUpdateDelayMs); 902 } 903 904 virtual void RemoveNetworkManagerObserver(NetworkManagerObserver* observer) { 905 network_manager_observers_.RemoveObserver(observer); 906 } 907 908 virtual void AddNetworkObserver(const std::string& service_path, 909 NetworkObserver* observer) { 910 DCHECK(observer); 911 if (!EnsureCrosLoaded()) 912 return; 913 // First, add the observer to the callback map. 914 NetworkObserverMap::iterator iter = network_observers_.find(service_path); 915 NetworkObserverList* oblist; 916 if (iter != network_observers_.end()) { 917 oblist = iter->second; 918 } else { 919 std::pair<NetworkObserverMap::iterator, bool> inserted = 920 network_observers_.insert( 921 std::make_pair<std::string, NetworkObserverList*>( 922 service_path, 923 new NetworkObserverList(this, service_path))); 924 oblist = inserted.first->second; 925 } 926 if (!oblist->HasObserver(observer)) 927 oblist->AddObserver(observer); 928 } 929 930 virtual void RemoveNetworkObserver(const std::string& service_path, 931 NetworkObserver* observer) { 932 DCHECK(observer); 933 DCHECK(service_path.size()); 934 NetworkObserverMap::iterator map_iter = 935 network_observers_.find(service_path); 936 if (map_iter != network_observers_.end()) { 937 map_iter->second->RemoveObserver(observer); 938 if (!map_iter->second->size()) { 939 delete map_iter->second; 940 network_observers_.erase(map_iter++); 941 } 942 } 943 } 944 945 virtual void RemoveObserverForAllNetworks(NetworkObserver* observer) { 946 DCHECK(observer); 947 NetworkObserverMap::iterator map_iter = network_observers_.begin(); 948 while (map_iter != network_observers_.end()) { 949 map_iter->second->RemoveObserver(observer); 950 if (!map_iter->second->size()) { 951 delete map_iter->second; 952 network_observers_.erase(map_iter++); 953 } else { 954 ++map_iter; 955 } 956 } 957 } 958 959 virtual void Lock() { 960 if (is_locked_) 961 return; 962 is_locked_ = true; 963 NotifyNetworkManagerChanged(); 964 } 965 966 virtual void Unlock() { 967 DCHECK(is_locked_); 968 if (!is_locked_) 969 return; 970 is_locked_ = false; 971 NotifyNetworkManagerChanged(); 972 } 973 974 virtual bool IsLocked() { 975 return is_locked_; 976 } 977 978 virtual void AddCellularDataPlanObserver(CellularDataPlanObserver* observer) { 979 if (!data_plan_observers_.HasObserver(observer)) 980 data_plan_observers_.AddObserver(observer); 981 } 982 983 virtual void RemoveCellularDataPlanObserver( 984 CellularDataPlanObserver* observer) { 985 data_plan_observers_.RemoveObserver(observer); 986 } 987 988 virtual const EthernetNetwork* ethernet_network() const { return ethernet_; } 989 virtual bool ethernet_connecting() const { 990 return ethernet_ ? ethernet_->connecting() : false; 991 } 992 virtual bool ethernet_connected() const { 993 return ethernet_ ? ethernet_->connected() : false; 994 } 995 996 virtual const WifiNetwork* wifi_network() const { return wifi_; } 997 virtual bool wifi_connecting() const { 998 return wifi_ ? wifi_->connecting() : false; 999 } 1000 virtual bool wifi_connected() const { 1001 return wifi_ ? wifi_->connected() : false; 1002 } 1003 1004 virtual const CellularNetwork* cellular_network() const { return cellular_; } 1005 virtual bool cellular_connecting() const { 1006 return cellular_ ? cellular_->connecting() : false; 1007 } 1008 virtual bool cellular_connected() const { 1009 return cellular_ ? cellular_->connected() : false; 1010 } 1011 1012 bool Connected() const { 1013 return ethernet_connected() || wifi_connected() || cellular_connected(); 1014 } 1015 1016 bool Connecting() const { 1017 return ethernet_connecting() || wifi_connecting() || cellular_connecting(); 1018 } 1019 1020 const std::string& IPAddress() const { 1021 // Returns IP address for the active network. 1022 const Network* active = active_network(); 1023 if (active != NULL) 1024 return active->ip_address(); 1025 if (ethernet_) 1026 return ethernet_->ip_address(); 1027 static std::string null_address("0.0.0.0"); 1028 return null_address; 1029 } 1030 1031 virtual const WifiNetworkVector& wifi_networks() const { 1032 return wifi_networks_; 1033 } 1034 1035 virtual const WifiNetworkVector& remembered_wifi_networks() const { 1036 return remembered_wifi_networks_; 1037 } 1038 1039 virtual const CellularNetworkVector& cellular_networks() const { 1040 return cellular_networks_; 1041 } 1042 1043 ///////////////////////////////////////////////////////////////////////////// 1044 1045 virtual WifiNetwork* FindWifiNetworkByPath( 1046 const std::string& path) { 1047 return GetWirelessNetworkByPath(wifi_networks_, path); 1048 } 1049 1050 virtual CellularNetwork* FindCellularNetworkByPath( 1051 const std::string& path) { 1052 return GetWirelessNetworkByPath(cellular_networks_, path); 1053 } 1054 1055 virtual void RequestWifiScan() { 1056 if (EnsureCrosLoaded() && wifi_enabled()) { 1057 wifi_scanning_ = true; // Cleared in UpdateNetworkManagerStatus. 1058 RequestScan(TYPE_WIFI); 1059 } 1060 } 1061 1062 virtual bool GetWifiAccessPoints(WifiAccessPointVector* result) { 1063 if (!EnsureCrosLoaded()) 1064 return false; 1065 DeviceNetworkList* network_list = GetDeviceNetworkList(); 1066 if (network_list == NULL) 1067 return false; 1068 result->clear(); 1069 result->reserve(network_list->network_size); 1070 const base::Time now = base::Time::Now(); 1071 for (size_t i = 0; i < network_list->network_size; ++i) { 1072 DCHECK(network_list->networks[i].address); 1073 DCHECK(network_list->networks[i].name); 1074 WifiAccessPoint ap; 1075 ap.mac_address = SafeString(network_list->networks[i].address); 1076 ap.name = SafeString(network_list->networks[i].name); 1077 ap.timestamp = now - 1078 base::TimeDelta::FromSeconds(network_list->networks[i].age_seconds); 1079 ap.signal_strength = network_list->networks[i].strength; 1080 ap.channel = network_list->networks[i].channel; 1081 result->push_back(ap); 1082 } 1083 FreeDeviceNetworkList(network_list); 1084 return true; 1085 } 1086 1087 virtual bool ConnectToWifiNetwork(WifiNetwork* network, 1088 const std::string& password, 1089 const std::string& identity, 1090 const std::string& certpath) { 1091 DCHECK(network); 1092 if (!EnsureCrosLoaded()) 1093 return true; // No library loaded, don't trigger a retry attempt. 1094 // TODO(ers) make wifi the highest priority service type 1095 if (ConnectToNetworkWithCertInfo(network->service_path().c_str(), 1096 password.empty() ? NULL : password.c_str(), 1097 identity.empty() ? NULL : identity.c_str(), 1098 certpath.empty() ? NULL : certpath.c_str())) { 1099 // Update local cache and notify listeners. 1100 WifiNetwork* wifi = GetWirelessNetworkByPath( 1101 wifi_networks_, network->service_path()); 1102 if (wifi) { 1103 wifi->set_passphrase(password); 1104 wifi->set_identity(identity); 1105 wifi->set_cert_path(certpath); 1106 wifi->set_connecting(true); 1107 wifi_ = wifi; 1108 } 1109 NotifyNetworkManagerChanged(); 1110 return true; 1111 } else { 1112 // The only likely cause for an immediate failure is a badly formatted 1113 // passphrase. TODO(stevenjb): get error information from libcros 1114 // and call set_error correctly. crosbug.com/9538. 1115 network->set_error(ERROR_BAD_PASSPHRASE); 1116 return false; // Immediate failure. 1117 } 1118 } 1119 1120 virtual bool ConnectToWifiNetwork(ConnectionSecurity security, 1121 const std::string& ssid, 1122 const std::string& password, 1123 const std::string& identity, 1124 const std::string& certpath, 1125 bool auto_connect) { 1126 if (!EnsureCrosLoaded()) 1127 return true; // No library loaded, don't trigger a retry attempt. 1128 // First create a service from hidden network. 1129 ServiceInfo* service = GetWifiService(ssid.c_str(), security); 1130 if (service) { 1131 // Set auto-connect. 1132 SetAutoConnect(service->service_path, auto_connect); 1133 // Now connect to that service. 1134 // TODO(ers) make wifi the highest priority service type 1135 bool res = ConnectToNetworkWithCertInfo( 1136 service->service_path, 1137 password.empty() ? NULL : password.c_str(), 1138 identity.empty() ? NULL : identity.c_str(), 1139 certpath.empty() ? NULL : certpath.c_str()); 1140 1141 // Clean up ServiceInfo object. 1142 FreeServiceInfo(service); 1143 return res; 1144 } else { 1145 LOG(WARNING) << "Cannot find hidden network: " << ssid; 1146 // TODO(chocobo): Show error message. 1147 return false; // Immediate failure. 1148 } 1149 } 1150 1151 virtual bool ConnectToCellularNetwork(const CellularNetwork* network) { 1152 DCHECK(network); 1153 if (!EnsureCrosLoaded()) 1154 return true; // No library loaded, don't trigger a retry attempt. 1155 // TODO(ers) make cellular the highest priority service type 1156 if (network && ConnectToNetwork(network->service_path().c_str(), NULL)) { 1157 // Update local cache and notify listeners. 1158 CellularNetwork* cellular = GetWirelessNetworkByPath( 1159 cellular_networks_, network->service_path()); 1160 if (cellular) { 1161 cellular->set_connecting(true); 1162 cellular_ = cellular; 1163 } 1164 NotifyNetworkManagerChanged(); 1165 return true; 1166 } else { 1167 return false; // Immediate failure. 1168 } 1169 } 1170 1171 virtual void RefreshCellularDataPlans(const CellularNetwork* network) { 1172 DCHECK(network); 1173 if (!EnsureCrosLoaded() || !network) 1174 return; 1175 RequestCellularDataPlanUpdate(network->service_path().c_str()); 1176 } 1177 1178 // Records information that cellular play payment had happened. 1179 virtual void SignalCellularPlanPayment() { 1180 DCHECK(!HasRecentCellularPlanPayment()); 1181 cellular_plan_payment_time_ = base::Time::Now(); 1182 } 1183 1184 // Returns true if cellular plan payment had been recorded recently. 1185 virtual bool HasRecentCellularPlanPayment() { 1186 return (base::Time::Now() - 1187 cellular_plan_payment_time_).InHours() < kRecentPlanPaymentHours; 1188 } 1189 1190 virtual void DisconnectFromWirelessNetwork(const WirelessNetwork* network) { 1191 DCHECK(network); 1192 if (!EnsureCrosLoaded() || !network) 1193 return; 1194 // TODO(ers) restore default service type priority ordering? 1195 if (DisconnectFromNetwork(network->service_path().c_str())) { 1196 // Update local cache and notify listeners. 1197 if (network->type() == TYPE_WIFI) { 1198 WifiNetwork* wifi = GetWirelessNetworkByPath( 1199 wifi_networks_, network->service_path()); 1200 if (wifi) { 1201 wifi->set_connected(false); 1202 wifi_ = NULL; 1203 } 1204 } else if (network->type() == TYPE_CELLULAR) { 1205 CellularNetwork* cellular = GetWirelessNetworkByPath( 1206 cellular_networks_, network->service_path()); 1207 if (cellular) { 1208 cellular->set_connected(false); 1209 cellular_ = NULL; 1210 } 1211 } 1212 NotifyNetworkManagerChanged(); 1213 } 1214 } 1215 1216 virtual void SaveCellularNetwork(const CellularNetwork* network) { 1217 DCHECK(network); 1218 // Update the cellular network with libcros. 1219 if (!EnsureCrosLoaded() || !network) 1220 return; 1221 CellularNetwork* cellular = 1222 GetWirelessNetworkByPath(cellular_networks_, 1223 network->service_path()); 1224 if (!cellular) { 1225 LOG(WARNING) << "Save to unknown network: " << network->service_path(); 1226 return; 1227 } 1228 1229 // Immediately update properties in the cached structure. 1230 cellular->set_auto_connect(network->auto_connect()); 1231 // Update libcros. 1232 SetAutoConnect(network->service_path().c_str(), network->auto_connect()); 1233 } 1234 1235 virtual void SaveWifiNetwork(const WifiNetwork* network) { 1236 DCHECK(network); 1237 // Update the wifi network with libcros. 1238 if (!EnsureCrosLoaded() || !network) 1239 return; 1240 WifiNetwork* wifi = GetWirelessNetworkByPath(wifi_networks_, 1241 network->service_path()); 1242 if (!wifi) { 1243 LOG(WARNING) << "Save to unknown network: " << network->service_path(); 1244 return; 1245 } 1246 // Immediately update properties in the cached structure. 1247 wifi->set_passphrase(network->passphrase()); 1248 wifi->set_identity(network->identity()); 1249 wifi->set_cert_path(network->cert_path()); 1250 wifi->set_auto_connect(network->auto_connect()); 1251 // Update libcros. 1252 const char* service_path = network->service_path().c_str(); 1253 SetPassphrase(service_path, network->passphrase().c_str()); 1254 SetIdentity(service_path, network->identity().c_str()); 1255 SetCertPath(service_path, network->cert_path().c_str()); 1256 SetAutoConnect(service_path, network->auto_connect()); 1257 } 1258 1259 virtual void ForgetWifiNetwork(const std::string& service_path) { 1260 if (!EnsureCrosLoaded()) 1261 return; 1262 // NOTE: service paths for remembered wifi networks do not match the 1263 // service paths in wifi_networks_; calling a libcros funtion that 1264 // operates on the wifi_networks_ list with this service_path will 1265 // trigger a crash because the DBUS path does not exist. 1266 // TODO(stevenjb): modify libcros to warn and fail instead of crash. 1267 // https://crosbug.com/9295 1268 if (DeleteRememberedService(service_path.c_str())) { 1269 // Update local cache and notify listeners. 1270 for (WifiNetworkVector::iterator iter = 1271 remembered_wifi_networks_.begin(); 1272 iter != remembered_wifi_networks_.end(); 1273 ++iter) { 1274 if ((*iter)->service_path() == service_path) { 1275 delete (*iter); 1276 remembered_wifi_networks_.erase(iter); 1277 break; 1278 } 1279 } 1280 NotifyNetworkManagerChanged(); 1281 } 1282 } 1283 1284 virtual bool ethernet_available() const { 1285 return available_devices_ & (1 << TYPE_ETHERNET); 1286 } 1287 virtual bool wifi_available() const { 1288 return available_devices_ & (1 << TYPE_WIFI); 1289 } 1290 virtual bool cellular_available() const { 1291 return available_devices_ & (1 << TYPE_CELLULAR); 1292 } 1293 1294 virtual bool ethernet_enabled() const { 1295 return enabled_devices_ & (1 << TYPE_ETHERNET); 1296 } 1297 virtual bool wifi_enabled() const { 1298 return enabled_devices_ & (1 << TYPE_WIFI); 1299 } 1300 virtual bool cellular_enabled() const { 1301 return enabled_devices_ & (1 << TYPE_CELLULAR); 1302 } 1303 1304 virtual bool wifi_scanning() const { 1305 return wifi_scanning_; 1306 } 1307 1308 virtual bool offline_mode() const { return offline_mode_; } 1309 1310 virtual const Network* active_network() const { 1311 if (ethernet_ && ethernet_->is_active()) 1312 return ethernet_; 1313 if (wifi_ && wifi_->is_active()) 1314 return wifi_; 1315 if (cellular_ && cellular_->is_active()) 1316 return cellular_; 1317 // Due to bug chromium-os:9310, if no active network is found, 1318 // use the first connected. 1319 // TODO(chocobo): Remove when bug 9310 is fixed. 1320 // START BUG 9310 WORKAROUND 1321 if (ethernet_ && ethernet_->connected()) { 1322 ethernet_->set_active(true); 1323 return ethernet_; 1324 } 1325 if (wifi_ && wifi_->connected()) { 1326 wifi_->set_active(true); 1327 return wifi_; 1328 } 1329 if (cellular_ && cellular_->connected()) { 1330 cellular_->set_active(true); 1331 return cellular_; 1332 } 1333 // END BUG 9310 WORKAROUND 1334 return NULL; 1335 } 1336 1337 virtual void EnableEthernetNetworkDevice(bool enable) { 1338 if (is_locked_) 1339 return; 1340 EnableNetworkDeviceType(TYPE_ETHERNET, enable); 1341 } 1342 1343 virtual void EnableWifiNetworkDevice(bool enable) { 1344 if (is_locked_) 1345 return; 1346 EnableNetworkDeviceType(TYPE_WIFI, enable); 1347 } 1348 1349 virtual void EnableCellularNetworkDevice(bool enable) { 1350 if (is_locked_) 1351 return; 1352 EnableNetworkDeviceType(TYPE_CELLULAR, enable); 1353 } 1354 1355 virtual void EnableOfflineMode(bool enable) { 1356 if (!EnsureCrosLoaded()) 1357 return; 1358 1359 // If network device is already enabled/disabled, then don't do anything. 1360 if (enable && offline_mode_) { 1361 VLOG(1) << "Trying to enable offline mode when it's already enabled."; 1362 return; 1363 } 1364 if (!enable && !offline_mode_) { 1365 VLOG(1) << "Trying to disable offline mode when it's already disabled."; 1366 return; 1367 } 1368 1369 if (SetOfflineMode(enable)) { 1370 offline_mode_ = enable; 1371 } 1372 } 1373 1374 virtual NetworkIPConfigVector GetIPConfigs(const std::string& device_path, 1375 std::string* hardware_address) { 1376 hardware_address->clear(); 1377 NetworkIPConfigVector ipconfig_vector; 1378 if (EnsureCrosLoaded() && !device_path.empty()) { 1379 IPConfigStatus* ipconfig_status = ListIPConfigs(device_path.c_str()); 1380 if (ipconfig_status) { 1381 for (int i = 0; i < ipconfig_status->size; i++) { 1382 IPConfig ipconfig = ipconfig_status->ips[i]; 1383 ipconfig_vector.push_back( 1384 NetworkIPConfig(device_path, ipconfig.type, ipconfig.address, 1385 ipconfig.netmask, ipconfig.gateway, 1386 ipconfig.name_servers)); 1387 } 1388 *hardware_address = ipconfig_status->hardware_address; 1389 FreeIPConfigStatus(ipconfig_status); 1390 // Sort the list of ip configs by type. 1391 std::sort(ipconfig_vector.begin(), ipconfig_vector.end()); 1392 } 1393 } 1394 return ipconfig_vector; 1395 } 1396 1397 virtual std::string GetHtmlInfo(int refresh) { 1398 std::string output; 1399 output.append("<html><head><title>About Network</title>"); 1400 if (refresh > 0) 1401 output.append("<meta http-equiv=\"refresh\" content=\"" + 1402 base::IntToString(refresh) + "\"/>"); 1403 output.append("</head><body>"); 1404 if (refresh > 0) { 1405 output.append("(Auto-refreshing page every " + 1406 base::IntToString(refresh) + "s)"); 1407 } else { 1408 output.append("(To auto-refresh this page: about:network/<secs>)"); 1409 } 1410 1411 if (ethernet_enabled()) { 1412 output.append("<h3>Ethernet:</h3><table border=1>"); 1413 if (ethernet_) { 1414 output.append("<tr>" + ToHtmlTableHeader(ethernet_) + "</tr>"); 1415 output.append("<tr>" + ToHtmlTableRow(ethernet_) + "</tr>"); 1416 } 1417 } 1418 1419 if (wifi_enabled()) { 1420 output.append("</table><h3>Wifi:</h3><table border=1>"); 1421 for (size_t i = 0; i < wifi_networks_.size(); ++i) { 1422 if (i == 0) 1423 output.append("<tr>" + ToHtmlTableHeader(wifi_networks_[i]) + 1424 "</tr>"); 1425 output.append("<tr>" + ToHtmlTableRow(wifi_networks_[i]) + "</tr>"); 1426 } 1427 } 1428 1429 if (cellular_enabled()) { 1430 output.append("</table><h3>Cellular:</h3><table border=1>"); 1431 for (size_t i = 0; i < cellular_networks_.size(); ++i) { 1432 if (i == 0) 1433 output.append("<tr>" + ToHtmlTableHeader(cellular_networks_[i]) + 1434 "</tr>"); 1435 output.append("<tr>" + ToHtmlTableRow(cellular_networks_[i]) + "</tr>"); 1436 } 1437 } 1438 1439 output.append("</table><h3>Remembered Wifi:</h3><table border=1>"); 1440 for (size_t i = 0; i < remembered_wifi_networks_.size(); ++i) { 1441 if (i == 0) 1442 output.append( 1443 "<tr>" + ToHtmlTableHeader(remembered_wifi_networks_[i]) + 1444 "</tr>"); 1445 output.append("<tr>" + ToHtmlTableRow(remembered_wifi_networks_[i]) + 1446 "</tr>"); 1447 } 1448 1449 output.append("</table></body></html>"); 1450 return output; 1451 } 1452 1453 private: 1454 1455 class NetworkObserverList : public ObserverList<NetworkObserver> { 1456 public: 1457 NetworkObserverList(NetworkLibraryImpl* library, 1458 const std::string& service_path) { 1459 network_monitor_ = MonitorNetworkService(&NetworkStatusChangedHandler, 1460 service_path.c_str(), 1461 library); 1462 } 1463 1464 virtual ~NetworkObserverList() { 1465 if (network_monitor_) 1466 DisconnectPropertyChangeMonitor(network_monitor_); 1467 } 1468 1469 private: 1470 static void NetworkStatusChangedHandler(void* object, 1471 const char* path, 1472 const char* key, 1473 const Value* value) { 1474 NetworkLibraryImpl* networklib = static_cast<NetworkLibraryImpl*>(object); 1475 DCHECK(networklib); 1476 networklib->UpdateNetworkStatus(path, key, value); 1477 } 1478 PropertyChangeMonitor network_monitor_; 1479 }; 1480 1481 typedef std::map<std::string, NetworkObserverList*> NetworkObserverMap; 1482 1483 static void NetworkManagerStatusChangedHandler(void* object, 1484 const char* path, 1485 const char* key, 1486 const Value* value) { 1487 NetworkLibraryImpl* networklib = static_cast<NetworkLibraryImpl*>(object); 1488 DCHECK(networklib); 1489 networklib->NetworkStatusChanged(); 1490 } 1491 1492 static void DataPlanUpdateHandler(void* object, 1493 const char* modem_service_path, 1494 const CellularDataPlanList* dataplan) { 1495 NetworkLibraryImpl* networklib = static_cast<NetworkLibraryImpl*>(object); 1496 if (!networklib || !networklib->cellular_network()) { 1497 // This might happen if an update is received as we are shutting down. 1498 return; 1499 } 1500 // Store data plan for currently connected cellular network. 1501 if (networklib->cellular_network()->service_path() 1502 .compare(modem_service_path) == 0) { 1503 if (dataplan != NULL) { 1504 networklib->UpdateCellularDataPlan(dataplan); 1505 } 1506 } 1507 } 1508 1509 void ParseSystem(SystemInfo* system) { 1510 std::string prev_cellular_service_path = cellular_ ? 1511 cellular_->service_path() : std::string(); 1512 bool prev_cellular_connected = cellular_ ? 1513 cellular_->connected() : false; 1514 std::vector<CellularDataPlan> prev_cellular_data_plans; 1515 if (cellular_) { 1516 const CellularDataPlanVector& plans = cellular_->GetDataPlans(); 1517 for (CellularDataPlanVector::const_iterator iter = plans.begin(); 1518 iter != plans.end(); 1519 ++iter) { 1520 prev_cellular_data_plans.push_back(**iter); 1521 } 1522 } 1523 1524 ClearNetworks(); 1525 available_devices_ = system->available_technologies; 1526 enabled_devices_ = system->enabled_technologies; 1527 connected_devices_ = system->connected_technologies; 1528 offline_mode_ = system->offline_mode; 1529 1530 DVLOG(1) << "ParseSystem:"; 1531 for (int i = 0; i < system->service_size; i++) { 1532 const ServiceInfo* service = system->GetServiceInfo(i); 1533 DVLOG(1) << " (" << service->type << ") " << service->name 1534 << " mode=" << service->mode 1535 << " state=" << service->state 1536 << " sec=" << service->security 1537 << " req=" << service->passphrase_required 1538 << " pass=" << service->passphrase 1539 << " id=" << service->identity 1540 << " certpath=" << service->cert_path 1541 << " str=" << service->strength 1542 << " fav=" << service->favorite 1543 << " auto=" << service->auto_connect 1544 << " is_active=" << service->is_active 1545 << " error=" << service->error; 1546 // Once a connected ethernet service is found, disregard other ethernet 1547 // services that are also found 1548 if (service->type == TYPE_ETHERNET) { 1549 // There could be multiple ethernet services (eth0, dummy0, etc) 1550 // In this case, once you find a connected service, ignore the 1551 // other ones. Otherwise, you may choose an ethernet service 1552 // that is not connected. 1553 if (ethernet_enabled() && 1554 (ethernet_ == NULL || !(ethernet_->connected()))) { 1555 // If previous ethernet was previously created, free it first 1556 if (ethernet_ != NULL) 1557 delete ethernet_; 1558 ethernet_ = new EthernetNetwork(service); 1559 } 1560 } else if (service->type == TYPE_WIFI) { 1561 // Sometimes flimflam still returns wifi networks when disabled. 1562 // We don't want to show these in the UI. 1563 if (wifi_enabled()) 1564 wifi_networks_.push_back(new WifiNetwork(service)); 1565 } else if (service->type == TYPE_CELLULAR) { 1566 // Sometimes flimflam still returns cellular networks when disabled. 1567 // We don't want to show these in the UI. 1568 if (cellular_enabled()) 1569 cellular_networks_.push_back(new CellularNetwork(service)); 1570 } 1571 } 1572 1573 // Create placeholder network for ethernet even if the service is not 1574 // detected at this moment. 1575 if (!ethernet_) 1576 ethernet_ = new EthernetNetwork(); 1577 1578 DVLOG(1) << "Remembered networks:"; 1579 for (int i = 0; i < system->remembered_service_size; i++) { 1580 const ServiceInfo* service = system->GetRememberedServiceInfo(i); 1581 // All services in the remembered list are "favorites" even though 1582 // they do not explicitly set the "favorite" property. 1583 DVLOG(1) << " (" << service->type << ") " << service->name 1584 << " mode=" << service->mode 1585 << " sec=" << service->security 1586 << " pass=" << service->passphrase 1587 << " id=" << service->identity 1588 << " certpath=" << service->cert_path 1589 << " auto=" << service->auto_connect; 1590 if (service->type == TYPE_WIFI) { 1591 remembered_wifi_networks_.push_back(new WifiNetwork(service)); 1592 } 1593 } 1594 1595 // Find the active wifi network (if any). 1596 wifi_ = NULL; 1597 for (size_t i = 0; i < wifi_networks_.size(); i++) { 1598 if (wifi_networks_[i]->connecting_or_connected()) { 1599 wifi_ = wifi_networks_[i]; 1600 break; // There is only one connected or connecting wifi network. 1601 } 1602 } 1603 1604 // Find the active cellular network (if any). 1605 cellular_ = NULL; 1606 for (size_t i = 0; i < cellular_networks_.size(); i++) { 1607 if (cellular_networks_[i]->connecting_or_connected()) { 1608 cellular_ = cellular_networks_[i]; 1609 // If refreshing previous cellular, then copy over prev data plans. 1610 if (cellular_->service_path() == prev_cellular_service_path) { 1611 for (std::vector<CellularDataPlan>::iterator iter = 1612 prev_cellular_data_plans.begin(); 1613 iter != prev_cellular_data_plans.end(); 1614 ++iter) { 1615 cellular_->data_plans_.push_back(new CellularDataPlan(*iter)); 1616 } 1617 } else if (!prev_cellular_connected && cellular_->connected()) { 1618 // If new cellular, then request update of the data plan list. 1619 RefreshCellularDataPlans(cellular_); 1620 } 1621 break; // There is only one connected or connecting cellular network. 1622 } 1623 } 1624 1625 wifi_scanning_ = false; 1626 for (int i = 0; i < system->device_size; i++) { 1627 const DeviceInfo* device = system->GetDeviceInfo(i); 1628 if (device->type == TYPE_WIFI && device->scanning) 1629 wifi_scanning_ = true; 1630 } 1631 } 1632 1633 void Init() { 1634 // First, get the currently available networks. This data is cached 1635 // on the connman side, so the call should be quick. 1636 VLOG(1) << "Getting initial CrOS network info."; 1637 UpdateSystemInfo(); 1638 } 1639 1640 void InitTestData() { 1641 is_locked_ = true; 1642 ethernet_ = new EthernetNetwork(); 1643 ethernet_->set_connected(true); 1644 ethernet_->set_service_path("eth1"); 1645 1646 STLDeleteElements(&wifi_networks_); 1647 wifi_networks_.clear(); 1648 WifiNetwork* wifi1 = new WifiNetwork(); 1649 wifi1->set_service_path("fw1"); 1650 wifi1->set_name("Fake Wifi 1"); 1651 wifi1->set_strength(90); 1652 wifi1->set_connected(false); 1653 wifi1->set_encryption(SECURITY_NONE); 1654 wifi_networks_.push_back(wifi1); 1655 1656 WifiNetwork* wifi2 = new WifiNetwork(); 1657 wifi2->set_service_path("fw2"); 1658 wifi2->set_name("Fake Wifi 2"); 1659 wifi2->set_strength(70); 1660 wifi2->set_connected(true); 1661 wifi2->set_encryption(SECURITY_WEP); 1662 wifi_networks_.push_back(wifi2); 1663 1664 WifiNetwork* wifi3 = new WifiNetwork(); 1665 wifi3->set_service_path("fw3"); 1666 wifi3->set_name("Fake Wifi 3"); 1667 wifi3->set_strength(50); 1668 wifi3->set_connected(false); 1669 wifi3->set_encryption(SECURITY_8021X); 1670 wifi3->set_identity("nobody@google.com"); 1671 wifi3->set_cert_path("SETTINGS:key_id=3,cert_id=3,pin=111111"); 1672 wifi_networks_.push_back(wifi3); 1673 1674 wifi_ = wifi2; 1675 1676 STLDeleteElements(&cellular_networks_); 1677 cellular_networks_.clear(); 1678 1679 CellularNetwork* cellular1 = new CellularNetwork(); 1680 cellular1->set_service_path("fc1"); 1681 cellular1->set_name("Fake Cellular 1"); 1682 cellular1->set_strength(70); 1683 cellular1->set_connected(false); 1684 cellular1->set_activation_state(ACTIVATION_STATE_ACTIVATED); 1685 cellular1->set_payment_url(std::string("http://www.google.com")); 1686 cellular1->set_network_technology(NETWORK_TECHNOLOGY_EVDO); 1687 1688 CellularDataPlan* base_plan = new CellularDataPlan(); 1689 base_plan->plan_name = "Base plan"; 1690 base_plan->plan_type = CELLULAR_DATA_PLAN_METERED_BASE; 1691 base_plan->plan_data_bytes = 100ll * 1024 * 1024; 1692 base_plan->data_bytes_used = 75ll * 1024 * 1024; 1693 cellular1->data_plans_.push_back(base_plan); 1694 1695 CellularDataPlan* paid_plan = new CellularDataPlan(); 1696 paid_plan->plan_name = "Paid plan"; 1697 paid_plan->plan_type = CELLULAR_DATA_PLAN_METERED_PAID; 1698 paid_plan->plan_data_bytes = 5ll * 1024 * 1024 * 1024; 1699 paid_plan->data_bytes_used = 3ll * 1024 * 1024 * 1024; 1700 cellular1->data_plans_.push_back(paid_plan); 1701 1702 cellular_networks_.push_back(cellular1); 1703 cellular_ = cellular1; 1704 1705 remembered_wifi_networks_.clear(); 1706 remembered_wifi_networks_.push_back(new WifiNetwork(*wifi2)); 1707 1708 int devices = (1 << TYPE_ETHERNET) | (1 << TYPE_WIFI) | 1709 (1 << TYPE_CELLULAR); 1710 available_devices_ = devices; 1711 enabled_devices_ = devices; 1712 connected_devices_ = devices; 1713 wifi_scanning_ = false; 1714 offline_mode_ = false; 1715 } 1716 1717 void UpdateSystemInfo() { 1718 if (EnsureCrosLoaded()) { 1719 UpdateNetworkManagerStatus(); 1720 } 1721 } 1722 1723 WifiNetwork* GetWifiNetworkByName(const std::string& name) { 1724 for (size_t i = 0; i < wifi_networks_.size(); ++i) { 1725 if (wifi_networks_[i]->name().compare(name) == 0) { 1726 return wifi_networks_[i]; 1727 } 1728 } 1729 return NULL; 1730 } 1731 1732 template<typename T> T GetWirelessNetworkByPath( 1733 std::vector<T>& networks, const std::string& path) { 1734 typedef typename std::vector<T>::iterator iter_t; 1735 iter_t iter = std::find_if(networks.begin(), networks.end(), 1736 WirelessNetwork::ServicePathEq(path)); 1737 return (iter != networks.end()) ? *iter : NULL; 1738 } 1739 1740 // const version 1741 template<typename T> const T GetWirelessNetworkByPath( 1742 const std::vector<T>& networks, const std::string& path) const { 1743 typedef typename std::vector<T>::const_iterator iter_t; 1744 iter_t iter = std::find_if(networks.begin(), networks.end(), 1745 WirelessNetwork::ServicePathEq(path)); 1746 return (iter != networks.end()) ? *iter : NULL; 1747 } 1748 1749 void EnableNetworkDeviceType(ConnectionType device, bool enable) { 1750 if (!EnsureCrosLoaded()) 1751 return; 1752 1753 // If network device is already enabled/disabled, then don't do anything. 1754 if (enable && (enabled_devices_ & (1 << device))) { 1755 LOG(WARNING) << "Trying to enable a device that's already enabled: " 1756 << device; 1757 return; 1758 } 1759 if (!enable && !(enabled_devices_ & (1 << device))) { 1760 LOG(WARNING) << "Trying to disable a device that's already disabled: " 1761 << device; 1762 return; 1763 } 1764 1765 EnableNetworkDevice(device, enable); 1766 } 1767 1768 void NotifyNetworkManagerChanged() { 1769 FOR_EACH_OBSERVER(NetworkManagerObserver, 1770 network_manager_observers_, 1771 OnNetworkManagerChanged(this)); 1772 } 1773 1774 void NotifyNetworkChanged(Network* network) { 1775 DCHECK(network); 1776 NetworkObserverMap::const_iterator iter = network_observers_.find( 1777 network->service_path()); 1778 if (iter != network_observers_.end()) { 1779 FOR_EACH_OBSERVER(NetworkObserver, 1780 *(iter->second), 1781 OnNetworkChanged(this, network)); 1782 } else { 1783 NOTREACHED() << 1784 "There weren't supposed to be any property change observers of " << 1785 network->service_path(); 1786 } 1787 } 1788 1789 void NotifyCellularDataPlanChanged() { 1790 FOR_EACH_OBSERVER(CellularDataPlanObserver, 1791 data_plan_observers_, 1792 OnCellularDataPlanChanged(this)); 1793 } 1794 1795 void UpdateNetworkManagerStatus() { 1796 // Make sure we run on UI thread. 1797 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1798 1799 update_task_ = NULL; 1800 VLOG(1) << "Updating Network Status"; 1801 1802 SystemInfo* system = GetSystemInfo(); 1803 if (!system) 1804 return; 1805 1806 ParseSystem(system); 1807 1808 NotifyNetworkManagerChanged(); 1809 FreeSystemInfo(system); 1810 } 1811 1812 void UpdateNetworkStatus(const char* path, 1813 const char* key, 1814 const Value* value) { 1815 if (key == NULL || value == NULL) 1816 return; 1817 // Make sure we run on UI thread. 1818 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { 1819 BrowserThread::PostTask( 1820 BrowserThread::UI, FROM_HERE, 1821 NewRunnableMethod(this, 1822 &NetworkLibraryImpl::UpdateNetworkStatus, 1823 path, key, value)); 1824 return; 1825 } 1826 1827 bool boolval = false; 1828 int intval = 0; 1829 std::string stringval; 1830 Network* network = NULL; 1831 if (ethernet_->service_path() == path) { 1832 network = ethernet_; 1833 } else { 1834 CellularNetwork* cellular = 1835 GetWirelessNetworkByPath(cellular_networks_, path); 1836 WifiNetwork* wifi = 1837 GetWirelessNetworkByPath(wifi_networks_, path); 1838 if (cellular == NULL && wifi == NULL) 1839 return; 1840 1841 WirelessNetwork* wireless = NULL; 1842 if (wifi != NULL) 1843 wireless = static_cast<WirelessNetwork*>(wifi); 1844 else 1845 wireless = static_cast<WirelessNetwork*>(cellular); 1846 1847 if (strcmp(key, kSignalStrengthProperty) == 0) { 1848 if (value->GetAsInteger(&intval)) 1849 wireless->set_strength(intval); 1850 } else if (cellular != NULL) { 1851 if (strcmp(key, kConnectivityStateProperty) == 0) { 1852 if (value->GetAsString(&stringval)) 1853 cellular->set_connectivity_state(ParseConnectivityState(stringval)); 1854 } else if (strcmp(key, kActivationStateProperty) == 0) { 1855 if (value->GetAsString(&stringval)) 1856 cellular->set_activation_state(ParseActivationState(stringval)); 1857 } else if (strcmp(key, kPaymentURLProperty) == 0) { 1858 if (value->GetAsString(&stringval)) 1859 cellular->set_payment_url(stringval); 1860 } else if (strcmp(key, kNetworkTechnologyProperty) == 0) { 1861 if (value->GetAsString(&stringval)) 1862 cellular->set_network_technology( 1863 ParseNetworkTechnology(stringval)); 1864 } else if (strcmp(key, kRoamingStateProperty) == 0) { 1865 if (value->GetAsString(&stringval)) 1866 cellular->set_roaming_state(ParseRoamingState(stringval)); 1867 } 1868 } 1869 network = wireless; 1870 } 1871 if (strcmp(key, kConnectableProperty) == 0) { 1872 if (value->GetAsBoolean(&boolval)) 1873 network->set_connectable(boolval); 1874 } else if (strcmp(key, kIsActiveProperty) == 0) { 1875 if (value->GetAsBoolean(&boolval)) 1876 network->set_active(boolval); 1877 } else if (strcmp(key, kStateProperty) == 0) { 1878 if (value->GetAsString(&stringval)) { 1879 network->set_state(ParseState(stringval)); 1880 // State changed, so refresh IP address. 1881 network->InitIPAddress(); 1882 } 1883 } 1884 if (network) 1885 NotifyNetworkChanged(network); 1886 } 1887 1888 void UpdateCellularDataPlan(const CellularDataPlanList* data_plans) { 1889 DCHECK(cellular_); 1890 cellular_->SetDataPlans(data_plans); 1891 NotifyCellularDataPlanChanged(); 1892 } 1893 1894 void ClearNetworks() { 1895 if (ethernet_) 1896 delete ethernet_; 1897 ethernet_ = NULL; 1898 wifi_ = NULL; 1899 cellular_ = NULL; 1900 STLDeleteElements(&wifi_networks_); 1901 wifi_networks_.clear(); 1902 STLDeleteElements(&cellular_networks_); 1903 cellular_networks_.clear(); 1904 STLDeleteElements(&remembered_wifi_networks_); 1905 remembered_wifi_networks_.clear(); 1906 } 1907 1908 // Network manager observer list 1909 ObserverList<NetworkManagerObserver> network_manager_observers_; 1910 1911 // Cellular data plan observer list 1912 ObserverList<CellularDataPlanObserver> data_plan_observers_; 1913 1914 // Network observer map 1915 NetworkObserverMap network_observers_; 1916 1917 // For monitoring network manager status changes. 1918 PropertyChangeMonitor network_manager_monitor_; 1919 1920 // For monitoring data plan changes to the connected cellular network. 1921 DataPlanUpdateMonitor data_plan_monitor_; 1922 1923 // Network login observer. 1924 scoped_ptr<NetworkLoginObserver> network_login_observer_; 1925 1926 // The ethernet network. 1927 EthernetNetwork* ethernet_; 1928 1929 // The list of available wifi networks. 1930 WifiNetworkVector wifi_networks_; 1931 1932 // The current connected (or connecting) wifi network. 1933 WifiNetwork* wifi_; 1934 1935 // The remembered wifi networks. 1936 WifiNetworkVector remembered_wifi_networks_; 1937 1938 // The list of available cellular networks. 1939 CellularNetworkVector cellular_networks_; 1940 1941 // The current connected (or connecting) cellular network. 1942 CellularNetwork* cellular_; 1943 1944 // The current available network devices. Bitwise flag of ConnectionTypes. 1945 int available_devices_; 1946 1947 // The current enabled network devices. Bitwise flag of ConnectionTypes. 1948 int enabled_devices_; 1949 1950 // The current connected network devices. Bitwise flag of ConnectionTypes. 1951 int connected_devices_; 1952 1953 // True if we are currently scanning for wifi networks. 1954 bool wifi_scanning_; 1955 1956 // Currently not implemented. TODO: implement or eliminate. 1957 bool offline_mode_; 1958 1959 // True if access network library is locked. 1960 bool is_locked_; 1961 1962 // Delayed task to retrieve the network information. 1963 CancelableTask* update_task_; 1964 1965 // Cellular plan payment time. 1966 base::Time cellular_plan_payment_time_; 1967 1968 DISALLOW_COPY_AND_ASSIGN(NetworkLibraryImpl); 1969}; 1970 1971class NetworkLibraryStubImpl : public NetworkLibrary { 1972 public: 1973 NetworkLibraryStubImpl() 1974 : ip_address_("1.1.1.1"), 1975 ethernet_(new EthernetNetwork()), 1976 wifi_(NULL), 1977 cellular_(NULL) { 1978 } 1979 ~NetworkLibraryStubImpl() { if (ethernet_) delete ethernet_; } 1980 virtual void AddNetworkManagerObserver(NetworkManagerObserver* observer) {} 1981 virtual void RemoveNetworkManagerObserver(NetworkManagerObserver* observer) {} 1982 virtual void AddNetworkObserver(const std::string& service_path, 1983 NetworkObserver* observer) {} 1984 virtual void RemoveNetworkObserver(const std::string& service_path, 1985 NetworkObserver* observer) {} 1986 virtual void RemoveObserverForAllNetworks(NetworkObserver* observer) {} 1987 virtual void Lock() {} 1988 virtual void Unlock() {} 1989 virtual bool IsLocked() { return true; } 1990 virtual void AddCellularDataPlanObserver( 1991 CellularDataPlanObserver* observer) {} 1992 virtual void RemoveCellularDataPlanObserver( 1993 CellularDataPlanObserver* observer) {} 1994 virtual const EthernetNetwork* ethernet_network() const { 1995 return ethernet_; 1996 } 1997 virtual bool ethernet_connecting() const { return false; } 1998 virtual bool ethernet_connected() const { return true; } 1999 virtual const WifiNetwork* wifi_network() const { 2000 return wifi_; 2001 } 2002 virtual bool wifi_connecting() const { return false; } 2003 virtual bool wifi_connected() const { return false; } 2004 virtual const CellularNetwork* cellular_network() const { 2005 return cellular_; 2006 } 2007 virtual bool cellular_connecting() const { return false; } 2008 virtual bool cellular_connected() const { return false; } 2009 2010 bool Connected() const { return true; } 2011 bool Connecting() const { return false; } 2012 const std::string& IPAddress() const { return ip_address_; } 2013 virtual const WifiNetworkVector& wifi_networks() const { 2014 return wifi_networks_; 2015 } 2016 virtual const WifiNetworkVector& remembered_wifi_networks() const { 2017 return wifi_networks_; 2018 } 2019 virtual const CellularNetworkVector& cellular_networks() const { 2020 return cellular_networks_; 2021 } 2022 virtual bool has_cellular_networks() const { 2023 return cellular_networks_.begin() != cellular_networks_.end(); 2024 } 2025 ///////////////////////////////////////////////////////////////////////////// 2026 2027 virtual WifiNetwork* FindWifiNetworkByPath( 2028 const std::string& path) { return NULL; } 2029 virtual CellularNetwork* FindCellularNetworkByPath( 2030 const std::string& path) { return NULL; } 2031 virtual void RequestWifiScan() {} 2032 virtual bool GetWifiAccessPoints(WifiAccessPointVector* result) { 2033 return false; 2034 } 2035 2036 virtual bool ConnectToWifiNetwork(WifiNetwork* network, 2037 const std::string& password, 2038 const std::string& identity, 2039 const std::string& certpath) { 2040 return true; 2041 } 2042 virtual bool ConnectToWifiNetwork(ConnectionSecurity security, 2043 const std::string& ssid, 2044 const std::string& password, 2045 const std::string& identity, 2046 const std::string& certpath, 2047 bool auto_connect) { 2048 return true; 2049 } 2050 virtual bool ConnectToCellularNetwork(const CellularNetwork* network) { 2051 return true; 2052 } 2053 virtual void RefreshCellularDataPlans(const CellularNetwork* network) {} 2054 virtual void SignalCellularPlanPayment() {} 2055 virtual bool HasRecentCellularPlanPayment() { return false; } 2056 virtual void DisconnectFromWirelessNetwork(const WirelessNetwork* network) {} 2057 virtual void SaveCellularNetwork(const CellularNetwork* network) {} 2058 virtual void SaveWifiNetwork(const WifiNetwork* network) {} 2059 virtual void ForgetWifiNetwork(const std::string& service_path) {} 2060 virtual bool ethernet_available() const { return true; } 2061 virtual bool wifi_available() const { return false; } 2062 virtual bool cellular_available() const { return false; } 2063 virtual bool ethernet_enabled() const { return true; } 2064 virtual bool wifi_enabled() const { return false; } 2065 virtual bool cellular_enabled() const { return false; } 2066 virtual bool wifi_scanning() const { return false; } 2067 virtual const Network* active_network() const { return NULL; } 2068 virtual bool offline_mode() const { return false; } 2069 virtual void EnableEthernetNetworkDevice(bool enable) {} 2070 virtual void EnableWifiNetworkDevice(bool enable) {} 2071 virtual void EnableCellularNetworkDevice(bool enable) {} 2072 virtual void EnableOfflineMode(bool enable) {} 2073 virtual NetworkIPConfigVector GetIPConfigs(const std::string& device_path, 2074 std::string* hardware_address) { 2075 hardware_address->clear(); 2076 return NetworkIPConfigVector(); 2077 } 2078 virtual std::string GetHtmlInfo(int refresh) { return std::string(); } 2079 2080 private: 2081 std::string ip_address_; 2082 EthernetNetwork* ethernet_; 2083 WifiNetwork* wifi_; 2084 CellularNetwork* cellular_; 2085 WifiNetworkVector wifi_networks_; 2086 CellularNetworkVector cellular_networks_; 2087}; 2088 2089// static 2090NetworkLibrary* NetworkLibrary::GetImpl(bool stub) { 2091 if (stub) 2092 return new NetworkLibraryStubImpl(); 2093 else 2094 return new NetworkLibraryImpl(); 2095} 2096 2097} // namespace chromeos 2098 2099// Allows InvokeLater without adding refcounting. This class is a Singleton and 2100// won't be deleted until it's last InvokeLater is run. 2101DISABLE_RUNNABLE_METHOD_REFCOUNT(chromeos::NetworkLibraryImpl); 2102