summaryrefslogtreecommitdiff
path: root/chromium/components/arc/net
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/components/arc/net')
-rw-r--r--chromium/components/arc/net/OWNERS3
-rw-r--r--chromium/components/arc/net/arc_net_host_impl.cc524
-rw-r--r--chromium/components/arc/net/arc_net_host_impl.h6
3 files changed, 164 insertions, 369 deletions
diff --git a/chromium/components/arc/net/OWNERS b/chromium/components/arc/net/OWNERS
new file mode 100644
index 00000000000..522f9d41ab5
--- /dev/null
+++ b/chromium/components/arc/net/OWNERS
@@ -0,0 +1,3 @@
+hugobenichi@google.com
+
+# COMPONENT: Platform>Apps>ARC
diff --git a/chromium/components/arc/net/arc_net_host_impl.cc b/chromium/components/arc/net/arc_net_host_impl.cc
index 6b5aa63e8f5..be411029899 100644
--- a/chromium/components/arc/net/arc_net_host_impl.cc
+++ b/chromium/components/arc/net/arc_net_host_impl.cc
@@ -13,8 +13,6 @@
#include "base/memory/singleton.h"
#include "base/posix/eintr_wrapper.h"
#include "base/stl_util.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "base/time/time.h"
#include "chromeos/login/login_state/login_state.h"
#include "chromeos/network/device_state.h"
#include "chromeos/network/managed_network_configuration_handler.h"
@@ -24,7 +22,6 @@
#include "chromeos/network/network_state.h"
#include "chromeos/network/network_state_handler.h"
#include "chromeos/network/network_type_pattern.h"
-#include "chromeos/network/network_util.h"
#include "chromeos/network/onc/onc_utils.h"
#include "components/arc/arc_browser_context_keyed_service_factory_base.h"
#include "components/arc/arc_prefs.h"
@@ -36,10 +33,6 @@
namespace {
constexpr int kGetNetworksListLimit = 100;
-// Delay in millisecond before asking for a network property update when no IP
-// configuration can be retrieved for a network.
-constexpr base::TimeDelta kNetworkPropertyUpdateDelay =
- base::TimeDelta::FromMilliseconds(5000);
chromeos::NetworkStateHandler* GetStateHandler() {
return chromeos::NetworkHandler::Get()->network_state_handler();
@@ -70,171 +63,25 @@ bool IsDeviceOwner() {
user_manager::UserManager::Get()->GetOwnerAccountId();
}
-std::string GetStringFromONCDictionary(const base::Value* dict,
- const char* key,
- bool required) {
- DCHECK(dict->is_dict());
- const base::Value* string_value =
- dict->FindKeyOfType(key, base::Value::Type::STRING);
- if (!string_value) {
- LOG_IF(ERROR, required) << "Required property " << key << " not found.";
- return std::string();
- }
- std::string result = string_value->GetString();
- LOG_IF(ERROR, required && result.empty())
- << "Required property " << key << " is empty.";
- return result;
-}
-
-arc::mojom::SecurityType TranslateONCWifiSecurityType(
- const base::DictionaryValue* dict) {
- std::string type = GetStringFromONCDictionary(dict, onc::wifi::kSecurity,
- true /* required */);
- if (type == onc::wifi::kWEP_PSK)
+arc::mojom::SecurityType TranslateWiFiSecurity(const std::string& type) {
+ if (type == shill::kSecurityNone)
+ return arc::mojom::SecurityType::NONE;
+ if (type == shill::kSecurityWep)
return arc::mojom::SecurityType::WEP_PSK;
- if (type == onc::wifi::kWEP_8021X)
- return arc::mojom::SecurityType::WEP_8021X;
- if (type == onc::wifi::kWPA_PSK)
+ if (type == shill::kSecurityPsk)
+ return arc::mojom::SecurityType::WPA_PSK;
+ if (type == shill::kSecurityWpa)
return arc::mojom::SecurityType::WPA_PSK;
- if (type == onc::wifi::kWPA_EAP)
+ if (type == shill::kSecurity8021x)
+ return arc::mojom::SecurityType::WPA_EAP;
+ // Robust Security Network does not appear to be defined in Android.
+ // Approximate it with WPA_EAP
+ if (type == shill::kSecurityRsn)
return arc::mojom::SecurityType::WPA_EAP;
+ LOG(WARNING) << "Unknown WiFi security type " << type;
return arc::mojom::SecurityType::NONE;
}
-arc::mojom::TetheringClientState TranslateTetheringState(
- const std::string& tethering_state) {
- if (tethering_state == onc::tethering_state::kTetheringConfirmedState)
- return arc::mojom::TetheringClientState::CONFIRMED;
- else if (tethering_state == onc::tethering_state::kTetheringNotDetectedState)
- return arc::mojom::TetheringClientState::NOT_DETECTED;
- else if (tethering_state == onc::tethering_state::kTetheringSuspectedState)
- return arc::mojom::TetheringClientState::SUSPECTED;
- NOTREACHED() << "Invalid tethering state: " << tethering_state;
- return arc::mojom::TetheringClientState::NOT_DETECTED;
-}
-
-arc::mojom::WiFiPtr TranslateONCWifi(const base::DictionaryValue* dict) {
- arc::mojom::WiFiPtr wifi = arc::mojom::WiFi::New();
-
- // Optional; defaults to 0.
- dict->GetInteger(onc::wifi::kFrequency, &wifi->frequency);
-
- wifi->bssid =
- GetStringFromONCDictionary(dict, onc::wifi::kBSSID, false /* required */);
- wifi->hex_ssid = GetStringFromONCDictionary(dict, onc::wifi::kHexSSID,
- true /* required */);
-
- // Optional; defaults to false.
- dict->GetBoolean(onc::wifi::kHiddenSSID, &wifi->hidden_ssid);
-
- wifi->security = TranslateONCWifiSecurityType(dict);
-
- // Optional; defaults to 0.
- dict->GetInteger(onc::wifi::kSignalStrength, &wifi->signal_strength);
-
- return wifi;
-}
-
-// Extracts WiFi's tethering client state from a dictionary of WiFi properties.
-arc::mojom::TetheringClientState GetWifiTetheringClientState(
- const base::DictionaryValue* dict) {
- std::string tethering_state;
- dict->GetString(onc::wifi::kTetheringState, &tethering_state);
- return TranslateTetheringState(tethering_state);
-}
-
-arc::mojom::IPConfigurationPtr TranslateONCIPConfig(
- const base::Value* ip_dict) {
- DCHECK(ip_dict->is_dict());
-
- arc::mojom::IPConfigurationPtr configuration =
- arc::mojom::IPConfiguration::New();
-
- const base::Value* ip_address = ip_dict->FindKeyOfType(
- onc::ipconfig::kIPAddress, base::Value::Type::STRING);
- if (ip_address && !ip_address->GetString().empty()) {
- configuration->ip_address = ip_address->GetString();
- const base::Value* routing_prefix = ip_dict->FindKeyOfType(
- onc::ipconfig::kRoutingPrefix, base::Value::Type::INTEGER);
- if (routing_prefix)
- configuration->routing_prefix = routing_prefix->GetInt();
- else
- LOG(ERROR) << "Required property RoutingPrefix not found.";
- configuration->gateway = GetStringFromONCDictionary(
- ip_dict, onc::ipconfig::kGateway, true /* required */);
- }
-
- const base::Value* name_servers = ip_dict->FindKeyOfType(
- onc::ipconfig::kNameServers, base::Value::Type::LIST);
- if (name_servers) {
- for (const auto& entry : name_servers->GetList())
- configuration->name_servers.push_back(entry.GetString());
- }
-
- const base::Value* type =
- ip_dict->FindKeyOfType(onc::ipconfig::kType, base::Value::Type::STRING);
- configuration->type = type && type->GetString() == onc::ipconfig::kIPv6
- ? arc::mojom::IPAddressType::IPV6
- : arc::mojom::IPAddressType::IPV4;
-
- configuration->web_proxy_auto_discovery_url = GetStringFromONCDictionary(
- ip_dict, onc::ipconfig::kWebProxyAutoDiscoveryUrl, false /* required */);
-
- return configuration;
-}
-
-// Returns true if the IP configuration is valid enough for ARC. Empty IP
-// config objects can be generated when IPv4 DHCP or IPv6 autoconf has not
-// completed yet.
-bool IsValidIPConfiguration(const arc::mojom::IPConfiguration& ip_config) {
- return !ip_config.ip_address.empty() && !ip_config.gateway.empty();
-}
-
-// Returns an IPConfiguration vector from the IPConfigs ONC property, which may
-// include multiple IP configurations (e.g. IPv4 and IPv6).
-std::vector<arc::mojom::IPConfigurationPtr> IPConfigurationsFromONCIPConfigs(
- const base::Value* dict) {
- const base::Value* ip_config_list =
- dict->FindKey(onc::network_config::kIPConfigs);
- if (!ip_config_list || !ip_config_list->is_list())
- return {};
- std::vector<arc::mojom::IPConfigurationPtr> result;
- for (const auto& entry : ip_config_list->GetList()) {
- arc::mojom::IPConfigurationPtr config = TranslateONCIPConfig(&entry);
- if (config && IsValidIPConfiguration(*config))
- result.push_back(std::move(config));
- }
- return result;
-}
-
-// Returns an IPConfiguration vector from ONC property |property|, which will
-// include a single IP configuration.
-std::vector<arc::mojom::IPConfigurationPtr> IPConfigurationsFromONCProperty(
- const base::Value* dict,
- const char* property_key) {
- const base::Value* ip_dict = dict->FindKey(property_key);
- if (!ip_dict)
- return {};
- arc::mojom::IPConfigurationPtr config = TranslateONCIPConfig(ip_dict);
- if (!config || !IsValidIPConfiguration(*config))
- return {};
- std::vector<arc::mojom::IPConfigurationPtr> result;
- result.push_back(std::move(config));
- return result;
-}
-
-arc::mojom::ConnectionStateType TranslateONCConnectionState(
- const base::DictionaryValue* dict) {
- std::string connection_state = GetStringFromONCDictionary(
- dict, onc::network_config::kConnectionState, false /* required */);
-
- if (connection_state == onc::connection_state::kConnected)
- return arc::mojom::ConnectionStateType::CONNECTED;
- if (connection_state == onc::connection_state::kConnecting)
- return arc::mojom::ConnectionStateType::CONNECTING;
- return arc::mojom::ConnectionStateType::NOT_CONNECTED;
-}
-
// Translates a shill connection state into a mojo ConnectionStateType.
// This is effectively the inverse function of shill.Service::GetStateString
// defined in platform2/shill/service.cc, with in addition some of shill's
@@ -273,54 +120,47 @@ bool IsActiveNetworkState(const chromeos::NetworkState* network) {
state == shill::kStatePortalSuspected;
}
-void TranslateONCNetworkTypeDetails(const base::DictionaryValue* dict,
- arc::mojom::NetworkConfiguration* mojo) {
- std::string type = GetStringFromONCDictionary(
- dict, onc::network_config::kType, true /* required */);
- // This property will be updated as required by the relevant network types
- // below.
- mojo->tethering_client_state = arc::mojom::TetheringClientState::NOT_DETECTED;
- if (type == onc::network_type::kCellular) {
- mojo->type = arc::mojom::NetworkType::CELLULAR;
- } else if (type == onc::network_type::kEthernet) {
- mojo->type = arc::mojom::NetworkType::ETHERNET;
- } else if (type == onc::network_type::kVPN) {
- mojo->type = arc::mojom::NetworkType::VPN;
- } else if (type == onc::network_type::kWiFi) {
- mojo->type = arc::mojom::NetworkType::WIFI;
- const base::DictionaryValue* wifi_dict = nullptr;
- dict->GetDictionary(onc::network_config::kWiFi, &wifi_dict);
- DCHECK(wifi_dict);
- mojo->wifi = TranslateONCWifi(wifi_dict);
- mojo->tethering_client_state = GetWifiTetheringClientState(wifi_dict);
- } else {
- NOTREACHED() << "Unknown network type: " << type;
- }
-}
-
-// Parse a shill IPConfig dictionary and appends the resulting mojo
-// IPConfiguration object to the given |ip_configs| vector.
-void AddIpConfiguration(std::vector<arc::mojom::IPConfigurationPtr>& ip_configs,
+arc::mojom::NetworkType TranslateNetworkType(const std::string& type) {
+ if (type == shill::kTypeWifi)
+ return arc::mojom::NetworkType::WIFI;
+ if (type == shill::kTypeVPN)
+ return arc::mojom::NetworkType::VPN;
+ if (type == shill::kTypeEthernet)
+ return arc::mojom::NetworkType::ETHERNET;
+ if (type == shill::kTypeEthernetEap)
+ return arc::mojom::NetworkType::ETHERNET;
+ if (type == shill::kTypeCellular)
+ return arc::mojom::NetworkType::CELLULAR;
+ NOTREACHED() << "Unknown network type: " << type;
+ return arc::mojom::NetworkType::ETHERNET;
+}
+
+// Parses a shill IPConfig dictionary and adds the relevant fields to
+// the given |network| NetworkConfiguration object.
+void AddIpConfiguration(arc::mojom::NetworkConfiguration* network,
const base::Value* shill_ipconfig) {
if (!shill_ipconfig || !shill_ipconfig->is_dict())
return;
- auto ip_config = arc::mojom::IPConfiguration::New();
- if (const auto* address_property =
- shill_ipconfig->FindStringPath(shill::kAddressProperty))
- ip_config->ip_address = *address_property;
-
- if (const auto* gateway_property =
- shill_ipconfig->FindStringPath(shill::kGatewayProperty))
- ip_config->gateway = *gateway_property;
-
- ip_config->routing_prefix =
+ // Only set the IP address and gateway if both are defined and non empty.
+ const auto* address = shill_ipconfig->FindStringPath(shill::kAddressProperty);
+ const auto* gateway = shill_ipconfig->FindStringPath(shill::kGatewayProperty);
+ const int prefixlen =
shill_ipconfig->FindIntPath(shill::kPrefixlenProperty).value_or(0);
+ if (address && !address->empty() && gateway && !gateway->empty()) {
+ if (prefixlen < 64) {
+ network->host_ipv4_prefix_length = prefixlen;
+ network->host_ipv4_address = *address;
+ network->host_ipv4_gateway = *gateway;
+ } else {
+ network->host_ipv6_prefix_length = prefixlen;
+ network->host_ipv6_global_addresses->push_back(*address);
+ network->host_ipv6_gateway = *gateway;
+ }
+ }
- ip_config->type = (ip_config->routing_prefix < 64)
- ? arc::mojom::IPAddressType::IPV4
- : arc::mojom::IPAddressType::IPV6;
-
+ // If the user has overridden DNS with the "Google nameservers" UI options,
+ // the kStaticIPConfigProperty object will be empty except for DNS addresses.
if (const auto* dns_list =
shill_ipconfig->FindListKey(shill::kNameServersProperty)) {
for (const auto& dns_value : dns_list->GetList()) {
@@ -333,80 +173,80 @@ void AddIpConfiguration(std::vector<arc::mojom::IPConfigurationPtr>& ip_configs,
if (dns == "0.0.0.0")
continue;
- ip_config->name_servers.push_back(dns);
+ network->host_dns_addresses->push_back(dns);
}
}
- if (IsValidIPConfiguration(*ip_config))
- ip_configs.push_back(std::move(ip_config));
-}
-
-// Add shill's Device properties to the given mojo NetworkConfiguration objects.
-// This adds the network interface and current IP configurations.
-void AddDeviceProperties(arc::mojom::NetworkConfiguration* network,
- const std::string& device_path) {
- const auto* device = GetStateHandler()->GetDeviceState(device_path);
- if (!device)
- return;
-
- network->network_interface = device->interface();
-
- std::vector<arc::mojom::IPConfigurationPtr> ip_configs;
- for (const auto& kv : device->ip_configs())
- AddIpConfiguration(ip_configs, kv.second.get());
+ if (const auto* domains =
+ shill_ipconfig->FindKey(shill::kSearchDomainsProperty)) {
+ if (domains->is_list()) {
+ for (const auto& domain : domains->GetList())
+ network->host_search_domains->push_back(domain.GetString());
+ }
+ }
- // If the DeviceState had any IP configuration, always use them and ignore
- // any other IP configuration previously obtained through NetworkState.
- if (!ip_configs.empty())
- network->ip_configs = std::move(ip_configs);
+ const int mtu = shill_ipconfig->FindIntPath(shill::kMtuProperty).value_or(0);
+ if (mtu > 0)
+ network->host_mtu = mtu;
}
-arc::mojom::NetworkConfigurationPtr TranslateONCConfiguration(
+arc::mojom::NetworkConfigurationPtr TranslateNetworkProperties(
const chromeos::NetworkState* network_state,
- const base::Value* shill_dict,
- const base::DictionaryValue* onc_dict) {
+ const base::Value* shill_dict) {
auto mojo = arc::mojom::NetworkConfiguration::New();
-
- mojo->connection_state = TranslateONCConnectionState(onc_dict);
-
- mojo->guid = GetStringFromONCDictionary(onc_dict, onc::network_config::kGUID,
- true /* required */);
-
- // crbug.com/761708 - VPNs do not currently have an IPConfigs array,
- // so in order to fetch the parameters (particularly the DNS server list),
- // fall back to StaticIPConfig or SavedIPConfig.
- // TODO(b/145960788) Remove IP configuration retrieval from ONC properties.
- std::vector<arc::mojom::IPConfigurationPtr> ip_configs =
- IPConfigurationsFromONCIPConfigs(onc_dict);
- if (ip_configs.empty()) {
- ip_configs = IPConfigurationsFromONCProperty(
- onc_dict, onc::network_config::kStaticIPConfig);
+ // Initialize optional array fields to avoid null guards both here and in ARC.
+ mojo->host_ipv6_global_addresses = std::vector<std::string>();
+ mojo->host_search_domains = std::vector<std::string>();
+ mojo->host_dns_addresses = std::vector<std::string>();
+ mojo->connection_state =
+ TranslateConnectionState(network_state->connection_state());
+ mojo->guid = network_state->guid();
+ if (mojo->guid.empty())
+ LOG(ERROR) << "Missing GUID property for network " << network_state->path();
+ mojo->type = TranslateNetworkType(network_state->type());
+ mojo->is_metered =
+ shill_dict &&
+ shill_dict->FindBoolPath(shill::kMeteredProperty).value_or(false);
+
+ // IP configuration data is added from the properties of the underlying shill
+ // Device and shill Service attached to the Device. Device properties are
+ // preferred because Service properties cannot have both IPv4 and IPv6
+ // configurations at the same time for dual stack networks. It is necessary to
+ // fallback on Service properties for networks without a shill Device exposed
+ // over DBus (builtin OpenVPN, builtin L2TP client, Chrome extension VPNs),
+ // particularly to obtain the DNS server list (b/155129178).
+ // A connecting or newly connected network may not immediately have any
+ // usable IP config object if IPv4 dhcp or IPv6 autoconf have not completed
+ // yet. This case is covered by requesting shill properties asynchronously
+ // when chromeos::NetworkStateHandlerObserver::NetworkPropertiesUpdated is
+ // called.
+
+ // Add shill's Device properties to the given mojo NetworkConfiguration
+ // objects. This adds the network interface and current IP configurations.
+ if (const auto* device =
+ GetStateHandler()->GetDeviceState(network_state->device_path())) {
+ mojo->network_interface = device->interface();
+ for (const auto& kv : device->ip_configs())
+ AddIpConfiguration(mojo.get(), kv.second.get());
}
- if (ip_configs.empty()) {
- ip_configs = IPConfigurationsFromONCProperty(
- onc_dict, onc::network_config::kSavedIPConfig);
- }
- // b/155129178 Also use cached shill properties if available.
+
if (shill_dict) {
for (const auto* property :
- {shill::kIPConfigProperty, shill::kStaticIPConfigProperty,
- shill::kSavedIPConfigProperty}) {
- if (!ip_configs.empty())
- break;
-
- AddIpConfiguration(ip_configs, shill_dict->FindKey(property));
+ {shill::kStaticIPConfigProperty, shill::kSavedIPConfigProperty}) {
+ AddIpConfiguration(mojo.get(), shill_dict->FindKey(property));
}
}
- mojo->ip_configs = std::move(ip_configs);
- mojo->guid = GetStringFromONCDictionary(onc_dict, onc::network_config::kGUID,
- true /* required */);
- TranslateONCNetworkTypeDetails(onc_dict, mojo.get());
-
- if (network_state) {
- mojo->connection_state =
- TranslateConnectionState(network_state->connection_state());
- AddDeviceProperties(mojo.get(), network_state->device_path());
+ if (mojo->type == arc::mojom::NetworkType::WIFI) {
+ mojo->wifi = arc::mojom::WiFi::New();
+ mojo->wifi->bssid = network_state->bssid();
+ mojo->wifi->hex_ssid = network_state->GetHexSsid();
+ mojo->wifi->security =
+ TranslateWiFiSecurity(network_state->security_class());
+ mojo->wifi->frequency = network_state->frequency();
+ mojo->wifi->hidden_ssid = shill_dict &&
+ shill_dict->FindBoolPath(shill::kWifiHiddenSsid).value_or(false);
+ mojo->wifi->signal_strength = network_state->signal_strength();
}
return mojo;
@@ -440,25 +280,22 @@ std::vector<arc::mojom::NetworkConfigurationPtr> TranslateNetworkStates(
std::vector<arc::mojom::NetworkConfigurationPtr> networks;
for (const chromeos::NetworkState* state : network_states) {
const std::string& network_path = state->path();
- if (network_path == arc_vpn_path) {
- // Never tell Android about its own VPN.
+ // Never tell Android about its own VPN.
+ if (network_path == arc_vpn_path)
continue;
- }
+
// For tethered networks, the underlying WiFi networks are not part of
// active networks. Replace any such tethered network with its underlying
// backing network, because ARC cannot match its datapath with the tethered
// network configuration.
state = GetShillBackedNetwork(state);
- if (!state) {
+ if (!state)
continue;
- }
const auto it = shill_network_properties.find(network_path);
const auto* shill_dict =
(it != shill_network_properties.end()) ? &it->second : nullptr;
- const auto onc_dict =
- chromeos::network_util::TranslateNetworkStateToONC(state);
- auto network = TranslateONCConfiguration(state, shill_dict, onc_dict.get());
+ auto network = TranslateNetworkProperties(state, shill_dict);
network->is_default_network = state == GetStateHandler()->DefaultNetwork();
network->service_name = network_path;
networks.push_back(std::move(network));
@@ -475,7 +312,6 @@ void ForgetNetworkFailureCallback(
base::OnceCallback<void(arc::mojom::NetworkResult)> callback,
const std::string& error_name,
std::unique_ptr<base::DictionaryValue> error_data) {
- VLOG(1) << "ForgetNetworkFailureCallback: " << error_name;
std::move(callback).Run(arc::mojom::NetworkResult::FAILURE);
}
@@ -488,7 +324,6 @@ void StartConnectFailureCallback(
base::OnceCallback<void(arc::mojom::NetworkResult)> callback,
const std::string& error_name,
std::unique_ptr<base::DictionaryValue> error_data) {
- VLOG(1) << "StartConnectFailureCallback: " << error_name;
std::move(callback).Run(arc::mojom::NetworkResult::FAILURE);
}
@@ -501,17 +336,15 @@ void StartDisconnectFailureCallback(
base::OnceCallback<void(arc::mojom::NetworkResult)> callback,
const std::string& error_name,
std::unique_ptr<base::DictionaryValue> error_data) {
- VLOG(1) << "StartDisconnectFailureCallback: " << error_name;
std::move(callback).Run(arc::mojom::NetworkResult::FAILURE);
}
-void ArcVpnSuccessCallback() {
- DVLOG(1) << "ArcVpnSuccessCallback";
-}
+void ArcVpnSuccessCallback() {}
-void ArcVpnErrorCallback(const std::string& error_name,
+void ArcVpnErrorCallback(const std::string& operation,
+ const std::string& error_name,
std::unique_ptr<base::DictionaryValue> error_data) {
- LOG(ERROR) << "ArcVpnErrorCallback: " << error_name;
+ LOG(ERROR) << "ArcVpnErrorCallback: " << operation << ": " << error_name;
}
} // namespace
@@ -588,10 +421,9 @@ void ArcNetHostImpl::OnConnectionReady() {
GetShillBackedNetwork(GetStateHandler()->DefaultNetwork());
if (default_network && default_network->type() == shill::kTypeVPN &&
default_network->GetVpnProviderType() == shill::kProviderArcVpn) {
- VLOG(0) << "Disconnecting stale ARC VPN " << default_network->path();
GetNetworkConnectionHandler()->DisconnectNetwork(
default_network->path(), base::Bind(&ArcVpnSuccessCallback),
- base::Bind(&ArcVpnErrorCallback));
+ base::Bind(&ArcVpnErrorCallback, "disconnecting stale ARC VPN"));
}
}
@@ -638,8 +470,6 @@ void ArcNetHostImpl::CreateNetworkSuccessCallback(
base::OnceCallback<void(const std::string&)> callback,
const std::string& service_path,
const std::string& guid) {
- VLOG(1) << "CreateNetworkSuccessCallback";
-
cached_guid_ = guid;
cached_service_path_ = service_path;
@@ -650,13 +480,14 @@ void ArcNetHostImpl::CreateNetworkFailureCallback(
base::OnceCallback<void(const std::string&)> callback,
const std::string& error_name,
std::unique_ptr<base::DictionaryValue> error_data) {
- VLOG(1) << "CreateNetworkFailureCallback: " << error_name;
+ LOG(ERROR) << "CreateNetworkFailureCallback: " << error_name;
std::move(callback).Run(std::string());
}
void ArcNetHostImpl::CreateNetwork(mojom::WifiConfigurationPtr cfg,
CreateNetworkCallback callback) {
if (!IsDeviceOwner()) {
+ LOG(ERROR) << "Only device owner can create WiFi networks";
std::move(callback).Run(std::string());
return;
}
@@ -665,12 +496,16 @@ void ArcNetHostImpl::CreateNetwork(mojom::WifiConfigurationPtr cfg,
std::unique_ptr<base::DictionaryValue> wifi_dict(new base::DictionaryValue);
if (!cfg->hexssid.has_value() || !cfg->details) {
+ LOG(ERROR)
+ << "Cannot create WiFi network without hex ssid or WiFi properties";
std::move(callback).Run(std::string());
return;
}
+
mojom::ConfiguredNetworkDetailsPtr details =
std::move(cfg->details->get_configured());
if (!details) {
+ LOG(ERROR) << "Cannot create WiFi network without WiFi properties";
std::move(callback).Run(std::string());
return;
}
@@ -707,7 +542,7 @@ void ArcNetHostImpl::CreateNetwork(mojom::WifiConfigurationPtr cfg,
bool ArcNetHostImpl::GetNetworkPathFromGuid(const std::string& guid,
std::string* path) {
- const chromeos::NetworkState* network =
+ const auto* network =
GetShillBackedNetwork(GetStateHandler()->GetNetworkStateFromGuid(guid));
if (network) {
*path = network->path();
@@ -718,18 +553,21 @@ bool ArcNetHostImpl::GetNetworkPathFromGuid(const std::string& guid,
*path = cached_service_path_;
return true;
}
+
return false;
}
void ArcNetHostImpl::ForgetNetwork(const std::string& guid,
ForgetNetworkCallback callback) {
if (!IsDeviceOwner()) {
+ LOG(ERROR) << "Only device owner can remove WiFi networks";
std::move(callback).Run(mojom::NetworkResult::FAILURE);
return;
}
std::string path;
if (!GetNetworkPathFromGuid(guid, &path)) {
+ LOG(ERROR) << "Could not retrieve Service path from GUID " << guid;
std::move(callback).Run(mojom::NetworkResult::FAILURE);
return;
}
@@ -748,6 +586,7 @@ void ArcNetHostImpl::StartConnect(const std::string& guid,
StartConnectCallback callback) {
std::string path;
if (!GetNetworkPathFromGuid(guid, &path)) {
+ LOG(ERROR) << "Could not retrieve Service path from GUID " << guid;
std::move(callback).Run(mojom::NetworkResult::FAILURE);
return;
}
@@ -766,6 +605,7 @@ void ArcNetHostImpl::StartDisconnect(const std::string& guid,
StartDisconnectCallback callback) {
std::string path;
if (!GetNetworkPathFromGuid(guid, &path)) {
+ LOG(ERROR) << "Could not retrieve Service path from GUID " << guid;
std::move(callback).Run(mojom::NetworkResult::FAILURE);
return;
}
@@ -788,17 +628,17 @@ void ArcNetHostImpl::GetWifiEnabledState(GetWifiEnabledStateCallback callback) {
void ArcNetHostImpl::SetWifiEnabledState(bool is_enabled,
SetWifiEnabledStateCallback callback) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- chromeos::NetworkStateHandler::TechnologyState state =
- GetStateHandler()->GetTechnologyState(
- chromeos::NetworkTypePattern::WiFi());
+ auto state = GetStateHandler()->GetTechnologyState(
+ chromeos::NetworkTypePattern::WiFi());
// WiFi can't be enabled or disabled in these states.
if ((state == chromeos::NetworkStateHandler::TECHNOLOGY_PROHIBITED) ||
(state == chromeos::NetworkStateHandler::TECHNOLOGY_UNINITIALIZED) ||
(state == chromeos::NetworkStateHandler::TECHNOLOGY_UNAVAILABLE)) {
- VLOG(1) << "SetWifiEnabledState failed due to WiFi state: " << state;
+ LOG(ERROR) << "SetWifiEnabledState failed due to WiFi state: " << state;
std::move(callback).Run(false);
return;
}
+
GetStateHandler()->SetTechnologyEnabled(
chromeos::NetworkTypePattern::WiFi(), is_enabled,
chromeos::network_handler::ErrorCallback());
@@ -836,43 +676,39 @@ std::string ArcNetHostImpl::LookupArcVpnServicePath() {
false /* visible_only */, kGetNetworksListLimit, &state_list);
for (const chromeos::NetworkState* state : state_list) {
- const chromeos::NetworkState* shill_backed_network =
- GetShillBackedNetwork(state);
+ const auto* shill_backed_network = GetShillBackedNetwork(state);
if (!shill_backed_network)
continue;
- if (shill_backed_network->GetVpnProviderType() == shill::kProviderArcVpn) {
+
+ if (shill_backed_network->GetVpnProviderType() == shill::kProviderArcVpn)
return shill_backed_network->path();
- }
}
return std::string();
}
void ArcNetHostImpl::ConnectArcVpn(const std::string& service_path,
const std::string& /* guid */) {
- DVLOG(1) << "ConnectArcVpn " << service_path;
arc_vpn_service_path_ = service_path;
GetNetworkConnectionHandler()->ConnectToNetwork(
service_path, base::Bind(&ArcVpnSuccessCallback),
- base::Bind(&ArcVpnErrorCallback), false /* check_error_state */,
+ base::Bind(&ArcVpnErrorCallback, "connecting ARC VPN"),
+ false /* check_error_state */,
chromeos::ConnectCallbackMode::ON_COMPLETED);
}
std::unique_ptr<base::Value> ArcNetHostImpl::TranslateStringListToValue(
const std::vector<std::string>& string_list) {
- std::unique_ptr<base::Value> result =
- std::make_unique<base::Value>(base::Value::Type::LIST);
- for (const auto& item : string_list) {
+ auto result = std::make_unique<base::Value>(base::Value::Type::LIST);
+ for (const auto& item : string_list)
result->Append(item);
- }
return result;
}
std::unique_ptr<base::DictionaryValue>
ArcNetHostImpl::TranslateVpnConfigurationToOnc(
const mojom::AndroidVpnConfiguration& cfg) {
- std::unique_ptr<base::DictionaryValue> top_dict =
- std::make_unique<base::DictionaryValue>();
+ auto top_dict = std::make_unique<base::DictionaryValue>();
// Name, Type
top_dict->SetKey(
@@ -930,31 +766,26 @@ ArcNetHostImpl::TranslateVpnConfigurationToOnc(
void ArcNetHostImpl::AndroidVpnConnected(
mojom::AndroidVpnConfigurationPtr cfg) {
- std::unique_ptr<base::DictionaryValue> properties =
- TranslateVpnConfigurationToOnc(*cfg);
+ auto properties = TranslateVpnConfigurationToOnc(*cfg);
std::string service_path = LookupArcVpnServicePath();
if (!service_path.empty()) {
- VLOG(1) << "AndroidVpnConnected: reusing " << service_path;
GetManagedConfigurationHandler()->SetProperties(
service_path, *properties,
base::Bind(&ArcNetHostImpl::ConnectArcVpn, weak_factory_.GetWeakPtr(),
service_path, std::string()),
- base::Bind(&ArcVpnErrorCallback));
+ base::Bind(&ArcVpnErrorCallback,
+ "reconnecting ARC VPN " + service_path));
return;
}
- VLOG(1) << "AndroidVpnConnected: creating new ARC VPN";
std::string user_id_hash = chromeos::LoginState::Get()->primary_user_hash();
GetManagedConfigurationHandler()->CreateConfiguration(
user_id_hash, *properties,
base::Bind(&ArcNetHostImpl::ConnectArcVpn, weak_factory_.GetWeakPtr()),
- base::Bind(&ArcVpnErrorCallback));
+ base::Bind(&ArcVpnErrorCallback, "connecting new ARC VPN"));
}
void ArcNetHostImpl::AndroidVpnStateChanged(mojom::ConnectionStateType state) {
- VLOG(1) << "AndroidVpnStateChanged: state=" << state
- << " service=" << arc_vpn_service_path_;
-
if (state != arc::mojom::ConnectionStateType::NOT_CONNECTED ||
arc_vpn_service_path_.empty()) {
return;
@@ -968,7 +799,7 @@ void ArcNetHostImpl::AndroidVpnStateChanged(mojom::ConnectionStateType state) {
GetNetworkConnectionHandler()->DisconnectNetwork(
service_path, base::Bind(&ArcVpnSuccessCallback),
- base::Bind(&ArcVpnErrorCallback));
+ base::Bind(&ArcVpnErrorCallback, "disconnecting ARC VPN"));
}
void ArcNetHostImpl::SetAlwaysOnVpn(const std::string& vpn_package,
@@ -984,10 +815,9 @@ void ArcNetHostImpl::DisconnectArcVpn() {
auto* net_instance = ARC_GET_INSTANCE_FOR_METHOD(arc_bridge_service_->net(),
DisconnectAndroidVpn);
- if (!net_instance) {
- LOG(ERROR) << "User requested VPN disconnection but API is unavailable";
+ if (!net_instance)
return;
- }
+
net_instance->DisconnectAndroidVpn();
}
@@ -999,27 +829,23 @@ void ArcNetHostImpl::DisconnectRequested(const std::string& service_path) {
// This code path is taken when a user clicks the blue Disconnect button
// in Chrome OS. Chrome is about to send the Disconnect call to shill,
// so update our local state and tell Android to disconnect the VPN.
- VLOG(1) << "DisconnectRequested " << service_path;
DisconnectArcVpn();
}
void ArcNetHostImpl::NetworkConnectionStateChanged(
const chromeos::NetworkState* network) {
- const chromeos::NetworkState* shill_backed_network =
- GetShillBackedNetwork(network);
+ const auto* shill_backed_network = GetShillBackedNetwork(network);
if (!shill_backed_network)
return;
if (arc_vpn_service_path_ != shill_backed_network->path() ||
- shill_backed_network->IsConnectingOrConnected()) {
+ shill_backed_network->IsConnectingOrConnected())
return;
- }
// This code path is taken when shill disconnects the Android VPN
// service. This can happen if a user tries to connect to a Chrome OS
// VPN, and shill's VPNProvider::DisconnectAll() forcibly disconnects
// all other VPN services to avoid a conflict.
- VLOG(1) << "NetworkConnectionStateChanged " << shill_backed_network->path();
DisconnectArcVpn();
}
@@ -1064,43 +890,8 @@ void ArcNetHostImpl::UpdateActiveNetworks() {
if (!net_instance)
return;
- const auto active_networks = GetActiveNetworks();
- auto network_configurations = TranslateNetworkStates(
- arc_vpn_service_path_, active_networks, shill_network_properties_);
-
- // A newly connected network may not immediately have any usable IP config
- // object if IPv4 dhcp or IPv6 autoconf have not completed yet. Schedule
- // with a few seconds delay a forced property update for that service to
- // ensure the IP configuration is sent to ARC. Ensure that at most one such
- // request is scheduled for a given service.
- for (const auto& network : network_configurations) {
- if (!network->ip_configs->empty())
- continue;
-
- if (!network->service_name)
- continue;
-
- const std::string& path = network->service_name.value();
- if (pending_service_property_requests_.insert(path).second) {
- LOG(WARNING) << "No IP configuration for " << path;
- // TODO(hugobenichi): add exponential backoff for the case when IP
- // configuration stays unavailable.
- base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE,
- base::BindOnce(&ArcNetHostImpl::RequestUpdateForNetwork,
- weak_factory_.GetWeakPtr(), path),
- kNetworkPropertyUpdateDelay);
- }
- }
-
- net_instance->ActiveNetworksChanged(std::move(network_configurations));
-}
-
-void ArcNetHostImpl::RequestUpdateForNetwork(const std::string& service_path) {
- // TODO(hugobenichi): skip the request if the IP configuration for this
- // service has been received since then and ARC has been notified about it.
- pending_service_property_requests_.erase(service_path);
- GetStateHandler()->RequestUpdateForNetwork(service_path);
+ net_instance->ActiveNetworksChanged(TranslateNetworkStates(
+ arc_vpn_service_path_, GetActiveNetworks(), shill_network_properties_));
}
void ArcNetHostImpl::NetworkListChanged() {
@@ -1109,7 +900,14 @@ void ArcNetHostImpl::NetworkListChanged() {
return !IsActiveNetworkState(
GetStateHandler()->GetNetworkState(entry.first));
});
- for (const auto* network : GetActiveNetworks())
+ const auto active_networks = GetActiveNetworks();
+ // If there is no active networks, send an explicit ActiveNetworksChanged
+ // event to ARC and skip updating Shill properties.
+ if (active_networks.empty()) {
+ UpdateActiveNetworks();
+ return;
+ }
+ for (const auto* network : active_networks)
NetworkPropertiesUpdated(network);
}
diff --git a/chromium/components/arc/net/arc_net_host_impl.h b/chromium/components/arc/net/arc_net_host_impl.h
index 1dcde71376c..5a072af14b5 100644
--- a/chromium/components/arc/net/arc_net_host_impl.h
+++ b/chromium/components/arc/net/arc_net_host_impl.h
@@ -8,7 +8,6 @@
#include <stdint.h>
#include <map>
#include <memory>
-#include <set>
#include <string>
#include <vector>
@@ -150,8 +149,6 @@ class ArcNetHostImpl : public KeyedService,
const std::string& error_name,
std::unique_ptr<base::DictionaryValue> error_data);
- // Request properties of the Service corresponding to |service_path|.
- void RequestUpdateForNetwork(const std::string& service_path);
// Callback for chromeos::NetworkHandler::GetShillProperties
void ReceiveShillProperties(const std::string& service_path,
const base::DictionaryValue& shill_properties);
@@ -161,9 +158,6 @@ class ArcNetHostImpl : public KeyedService,
// True if the chrome::NetworkStateHandler is currently being observed for
// state changes.
bool observing_network_state_ = false;
- // Contains all service paths for which a property update request is
- // currently scheduled.
- std::set<std::string> pending_service_property_requests_;
// Cached shill properties for all active networks, keyed by Service path.
std::map<std::string, base::Value> shill_network_properties_;