| 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 "chrome/browser/chromeos/cros/network_library_impl_cros.h" | 5 #include "chrome/browser/chromeos/cros/network_library_impl_cros.h" |
| 6 | 6 |
| 7 #include <dbus/dbus-glib.h> | 7 #include <dbus/dbus-glib.h> |
| 8 #include "base/bind.h" | 8 #include "base/bind.h" |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/json/json_writer.h" // for debug output only. | 10 #include "base/json/json_writer.h" // for debug output only. |
| 11 #include "base/metrics/histogram.h" | 11 #include "base/metrics/histogram.h" |
| 12 #include "base/values.h" | 12 #include "base/values.h" |
| 13 #include "chrome/browser/chromeos/cros/cros_library.h" | 13 #include "chrome/browser/chromeos/cros/cros_library.h" |
| 14 #include "chrome/browser/chromeos/cros/native_network_constants.h" | 14 #include "chrome/browser/chromeos/cros/native_network_constants.h" |
| 15 #include "chrome/browser/chromeos/cros/native_network_parser.h" | 15 #include "chrome/browser/chromeos/cros/native_network_parser.h" |
| 16 #include "chrome/browser/chromeos/settings/cros_settings.h" | 16 #include "chrome/browser/chromeos/settings/cros_settings.h" |
| 17 #include "chrome/common/chrome_switches.h" | 17 #include "chrome/common/chrome_switches.h" |
| 18 #include "content/public/browser/browser_thread.h" | 18 #include "content/public/browser/browser_thread.h" |
| 19 #include "third_party/cros_system_api/dbus/service_constants.h" | 19 #include "third_party/cros_system_api/dbus/service_constants.h" |
| 20 | 20 |
| 21 using content::BrowserThread; | 21 using content::BrowserThread; |
| 22 | 22 |
| 23 namespace chromeos { | 23 namespace chromeos { |
| 24 | 24 |
| 25 // Structure used to pass IP parameter info to a DoSetIPParameters callback, |
| 26 // since Bind only takes up to six parameters. |
| 27 struct NetworkLibraryImplCros::IPParameterInfo { |
| 28 std::string address; |
| 29 std::string netmask; |
| 30 std::string gateway; |
| 31 std::string name_servers; |
| 32 int dhcp_usage_mask; |
| 33 }; |
| 34 |
| 25 namespace { | 35 namespace { |
| 26 | 36 |
| 27 // List of cellular operators names that should have data roaming always enabled | 37 // List of cellular operators names that should have data roaming always enabled |
| 28 // to be able to connect to any network. | 38 // to be able to connect to any network. |
| 29 const char* kAlwaysInRoamingOperators[] = { | 39 const char* kAlwaysInRoamingOperators[] = { |
| 30 "CUBIC", | 40 "CUBIC", |
| 31 "Cubic", | 41 "Cubic", |
| 32 }; | 42 }; |
| 33 | 43 |
| 34 // List of interfaces that have portal check enabled by default. | 44 // List of interfaces that have portal check enabled by default. |
| (...skipping 493 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 528 output.push_back((*hardware_address)[i]); | 538 output.push_back((*hardware_address)[i]); |
| 529 } | 539 } |
| 530 *hardware_address = output; | 540 *hardware_address = output; |
| 531 } | 541 } |
| 532 } else { | 542 } else { |
| 533 DCHECK_EQ(format, FORMAT_RAW_HEX); | 543 DCHECK_EQ(format, FORMAT_RAW_HEX); |
| 534 } | 544 } |
| 535 return ipconfig_vector; | 545 return ipconfig_vector; |
| 536 } | 546 } |
| 537 | 547 |
| 538 void NetworkLibraryImplCros::SetIPConfig(const NetworkIPConfig& ipconfig) { | 548 void NetworkLibraryImplCros::SetIPParameters(const std::string& service_path, |
| 539 if (ipconfig.device_path.empty()) | 549 const std::string& address, |
| 550 const std::string& netmask, |
| 551 const std::string& gateway, |
| 552 const std::string& name_servers, |
| 553 int dhcp_usage_mask) { |
| 554 if (service_path.empty()) |
| 540 return; | 555 return; |
| 541 | 556 |
| 542 VLOG(1) << "Setting IPConfig: " << ipconfig.ToString(); | 557 VLOG(1) << "Setting IP parameters: " |
| 558 << "address: " << address |
| 559 << (dhcp_usage_mask & USE_DHCP_ADDRESS ? |
| 560 " (ignored)" : " (in use)") |
| 561 << "netmask: " << netmask |
| 562 << (dhcp_usage_mask & USE_DHCP_NETMASK ? |
| 563 " (ignored)" : " (in use)") |
| 564 << "gateway: " << gateway |
| 565 << (dhcp_usage_mask & USE_DHCP_GATEWAY ? |
| 566 " (ignored)" : " (in use)") |
| 567 << "name_servers: " << name_servers |
| 568 << (dhcp_usage_mask & USE_DHCP_NAME_SERVERS ? |
| 569 " (ignored)" : " (in use)"); |
| 543 | 570 |
| 544 NetworkIPConfig* ipconfig_dhcp = NULL; | 571 // Have to pass these in a structure, since Bind only takes up to six |
| 545 std::string ipconfig_dhcp_path; | 572 // parameters. |
| 546 NetworkIPConfig* ipconfig_static = NULL; | 573 IPParameterInfo info; |
| 547 std::string ipconfig_static_path; | 574 info.address = address; |
| 575 info.netmask = netmask; |
| 576 info.gateway = gateway; |
| 577 info.name_servers = name_servers; |
| 578 info.dhcp_usage_mask = dhcp_usage_mask; |
| 579 chromeos::NetworkPropertiesCallback callback = |
| 580 base::Bind(&NetworkLibraryImplCros::SetIPParametersCallback, |
| 581 weak_ptr_factory_.GetWeakPtr(), info); |
| 548 | 582 |
| 549 NetworkIPConfigVector ipconfigs; | 583 CrosRequestNetworkServiceProperties(service_path, callback); |
| 550 std::vector<std::string> ipconfig_paths; | |
| 551 CrosListIPConfigs(ipconfig.device_path, &ipconfigs, &ipconfig_paths, NULL); | |
| 552 for (size_t i = 0; i < ipconfigs.size(); ++i) { | |
| 553 if (ipconfigs[i].type == chromeos::IPCONFIG_TYPE_DHCP) { | |
| 554 ipconfig_dhcp = &ipconfigs[i]; | |
| 555 ipconfig_dhcp_path = ipconfig_paths[i]; | |
| 556 } else if (ipconfigs[i].type == chromeos::IPCONFIG_TYPE_IPV4) { | |
| 557 ipconfig_static = &ipconfigs[i]; | |
| 558 ipconfig_static_path = ipconfig_paths[i]; | |
| 559 } | |
| 560 } | |
| 561 | |
| 562 NetworkIPConfigVector ipconfigs2; | |
| 563 std::vector<std::string> ipconfig_paths2; | |
| 564 if (ipconfig.type == chromeos::IPCONFIG_TYPE_DHCP) { | |
| 565 // If switching from static to DHCP, create new DHCP IPConfig. | |
| 566 if (!ipconfig_dhcp && | |
| 567 !CrosAddIPConfig(ipconfig.device_path, chromeos::IPCONFIG_TYPE_DHCP)) { | |
| 568 LOG(ERROR) << "Unable to add new DHCP IPConfig"; | |
| 569 return; | |
| 570 } | |
| 571 // User wants DHCP now. So delete the static IPConfig. | |
| 572 if (ipconfig_static) | |
| 573 CrosRemoveIPConfig(ipconfig_static_path); | |
| 574 } else if (ipconfig.type == chromeos::IPCONFIG_TYPE_IPV4) { | |
| 575 // If switching from DHCP to static, create new static IPConfig. | |
| 576 if (!ipconfig_static) { | |
| 577 if (!CrosAddIPConfig(ipconfig.device_path, | |
| 578 chromeos::IPCONFIG_TYPE_IPV4)) { | |
| 579 LOG(ERROR) << "Unable to add new static IPConfig"; | |
| 580 return; | |
| 581 } | |
| 582 // Now find the newly created IPConfig. | |
| 583 if (CrosListIPConfigs(ipconfig.device_path, &ipconfigs2, | |
| 584 &ipconfig_paths2, NULL)) { | |
| 585 for (size_t i = 0; i < ipconfigs2.size(); ++i) { | |
| 586 if (ipconfigs2[i].type == chromeos::IPCONFIG_TYPE_IPV4) { | |
| 587 ipconfig_static = &ipconfigs2[i]; | |
| 588 ipconfig_static_path = ipconfig_paths2[i]; | |
| 589 } | |
| 590 } | |
| 591 } | |
| 592 if (!ipconfig_static) { | |
| 593 LOG(ERROR) << "Unable to find newly added static IPConfig"; | |
| 594 return; | |
| 595 } | |
| 596 } | |
| 597 | |
| 598 // Save any changed details. | |
| 599 if (ipconfig.address != ipconfig_static->address) { | |
| 600 base::StringValue value(ipconfig.address); | |
| 601 CrosSetNetworkIPConfigProperty(ipconfig_static_path, | |
| 602 flimflam::kAddressProperty, value); | |
| 603 } | |
| 604 if (ipconfig.netmask != ipconfig_static->netmask) { | |
| 605 int prefixlen = ipconfig.GetPrefixLength(); | |
| 606 if (prefixlen == -1) { | |
| 607 VLOG(1) << "IPConfig prefix length is invalid for netmask " | |
| 608 << ipconfig.netmask; | |
| 609 } else { | |
| 610 base::FundamentalValue value(prefixlen); | |
| 611 CrosSetNetworkIPConfigProperty(ipconfig_static_path, | |
| 612 flimflam::kPrefixlenProperty, value); | |
| 613 } | |
| 614 } | |
| 615 if (ipconfig.gateway != ipconfig_static->gateway) { | |
| 616 base::StringValue value(ipconfig.gateway); | |
| 617 CrosSetNetworkIPConfigProperty(ipconfig_static_path, | |
| 618 flimflam::kGatewayProperty, value); | |
| 619 } | |
| 620 if (ipconfig.name_servers != ipconfig_static->name_servers) { | |
| 621 base::StringValue value(ipconfig.name_servers); | |
| 622 CrosSetNetworkIPConfigProperty(ipconfig_static_path, | |
| 623 flimflam::kNameServersProperty, value); | |
| 624 } | |
| 625 // Remove DHCP IPConfig if there is one. | |
| 626 if (ipconfig_dhcp) | |
| 627 CrosRemoveIPConfig(ipconfig_dhcp_path); | |
| 628 } | |
| 629 } | 584 } |
| 630 | 585 |
| 631 ///////////////////////////////////////////////////////////////////////////// | 586 ///////////////////////////////////////////////////////////////////////////// |
| 632 // Network Manager functions. | 587 // Network Manager functions. |
| 633 | 588 |
| 634 void NetworkLibraryImplCros::NetworkManagerStatusChangedHandler( | 589 void NetworkLibraryImplCros::NetworkManagerStatusChangedHandler( |
| 635 const std::string& path, | 590 const std::string& path, |
| 636 const std::string& key, | 591 const std::string& key, |
| 637 const Value& value) { | 592 const Value& value) { |
| 638 if (!NetworkManagerStatusChanged(key, &value)) { | 593 if (!NetworkManagerStatusChanged(key, &value)) { |
| (...skipping 566 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1205 VLOG(2) << "ParseNetworkDevice:" << device->name(); | 1160 VLOG(2) << "ParseNetworkDevice:" << device->name(); |
| 1206 | 1161 |
| 1207 // Re-synchronize the roaming setting with the device property if required. | 1162 // Re-synchronize the roaming setting with the device property if required. |
| 1208 if (device && device->type() == TYPE_CELLULAR) | 1163 if (device && device->type() == TYPE_CELLULAR) |
| 1209 UpdateCellularDeviceStatus(device, PROPERTY_INDEX_CELLULAR_ALLOW_ROAMING); | 1164 UpdateCellularDeviceStatus(device, PROPERTY_INDEX_CELLULAR_ALLOW_ROAMING); |
| 1210 | 1165 |
| 1211 NotifyNetworkManagerChanged(false); // Not forced. | 1166 NotifyNetworkManagerChanged(false); // Not forced. |
| 1212 AddNetworkDeviceObserver(device_path, network_device_observer_.get()); | 1167 AddNetworkDeviceObserver(device_path, network_device_observer_.get()); |
| 1213 } | 1168 } |
| 1214 | 1169 |
| 1170 void NetworkLibraryImplCros::SetIPParametersCallback( |
| 1171 const IPParameterInfo& info, |
| 1172 const std::string& service_path, |
| 1173 const base::DictionaryValue* properties) { |
| 1174 // Find the properties we're going to set, and minimize the DBus calls below |
| 1175 // by not clearing if it's already cleared, and not setting if it's already |
| 1176 // set to the same value. Also, don't reconnect at the end if nothing changed. |
| 1177 bool something_changed = false; |
| 1178 std::string current_address; |
| 1179 int32 current_prefixlen = -1; |
| 1180 std::string current_gateway; |
| 1181 std::string current_name_servers; |
| 1182 bool address_exists = properties->GetStringWithoutPathExpansion( |
| 1183 shill::kStaticIPAddressProperty, |
| 1184 ¤t_address); |
| 1185 VLOG_IF(2, address_exists) << shill::kStaticIPAddressProperty |
| 1186 << "=" << current_address; |
| 1187 bool prefixlen_exists = properties->GetIntegerWithoutPathExpansion( |
| 1188 shill::kStaticIPPrefixlenProperty, |
| 1189 ¤t_prefixlen); |
| 1190 VLOG_IF(2, prefixlen_exists) << shill::kStaticIPPrefixlenProperty |
| 1191 << "=" << current_prefixlen; |
| 1192 bool gateway_exists = properties->GetStringWithoutPathExpansion( |
| 1193 shill::kStaticIPGatewayProperty, |
| 1194 ¤t_gateway); |
| 1195 VLOG_IF(2, gateway_exists) << shill::kStaticIPGatewayProperty |
| 1196 << "=" << current_gateway; |
| 1197 bool name_servers_exist = properties->GetStringWithoutPathExpansion( |
| 1198 shill::kStaticIPNameServersProperty, |
| 1199 ¤t_name_servers); |
| 1200 VLOG_IF(2, name_servers_exist) << shill::kStaticIPNameServersProperty |
| 1201 << "=" << current_name_servers; |
| 1202 |
| 1203 if (info.dhcp_usage_mask & USE_DHCP_ADDRESS) { |
| 1204 if (address_exists) { |
| 1205 something_changed = true; |
| 1206 CrosClearNetworkServiceProperty(service_path, |
| 1207 shill::kStaticIPAddressProperty); |
| 1208 VLOG(2) << "Clearing " << shill::kStaticIPAddressProperty; |
| 1209 } |
| 1210 } else if (current_address != info.address) { |
| 1211 base::StringValue value(info.address); |
| 1212 VLOG(2) << "Setting " << shill::kStaticIPAddressProperty |
| 1213 << " to " << info.address; |
| 1214 something_changed = true; |
| 1215 CrosSetNetworkServiceProperty(service_path, |
| 1216 shill::kStaticIPAddressProperty, |
| 1217 value); |
| 1218 } |
| 1219 |
| 1220 if (info.dhcp_usage_mask & USE_DHCP_NETMASK) { |
| 1221 if (prefixlen_exists) { |
| 1222 something_changed = true; |
| 1223 CrosClearNetworkServiceProperty(service_path, |
| 1224 shill::kStaticIPPrefixlenProperty); |
| 1225 VLOG(2) << "Clearing " << shill::kStaticIPPrefixlenProperty; |
| 1226 } |
| 1227 } else { |
| 1228 int prefixlen = CrosNetmaskToPrefixLength(info.netmask); |
| 1229 if (prefixlen == -1) { |
| 1230 VLOG(1) << "IPConfig prefix length is invalid for netmask " |
| 1231 << info.netmask; |
| 1232 } else if (current_prefixlen != prefixlen) { |
| 1233 base::FundamentalValue value(prefixlen); |
| 1234 VLOG(2) << "Setting " << shill::kStaticIPPrefixlenProperty |
| 1235 << " to " << prefixlen; |
| 1236 something_changed = true; |
| 1237 CrosSetNetworkServiceProperty(service_path, |
| 1238 shill::kStaticIPPrefixlenProperty, |
| 1239 value); |
| 1240 } |
| 1241 } |
| 1242 |
| 1243 if (info.dhcp_usage_mask & USE_DHCP_GATEWAY) { |
| 1244 if (gateway_exists) { |
| 1245 something_changed = true; |
| 1246 CrosClearNetworkServiceProperty(service_path, |
| 1247 shill::kStaticIPGatewayProperty); |
| 1248 VLOG(2) << "Clearing " << shill::kStaticIPGatewayProperty; |
| 1249 } |
| 1250 } else if (current_gateway != info.gateway){ |
| 1251 base::StringValue value(info.gateway); |
| 1252 VLOG(2) << "Setting " << shill::kStaticIPGatewayProperty |
| 1253 << " to " << info.gateway; |
| 1254 something_changed = true; |
| 1255 CrosSetNetworkServiceProperty(service_path, |
| 1256 shill::kStaticIPGatewayProperty, |
| 1257 value); |
| 1258 } |
| 1259 |
| 1260 if (info.dhcp_usage_mask & USE_DHCP_NAME_SERVERS) { |
| 1261 if (name_servers_exist) { |
| 1262 something_changed = true; |
| 1263 CrosClearNetworkServiceProperty(service_path, |
| 1264 shill::kStaticIPNameServersProperty); |
| 1265 VLOG(2) << "Clearing " << shill::kStaticIPNameServersProperty; |
| 1266 } |
| 1267 } else if (current_name_servers != info.name_servers){ |
| 1268 base::StringValue value(info.name_servers); |
| 1269 VLOG(2) << "Setting " << shill::kStaticIPNameServersProperty |
| 1270 << " to " << info.name_servers; |
| 1271 something_changed = true; |
| 1272 CrosSetNetworkServiceProperty(service_path, |
| 1273 shill::kStaticIPNameServersProperty, |
| 1274 value); |
| 1275 } |
| 1276 |
| 1277 if (!something_changed) |
| 1278 return; |
| 1279 |
| 1280 // Find the network associated with this service path, and attempt to refresh |
| 1281 // its IP parameters, so that the changes to the service properties can take |
| 1282 // effect. |
| 1283 Network* network = FindNetworkByPath(service_path); |
| 1284 |
| 1285 if (network && network->connecting_or_connected()) |
| 1286 RefreshIPConfig(network); |
| 1287 } |
| 1288 |
| 1215 } // namespace chromeos | 1289 } // namespace chromeos |
| OLD | NEW |