| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chromeos/network/network_state.h" | 5 #include "chromeos/network/network_state.h" |
| 6 | 6 |
| 7 #include "base/i18n/icu_encoding_detection.h" | 7 #include "base/i18n/icu_encoding_detection.h" |
| 8 #include "base/i18n/icu_string_conversions.h" | 8 #include "base/i18n/icu_string_conversions.h" |
| 9 #include "base/json/json_writer.h" | 9 #include "base/json/json_writer.h" |
| 10 #include "base/strings/string_number_conversions.h" | 10 #include "base/strings/string_number_conversions.h" |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 44 } else { | 44 } else { |
| 45 const uint32 kReplacementChar = 0xFFFD; | 45 const uint32 kReplacementChar = 0xFFFD; |
| 46 // Puts kReplacementChar if character is a control character [0,0x20) | 46 // Puts kReplacementChar if character is a control character [0,0x20) |
| 47 // or is not readable UTF8. | 47 // or is not readable UTF8. |
| 48 base::WriteUnicodeCharacter(kReplacementChar, &result); | 48 base::WriteUnicodeCharacter(kReplacementChar, &result); |
| 49 } | 49 } |
| 50 } | 50 } |
| 51 return result; | 51 return result; |
| 52 } | 52 } |
| 53 | 53 |
| 54 // Returns a new NetworkUIData* if |ui_data_value| is a valid NetworkUIData |
| 55 // dictionary string, otherwise returns NULL. |
| 56 chromeos::NetworkUIData* CreateUIDataFromValue( |
| 57 const base::Value& ui_data_value) { |
| 58 std::string ui_data_str; |
| 59 if (!ui_data_value.GetAsString(&ui_data_str)) |
| 60 return NULL; |
| 61 if (ui_data_str.empty()) |
| 62 return new chromeos::NetworkUIData(); |
| 63 |
| 64 scoped_ptr<base::DictionaryValue> ui_data_dict( |
| 65 chromeos::onc::ReadDictionaryFromJson(ui_data_str)); |
| 66 if (!ui_data_dict) |
| 67 return NULL; |
| 68 return new chromeos::NetworkUIData(*ui_data_dict); |
| 69 } |
| 70 |
| 54 } // namespace | 71 } // namespace |
| 55 | 72 |
| 56 namespace chromeos { | 73 namespace chromeos { |
| 57 | 74 |
| 58 NetworkState::NetworkState(const std::string& path) | 75 NetworkState::NetworkState(const std::string& path) |
| 59 : ManagedState(MANAGED_TYPE_NETWORK, path), | 76 : ManagedState(MANAGED_TYPE_NETWORK, path), |
| 60 auto_connect_(false), | 77 auto_connect_(false), |
| 61 favorite_(false), | 78 favorite_(false), |
| 62 priority_(0), | 79 priority_(0), |
| 63 onc_source_(onc::ONC_SOURCE_NONE), | 80 onc_source_(onc::ONC_SOURCE_NONE), |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 156 NET_LOG_ERROR("Failed to parse " + key, path()); | 173 NET_LOG_ERROR("Failed to parse " + key, path()); |
| 157 } | 174 } |
| 158 return true; | 175 return true; |
| 159 } else if (key == flimflam::kUIDataProperty) { | 176 } else if (key == flimflam::kUIDataProperty) { |
| 160 if (!GetOncSource(value, &onc_source_)) { | 177 if (!GetOncSource(value, &onc_source_)) { |
| 161 NET_LOG_ERROR("Failed to parse " + key, path()); | 178 NET_LOG_ERROR("Failed to parse " + key, path()); |
| 162 return false; | 179 return false; |
| 163 } | 180 } |
| 164 return true; | 181 return true; |
| 165 } else if (key == flimflam::kNetworkTechnologyProperty) { | 182 } else if (key == flimflam::kNetworkTechnologyProperty) { |
| 166 return GetStringValue(key, value, &technology_); | 183 return GetStringValue(key, value, &network_technology_); |
| 167 } else if (key == flimflam::kDeviceProperty) { | 184 } else if (key == flimflam::kDeviceProperty) { |
| 168 return GetStringValue(key, value, &device_path_); | 185 return GetStringValue(key, value, &device_path_); |
| 169 } else if (key == flimflam::kGuidProperty) { | 186 } else if (key == flimflam::kGuidProperty) { |
| 170 return GetStringValue(key, value, &guid_); | 187 return GetStringValue(key, value, &guid_); |
| 171 } else if (key == flimflam::kProfileProperty) { | 188 } else if (key == flimflam::kProfileProperty) { |
| 172 return GetStringValue(key, value, &profile_path_); | 189 return GetStringValue(key, value, &profile_path_); |
| 173 } else if (key == shill::kActivateOverNonCellularNetworkProperty) { | 190 } else if (key == shill::kActivateOverNonCellularNetworkProperty) { |
| 174 return GetBooleanValue(key, value, &activate_over_non_cellular_networks_); | 191 return GetBooleanValue(key, value, &activate_over_non_cellular_networks_); |
| 175 } else if (key == shill::kOutOfCreditsProperty) { | 192 } else if (key == shill::kOutOfCreditsProperty) { |
| 176 return GetBooleanValue(key, value, &cellular_out_of_credits_); | 193 return GetBooleanValue(key, value, &cellular_out_of_credits_); |
| 177 } else if (key == flimflam::kUsageURLProperty) { | 194 } else if (key == flimflam::kUsageURLProperty) { |
| 178 return GetStringValue(key, value, &usage_url_); | 195 return GetStringValue(key, value, &usage_url_); |
| 179 } else if (key == flimflam::kPaymentPortalProperty) { | 196 } else if (key == flimflam::kPaymentPortalProperty) { |
| 180 const DictionaryValue* dict; | 197 const DictionaryValue* dict; |
| 181 if (!value.GetAsDictionary(&dict)) | 198 if (!value.GetAsDictionary(&dict)) |
| 182 return false; | 199 return false; |
| 183 if (!dict->GetStringWithoutPathExpansion( | 200 if (!dict->GetStringWithoutPathExpansion( |
| 184 flimflam::kPaymentPortalURL, &payment_url_) || | 201 flimflam::kPaymentPortalURL, &payment_url_) || |
| 185 !dict->GetStringWithoutPathExpansion( | 202 !dict->GetStringWithoutPathExpansion( |
| 186 flimflam::kPaymentPortalMethod, &post_method_) || | 203 flimflam::kPaymentPortalMethod, &post_method_) || |
| 187 !dict->GetStringWithoutPathExpansion( | 204 !dict->GetStringWithoutPathExpansion( |
| 188 flimflam::kPaymentPortalPostData, &post_data_)) { | 205 flimflam::kPaymentPortalPostData, &post_data_)) { |
| 189 return false; | 206 return false; |
| 190 } | 207 } |
| 191 return true; | 208 return true; |
| 192 } else if (key == flimflam::kWifiHexSsid) { | |
| 193 return GetStringValue(key, value, &hex_ssid_); | |
| 194 } else if (key == flimflam::kCountryProperty) { | |
| 195 // TODO(stevenjb): This is currently experimental. If we find a case where | |
| 196 // base::DetectEncoding() fails in UpdateName(), where country_code_ is | |
| 197 // set, figure out whether we can use country_code_ with ConvertToUtf8(). | |
| 198 // crbug.com/233267. | |
| 199 return GetStringValue(key, value, &country_code_); | |
| 200 } | 209 } |
| 201 return false; | 210 return false; |
| 202 } | 211 } |
| 203 | 212 |
| 204 void NetworkState::InitialPropertiesReceived() { | 213 bool NetworkState::InitialPropertiesReceived( |
| 205 UpdateName(); | 214 const base::DictionaryValue& properties) { |
| 215 bool changed = UpdateName(properties); |
| 216 return changed; |
| 206 } | 217 } |
| 207 | 218 |
| 208 void NetworkState::GetProperties(base::DictionaryValue* dictionary) const { | 219 void NetworkState::GetProperties(base::DictionaryValue* dictionary) const { |
| 209 // Keep care that these properties are the same as in |PropertyChanged|. | 220 // Keep care that these properties are the same as in |PropertyChanged|. |
| 210 dictionary->SetStringWithoutPathExpansion(flimflam::kNameProperty, name()); | 221 dictionary->SetStringWithoutPathExpansion(flimflam::kNameProperty, name()); |
| 211 dictionary->SetStringWithoutPathExpansion(flimflam::kTypeProperty, type()); | 222 dictionary->SetStringWithoutPathExpansion(flimflam::kTypeProperty, type()); |
| 212 dictionary->SetIntegerWithoutPathExpansion(flimflam::kSignalStrengthProperty, | 223 dictionary->SetIntegerWithoutPathExpansion(flimflam::kSignalStrengthProperty, |
| 213 signal_strength_); | 224 signal_strength_); |
| 214 dictionary->SetStringWithoutPathExpansion(flimflam::kStateProperty, | 225 dictionary->SetStringWithoutPathExpansion(flimflam::kStateProperty, |
| 215 connection_state_); | 226 connection_state_); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 259 favorite_); | 270 favorite_); |
| 260 dictionary->SetIntegerWithoutPathExpansion(flimflam::kPriorityProperty, | 271 dictionary->SetIntegerWithoutPathExpansion(flimflam::kPriorityProperty, |
| 261 priority_); | 272 priority_); |
| 262 // Proxy config and ONC source are intentionally omitted: These properties are | 273 // Proxy config and ONC source are intentionally omitted: These properties are |
| 263 // placed in NetworkState to transition ProxyConfigServiceImpl from | 274 // placed in NetworkState to transition ProxyConfigServiceImpl from |
| 264 // NetworkLibrary to the new network stack. The networking extension API | 275 // NetworkLibrary to the new network stack. The networking extension API |
| 265 // shouldn't depend on this member. Once ManagedNetworkConfigurationHandler | 276 // shouldn't depend on this member. Once ManagedNetworkConfigurationHandler |
| 266 // is used instead of NetworkLibrary, we can remove them again. | 277 // is used instead of NetworkLibrary, we can remove them again. |
| 267 dictionary->SetStringWithoutPathExpansion( | 278 dictionary->SetStringWithoutPathExpansion( |
| 268 flimflam::kNetworkTechnologyProperty, | 279 flimflam::kNetworkTechnologyProperty, |
| 269 technology_); | 280 network_technology_); |
| 270 dictionary->SetStringWithoutPathExpansion(flimflam::kDeviceProperty, | 281 dictionary->SetStringWithoutPathExpansion(flimflam::kDeviceProperty, |
| 271 device_path_); | 282 device_path_); |
| 272 dictionary->SetStringWithoutPathExpansion(flimflam::kGuidProperty, guid_); | 283 dictionary->SetStringWithoutPathExpansion(flimflam::kGuidProperty, guid_); |
| 273 dictionary->SetStringWithoutPathExpansion(flimflam::kProfileProperty, | 284 dictionary->SetStringWithoutPathExpansion(flimflam::kProfileProperty, |
| 274 profile_path_); | 285 profile_path_); |
| 275 dictionary->SetBooleanWithoutPathExpansion( | 286 dictionary->SetBooleanWithoutPathExpansion( |
| 276 shill::kActivateOverNonCellularNetworkProperty, | 287 shill::kActivateOverNonCellularNetworkProperty, |
| 277 activate_over_non_cellular_networks_); | 288 activate_over_non_cellular_networks_); |
| 278 dictionary->SetBooleanWithoutPathExpansion(shill::kOutOfCreditsProperty, | 289 dictionary->SetBooleanWithoutPathExpansion(shill::kOutOfCreditsProperty, |
| 279 cellular_out_of_credits_); | 290 cellular_out_of_credits_); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 306 | 317 |
| 307 bool NetworkState::IsConnectingState() const { | 318 bool NetworkState::IsConnectingState() const { |
| 308 return StateIsConnecting(connection_state_); | 319 return StateIsConnecting(connection_state_); |
| 309 } | 320 } |
| 310 | 321 |
| 311 bool NetworkState::IsManaged() const { | 322 bool NetworkState::IsManaged() const { |
| 312 return onc_source_ == onc::ONC_SOURCE_DEVICE_POLICY || | 323 return onc_source_ == onc::ONC_SOURCE_DEVICE_POLICY || |
| 313 onc_source_ == onc::ONC_SOURCE_USER_POLICY; | 324 onc_source_ == onc::ONC_SOURCE_USER_POLICY; |
| 314 } | 325 } |
| 315 | 326 |
| 316 bool NetworkState::IsShared() const { | 327 bool NetworkState::IsPrivate() const { |
| 317 return profile_path_ == NetworkProfileHandler::kSharedProfilePath; | 328 return !profile_path_.empty() && |
| 329 profile_path_ != NetworkProfileHandler::kSharedProfilePath; |
| 318 } | 330 } |
| 319 | 331 |
| 320 std::string NetworkState::GetDnsServersAsString() const { | 332 std::string NetworkState::GetDnsServersAsString() const { |
| 321 std::string result; | 333 std::string result; |
| 322 for (size_t i = 0; i < dns_servers_.size(); ++i) { | 334 for (size_t i = 0; i < dns_servers_.size(); ++i) { |
| 323 if (i != 0) | 335 if (i != 0) |
| 324 result += ","; | 336 result += ","; |
| 325 result += dns_servers_[i]; | 337 result += dns_servers_[i]; |
| 326 } | 338 } |
| 327 return result; | 339 return result; |
| 328 } | 340 } |
| 329 | 341 |
| 330 std::string NetworkState::GetNetmask() const { | 342 std::string NetworkState::GetNetmask() const { |
| 331 return network_util::PrefixLengthToNetmask(prefix_length_); | 343 return network_util::PrefixLengthToNetmask(prefix_length_); |
| 332 } | 344 } |
| 333 | 345 |
| 334 bool NetworkState::HasAuthenticationError() const { | 346 bool NetworkState::HasAuthenticationError() const { |
| 335 return (error_ == flimflam::kErrorBadPassphrase || | 347 return (error_ == flimflam::kErrorBadPassphrase || |
| 336 error_ == flimflam::kErrorBadWEPKey || | 348 error_ == flimflam::kErrorBadWEPKey || |
| 337 error_ == flimflam::kErrorPppAuthFailed || | 349 error_ == flimflam::kErrorPppAuthFailed || |
| 338 error_ == shill::kErrorEapLocalTlsFailed || | 350 error_ == shill::kErrorEapLocalTlsFailed || |
| 339 error_ == shill::kErrorEapRemoteTlsFailed || | 351 error_ == shill::kErrorEapRemoteTlsFailed || |
| 340 error_ == shill::kErrorEapAuthenticationFailed); | 352 error_ == shill::kErrorEapAuthenticationFailed); |
| 341 } | 353 } |
| 342 | 354 |
| 343 void NetworkState::UpdateName() { | 355 bool NetworkState::UpdateName(const base::DictionaryValue& properties) { |
| 344 if (hex_ssid_.empty()) { | 356 std::string hex_ssid; |
| 357 properties.GetStringWithoutPathExpansion(flimflam::kWifiHexSsid, &hex_ssid); |
| 358 if (hex_ssid.empty()) { |
| 345 // Validate name for UTF8. | 359 // Validate name for UTF8. |
| 346 std::string valid_ssid = ValidateUTF8(name()); | 360 std::string valid_ssid = ValidateUTF8(name()); |
| 347 if (valid_ssid != name()) { | 361 if (valid_ssid != name()) { |
| 348 set_name(valid_ssid); | 362 set_name(valid_ssid); |
| 349 NET_LOG_DEBUG("UpdateName", base::StringPrintf( | 363 NET_LOG_DEBUG("UpdateName", base::StringPrintf( |
| 350 "%s: UTF8: %s", path().c_str(), name().c_str())); | 364 "%s: UTF8: %s", path().c_str(), name().c_str())); |
| 365 return true; |
| 351 } | 366 } |
| 352 return; | 367 return false; |
| 353 } | 368 } |
| 354 | 369 |
| 355 std::string ssid; | 370 std::string ssid; |
| 356 std::vector<uint8> raw_ssid_bytes; | 371 std::vector<uint8> raw_ssid_bytes; |
| 357 if (base::HexStringToBytes(hex_ssid_, &raw_ssid_bytes)) { | 372 if (base::HexStringToBytes(hex_ssid, &raw_ssid_bytes)) { |
| 358 ssid = std::string(raw_ssid_bytes.begin(), raw_ssid_bytes.end()); | 373 ssid = std::string(raw_ssid_bytes.begin(), raw_ssid_bytes.end()); |
| 359 } else { | 374 } else { |
| 360 std::string desc = base::StringPrintf("%s: Error processing: %s", | 375 std::string desc = base::StringPrintf("%s: Error processing: %s", |
| 361 path().c_str(), hex_ssid_.c_str()); | 376 path().c_str(), hex_ssid.c_str()); |
| 362 NET_LOG_DEBUG("UpdateName", desc); | 377 NET_LOG_DEBUG("UpdateName", desc); |
| 363 LOG(ERROR) << desc; | 378 LOG(ERROR) << desc; |
| 364 ssid = name(); | 379 ssid = name(); |
| 365 } | 380 } |
| 366 | 381 |
| 367 if (IsStringUTF8(ssid)) { | 382 if (IsStringUTF8(ssid)) { |
| 368 if (ssid != name()) { | 383 if (ssid != name()) { |
| 369 set_name(ssid); | 384 set_name(ssid); |
| 370 NET_LOG_DEBUG("UpdateName", base::StringPrintf( | 385 NET_LOG_DEBUG("UpdateName", base::StringPrintf( |
| 371 "%s: UTF8: %s", path().c_str(), name().c_str())); | 386 "%s: UTF8: %s", path().c_str(), name().c_str())); |
| 387 return true; |
| 372 } | 388 } |
| 373 return; | 389 return false; |
| 374 } | 390 } |
| 375 | 391 |
| 376 // Detect encoding and convert to UTF-8. | 392 // Detect encoding and convert to UTF-8. |
| 393 std::string country_code; |
| 394 properties.GetStringWithoutPathExpansion( |
| 395 flimflam::kCountryProperty, &country_code); |
| 377 std::string encoding; | 396 std::string encoding; |
| 378 if (!base::DetectEncoding(ssid, &encoding)) { | 397 if (!base::DetectEncoding(ssid, &encoding)) { |
| 379 // TODO(stevenjb): Test this. See comment in PropertyChanged() under | 398 // TODO(stevenjb): This is currently experimental. If we find a case where |
| 380 // flimflam::kCountryProperty. | 399 // base::DetectEncoding() fails, we need to figure out whether we can use |
| 381 encoding = country_code_; | 400 // country_code with ConvertToUtf8(). crbug.com/233267. |
| 401 encoding = country_code; |
| 382 } | 402 } |
| 383 if (!encoding.empty()) { | 403 if (!encoding.empty()) { |
| 384 std::string utf8_ssid; | 404 std::string utf8_ssid; |
| 385 if (base::ConvertToUtf8AndNormalize(ssid, encoding, &utf8_ssid)) { | 405 if (base::ConvertToUtf8AndNormalize(ssid, encoding, &utf8_ssid)) { |
| 386 set_name(utf8_ssid); | 406 if (utf8_ssid != name()) { |
| 387 NET_LOG_DEBUG("UpdateName", base::StringPrintf( | 407 set_name(utf8_ssid); |
| 388 "%s: Encoding=%s: %s", path().c_str(), | 408 NET_LOG_DEBUG("UpdateName", base::StringPrintf( |
| 389 encoding.c_str(), name().c_str())); | 409 "%s: Encoding=%s: %s", path().c_str(), |
| 390 return; | 410 encoding.c_str(), name().c_str())); |
| 411 return true; |
| 412 } |
| 413 return false; |
| 391 } | 414 } |
| 392 } | 415 } |
| 393 | 416 |
| 394 // Unrecognized encoding. Only use raw bytes if name_ is empty. | 417 // Unrecognized encoding. Only use raw bytes if name_ is empty. |
| 395 if (name().empty()) | |
| 396 set_name(ssid); | |
| 397 NET_LOG_DEBUG("UpdateName", base::StringPrintf( | 418 NET_LOG_DEBUG("UpdateName", base::StringPrintf( |
| 398 "%s: Unrecognized Encoding=%s: %s", path().c_str(), | 419 "%s: Unrecognized Encoding=%s: %s", path().c_str(), |
| 399 encoding.c_str(), name().c_str())); | 420 encoding.c_str(), ssid.c_str())); |
| 421 if (name().empty() && !ssid.empty()) { |
| 422 set_name(ssid); |
| 423 return true; |
| 424 } |
| 425 return false; |
| 400 } | 426 } |
| 401 | 427 |
| 402 // static | 428 // static |
| 403 bool NetworkState::StateIsConnected(const std::string& connection_state) { | 429 bool NetworkState::StateIsConnected(const std::string& connection_state) { |
| 404 return (connection_state == flimflam::kStateReady || | 430 return (connection_state == flimflam::kStateReady || |
| 405 connection_state == flimflam::kStateOnline || | 431 connection_state == flimflam::kStateOnline || |
| 406 connection_state == flimflam::kStatePortal); | 432 connection_state == flimflam::kStatePortal); |
| 407 } | 433 } |
| 408 | 434 |
| 409 // static | 435 // static |
| 410 bool NetworkState::StateIsConnecting(const std::string& connection_state) { | 436 bool NetworkState::StateIsConnecting(const std::string& connection_state) { |
| 411 return (connection_state == flimflam::kStateAssociation || | 437 return (connection_state == flimflam::kStateAssociation || |
| 412 connection_state == flimflam::kStateConfiguration || | 438 connection_state == flimflam::kStateConfiguration || |
| 413 connection_state == flimflam::kStateCarrier); | 439 connection_state == flimflam::kStateCarrier); |
| 414 } | 440 } |
| 415 | 441 |
| 416 // static | 442 // static |
| 417 std::string NetworkState::IPConfigProperty(const char* key) { | 443 std::string NetworkState::IPConfigProperty(const char* key) { |
| 418 return base::StringPrintf("%s.%s", shill::kIPConfigProperty, key); | 444 return base::StringPrintf("%s.%s", shill::kIPConfigProperty, key); |
| 419 } | 445 } |
| 420 | 446 |
| 421 // static | 447 // static |
| 422 bool NetworkState::GetOncSource(const base::Value& value, | 448 bool NetworkState::GetOncSource(const base::Value& ui_data_value, |
| 423 onc::ONCSource* out) { | 449 onc::ONCSource* out) { |
| 424 std::string ui_data_str; | 450 scoped_ptr<NetworkUIData> ui_data(CreateUIDataFromValue(ui_data_value)); |
| 425 if (!value.GetAsString(&ui_data_str)) | 451 if (!ui_data) |
| 426 return false; | 452 return false; |
| 427 if (ui_data_str.empty()) { | 453 *out = ui_data->onc_source(); |
| 428 *out = onc::ONC_SOURCE_NONE; | |
| 429 return true; | |
| 430 } | |
| 431 scoped_ptr<base::DictionaryValue> ui_data_dict( | |
| 432 onc::ReadDictionaryFromJson(ui_data_str)); | |
| 433 if (!ui_data_dict) | |
| 434 return false; | |
| 435 *out = NetworkUIData(*ui_data_dict).onc_source(); | |
| 436 return true; | 454 return true; |
| 437 } | 455 } |
| 438 | 456 |
| 439 } // namespace chromeos | 457 } // namespace chromeos |
| OLD | NEW |