Index: chromeos/network/network_connection_handler.cc |
diff --git a/chromeos/network/network_connection_handler.cc b/chromeos/network/network_connection_handler.cc |
index 69483bfb0cdf3d07bd25abf79e9cba5648f144e4..bcdbc6e65bf9d29fd4237fd4e0df6daab5ad8f9a 100644 |
--- a/chromeos/network/network_connection_handler.cc |
+++ b/chromeos/network/network_connection_handler.cc |
@@ -10,6 +10,7 @@ |
#include "base/single_thread_task_runner.h" |
#include "base/strings/string_number_conversions.h" |
#include "base/threading/thread_task_runner_handle.h" |
+#include "base/time/time.h" |
#include "chromeos/dbus/dbus_thread_manager.h" |
#include "chromeos/dbus/shill_manager_client.h" |
#include "chromeos/dbus/shill_service_client.h" |
@@ -29,70 +30,7 @@ |
namespace chromeos { |
-namespace { |
- |
-bool IsAuthenticationError(const std::string& error) { |
- return (error == shill::kErrorBadWEPKey || |
- error == shill::kErrorPppAuthFailed || |
- error == shill::kErrorEapLocalTlsFailed || |
- error == shill::kErrorEapRemoteTlsFailed || |
- error == shill::kErrorEapAuthenticationFailed); |
-} |
- |
-bool VPNRequiresCredentials(const std::string& service_path, |
- const std::string& provider_type, |
- const base::DictionaryValue& provider_properties) { |
- if (provider_type == shill::kProviderOpenVpn) { |
- std::string username; |
- provider_properties.GetStringWithoutPathExpansion( |
- shill::kOpenVPNUserProperty, &username); |
- if (username.empty()) { |
- NET_LOG_EVENT("OpenVPN: No username", service_path); |
- return true; |
- } |
- bool passphrase_required = false; |
- provider_properties.GetBooleanWithoutPathExpansion( |
- shill::kPassphraseRequiredProperty, &passphrase_required); |
- if (passphrase_required) { |
- NET_LOG_EVENT("OpenVPN: Passphrase Required", service_path); |
- return true; |
- } |
- NET_LOG_EVENT("OpenVPN Is Configured", service_path); |
- } else { |
- bool passphrase_required = false; |
- provider_properties.GetBooleanWithoutPathExpansion( |
- shill::kL2tpIpsecPskRequiredProperty, &passphrase_required); |
- if (passphrase_required) { |
- NET_LOG_EVENT("VPN: PSK Required", service_path); |
- return true; |
- } |
- provider_properties.GetBooleanWithoutPathExpansion( |
- shill::kPassphraseRequiredProperty, &passphrase_required); |
- if (passphrase_required) { |
- NET_LOG_EVENT("VPN: Passphrase Required", service_path); |
- return true; |
- } |
- NET_LOG_EVENT("VPN Is Configured", service_path); |
- } |
- return false; |
-} |
- |
-std::string GetDefaultUserProfilePath(const NetworkState* network) { |
- if (!NetworkHandler::IsInitialized() || |
- (LoginState::IsInitialized() && |
- !LoginState::Get()->UserHasNetworkProfile()) || |
- (network && network->type() == shill::kTypeWifi && |
- network->security_class() == shill::kSecurityNone)) { |
- return NetworkProfileHandler::GetSharedProfilePath(); |
- } |
- const NetworkProfile* profile = |
- NetworkHandler::Get()->network_profile_handler()->GetDefaultUserProfile(); |
- return profile ? profile->path |
- : NetworkProfileHandler::GetSharedProfilePath(); |
-} |
- |
-} // namespace |
- |
+// Static constants. |
const char NetworkConnectionHandler::kErrorNotFound[] = "not-found"; |
const char NetworkConnectionHandler::kErrorConnected[] = "connected"; |
const char NetworkConnectionHandler::kErrorConnecting[] = "connecting"; |
@@ -124,79 +62,10 @@ const char |
NetworkConnectionHandler::kErrorTetherConnectionAttemptWithNoDelegate[] = |
"tether-with-no-delegate"; |
-struct NetworkConnectionHandler::ConnectRequest { |
- ConnectRequest(const std::string& service_path, |
- const std::string& profile_path, |
- const base::Closure& success, |
- const network_handler::ErrorCallback& error) |
- : service_path(service_path), |
- profile_path(profile_path), |
- connect_state(CONNECT_REQUESTED), |
- success_callback(success), |
- error_callback(error) { |
- } |
- enum ConnectState { |
- CONNECT_REQUESTED = 0, |
- CONNECT_STARTED = 1, |
- CONNECT_CONNECTING = 2 |
- }; |
- std::string service_path; |
- std::string profile_path; |
- ConnectState connect_state; |
- base::Closure success_callback; |
- network_handler::ErrorCallback error_callback; |
-}; |
- |
NetworkConnectionHandler::NetworkConnectionHandler() |
- : cert_loader_(NULL), |
- network_state_handler_(NULL), |
- configuration_handler_(NULL), |
- logged_in_(false), |
- certificates_loaded_(false), |
- tether_delegate_(nullptr) {} |
+ : tether_delegate_(nullptr), weak_ptr_factory_(this) {} |
-NetworkConnectionHandler::~NetworkConnectionHandler() { |
- if (network_state_handler_) |
- network_state_handler_->RemoveObserver(this, FROM_HERE); |
- if (cert_loader_) |
- cert_loader_->RemoveObserver(this); |
- if (LoginState::IsInitialized()) |
- LoginState::Get()->RemoveObserver(this); |
-} |
- |
-void NetworkConnectionHandler::Init( |
- NetworkStateHandler* network_state_handler, |
- NetworkConfigurationHandler* network_configuration_handler, |
- ManagedNetworkConfigurationHandler* managed_network_configuration_handler) { |
- if (LoginState::IsInitialized()) |
- LoginState::Get()->AddObserver(this); |
- |
- if (CertLoader::IsInitialized()) { |
- cert_loader_ = CertLoader::Get(); |
- cert_loader_->AddObserver(this); |
- if (cert_loader_->certificates_loaded()) { |
- NET_LOG_EVENT("Certificates Loaded", ""); |
- certificates_loaded_ = true; |
- } |
- } else { |
- // TODO(tbarzic): Require a mock or stub cert_loader in tests. |
- NET_LOG_EVENT("Certificate Loader not initialized", ""); |
- certificates_loaded_ = true; |
- } |
- |
- if (network_state_handler) { |
- network_state_handler_ = network_state_handler; |
- network_state_handler_->AddObserver(this, FROM_HERE); |
- } |
- configuration_handler_ = network_configuration_handler; |
- managed_configuration_handler_ = managed_network_configuration_handler; |
- |
- // After this point, the NetworkConnectionHandler is fully initialized (all |
- // handler references set, observers registered, ...). |
- |
- if (LoginState::IsInitialized()) |
- LoggedInStateChanged(); |
-} |
+NetworkConnectionHandler::~NetworkConnectionHandler() {} |
void NetworkConnectionHandler::AddObserver( |
NetworkConnectionObserver* observer) { |
@@ -208,593 +77,11 @@ void NetworkConnectionHandler::RemoveObserver( |
observers_.RemoveObserver(observer); |
} |
-void NetworkConnectionHandler::LoggedInStateChanged() { |
- LoginState* login_state = LoginState::Get(); |
- if (logged_in_ || !login_state->IsUserLoggedIn()) |
- return; |
- |
- logged_in_ = true; |
- logged_in_time_ = base::TimeTicks::Now(); |
-} |
- |
-void NetworkConnectionHandler::OnCertificatesLoaded( |
- const net::CertificateList& cert_list, |
- bool initial_load) { |
- certificates_loaded_ = true; |
- NET_LOG_EVENT("Certificates Loaded", ""); |
- if (queued_connect_) |
- ConnectToQueuedNetwork(); |
-} |
- |
-void NetworkConnectionHandler::InitiateTetherNetworkConnection( |
- const std::string& tether_network_guid, |
- const base::Closure& success_callback, |
- const network_handler::ErrorCallback& error_callback) { |
- DCHECK(tether_delegate_); |
- tether_delegate_->ConnectToNetwork( |
- tether_network_guid, |
- base::Bind(&NetworkConnectionHandler::InvokeConnectSuccessCallback, |
- AsWeakPtr(), tether_network_guid, success_callback), |
- base::Bind(&NetworkConnectionHandler::InvokeConnectErrorCallback, |
- AsWeakPtr(), tether_network_guid, error_callback)); |
-} |
- |
-void NetworkConnectionHandler::ConnectToNetwork( |
- const std::string& service_path, |
- const base::Closure& success_callback, |
- const network_handler::ErrorCallback& error_callback, |
- bool check_error_state) { |
- NET_LOG_USER("ConnectToNetwork", service_path); |
- for (auto& observer : observers_) |
- observer.ConnectToNetworkRequested(service_path); |
- |
- // Clear any existing queued connect request. |
- queued_connect_.reset(); |
- if (HasConnectingNetwork(service_path)) { |
- NET_LOG_USER("Connect Request While Pending", service_path); |
- InvokeConnectErrorCallback(service_path, error_callback, kErrorConnecting); |
- return; |
- } |
- |
- // Check cached network state for connected, connecting, or unactivated |
- // networks. These states will not be affected by a recent configuration. |
- // Note: NetworkState may not exist for a network that was recently |
- // configured, in which case these checks do not apply anyway. |
- const NetworkState* network = |
- network_state_handler_->GetNetworkState(service_path); |
- |
- if (network) { |
- // For existing networks, perform some immediate consistency checks. |
- if (network->IsConnectedState()) { |
- InvokeConnectErrorCallback(service_path, error_callback, kErrorConnected); |
- return; |
- } |
- if (network->IsConnectingState()) { |
- InvokeConnectErrorCallback(service_path, error_callback, |
- kErrorConnecting); |
- return; |
- } |
- |
- if (check_error_state) { |
- const std::string& error = network->last_error(); |
- if (error == shill::kErrorBadPassphrase) { |
- InvokeConnectErrorCallback(service_path, error_callback, |
- kErrorBadPassphrase); |
- return; |
- } |
- if (IsAuthenticationError(error)) { |
- InvokeConnectErrorCallback(service_path, error_callback, |
- kErrorAuthenticationRequired); |
- return; |
- } |
- } |
- |
- if (NetworkTypePattern::Tether().MatchesType(network->type())) { |
- if (tether_delegate_) { |
- const std::string& tether_network_guid = network->guid(); |
- DCHECK(!tether_network_guid.empty()); |
- InitiateTetherNetworkConnection(tether_network_guid, success_callback, |
- error_callback); |
- } else { |
- InvokeConnectErrorCallback(service_path, error_callback, |
- kErrorTetherConnectionAttemptWithNoDelegate); |
- } |
- return; |
- } |
- } |
- |
- // If the network does not have a profile path, specify the correct default |
- // profile here and set it once connected. Otherwise leave it empty to |
- // indicate that it does not need to be set. |
- std::string profile_path; |
- if (!network || network->profile_path().empty()) |
- profile_path = GetDefaultUserProfilePath(network); |
- |
- // All synchronous checks passed, add |service_path| to connecting list. |
- pending_requests_.insert(std::make_pair( |
- service_path, |
- ConnectRequest(service_path, profile_path, |
- success_callback, error_callback))); |
- |
- // Connect immediately to 'connectable' networks. |
- // TODO(stevenjb): Shill needs to properly set Connectable for VPN. |
- if (network && network->connectable() && network->type() != shill::kTypeVPN) { |
- if (IsNetworkProhibitedByPolicy(network->type(), network->guid(), |
- network->profile_path())) { |
- ErrorCallbackForPendingRequest(service_path, kErrorUnmanagedNetwork); |
- return; |
- } |
- |
- CallShillConnect(service_path); |
- return; |
- } |
- |
- // Request additional properties to check. VerifyConfiguredAndConnect will |
- // use only these properties, not cached properties, to ensure that they |
- // are up to date after any recent configuration. |
- configuration_handler_->GetShillProperties( |
- service_path, |
- base::Bind(&NetworkConnectionHandler::VerifyConfiguredAndConnect, |
- AsWeakPtr(), check_error_state), |
- base::Bind(&NetworkConnectionHandler::HandleConfigurationFailure, |
- AsWeakPtr(), service_path)); |
-} |
- |
-void NetworkConnectionHandler::DisconnectNetwork( |
- const std::string& service_path, |
- const base::Closure& success_callback, |
- const network_handler::ErrorCallback& error_callback) { |
- NET_LOG_USER("DisconnectNetwork", service_path); |
- for (auto& observer : observers_) |
- observer.DisconnectRequested(service_path); |
- |
- const NetworkState* network = |
- network_state_handler_->GetNetworkState(service_path); |
- if (!network) { |
- NET_LOG_ERROR("Disconnect Error: Not Found", service_path); |
- network_handler::RunErrorCallback(error_callback, service_path, |
- kErrorNotFound, ""); |
- return; |
- } |
- if (!network->IsConnectedState() && !network->IsConnectingState()) { |
- NET_LOG_ERROR("Disconnect Error: Not Connected", service_path); |
- network_handler::RunErrorCallback(error_callback, service_path, |
- kErrorNotConnected, ""); |
- return; |
- } |
- pending_requests_.erase(service_path); |
- CallShillDisconnect(service_path, success_callback, error_callback); |
-} |
- |
-bool NetworkConnectionHandler::HasConnectingNetwork( |
- const std::string& service_path) { |
- return pending_requests_.count(service_path) != 0; |
-} |
- |
-bool NetworkConnectionHandler::HasPendingConnectRequest() { |
- return pending_requests_.size() > 0; |
-} |
- |
void NetworkConnectionHandler::SetTetherDelegate( |
TetherDelegate* tether_delegate) { |
tether_delegate_ = tether_delegate; |
} |
-void NetworkConnectionHandler::NetworkListChanged() { |
- CheckAllPendingRequests(); |
-} |
- |
-void NetworkConnectionHandler::NetworkPropertiesUpdated( |
- const NetworkState* network) { |
- if (HasConnectingNetwork(network->path())) |
- CheckPendingRequest(network->path()); |
-} |
- |
-NetworkConnectionHandler::ConnectRequest* |
-NetworkConnectionHandler::GetPendingRequest(const std::string& service_path) { |
- std::map<std::string, ConnectRequest>::iterator iter = |
- pending_requests_.find(service_path); |
- return iter != pending_requests_.end() ? &(iter->second) : NULL; |
-} |
- |
-// ConnectToNetwork implementation |
- |
-void NetworkConnectionHandler::VerifyConfiguredAndConnect( |
- bool check_error_state, |
- const std::string& service_path, |
- const base::DictionaryValue& service_properties) { |
- NET_LOG_EVENT("VerifyConfiguredAndConnect", service_path); |
- |
- // If 'passphrase_required' is still true, then the 'Passphrase' property |
- // has not been set to a minimum length value. |
- bool passphrase_required = false; |
- service_properties.GetBooleanWithoutPathExpansion( |
- shill::kPassphraseRequiredProperty, &passphrase_required); |
- if (passphrase_required) { |
- ErrorCallbackForPendingRequest(service_path, kErrorPassphraseRequired); |
- return; |
- } |
- |
- std::string type, security_class; |
- service_properties.GetStringWithoutPathExpansion(shill::kTypeProperty, &type); |
- service_properties.GetStringWithoutPathExpansion( |
- shill::kSecurityClassProperty, &security_class); |
- bool connectable = false; |
- service_properties.GetBooleanWithoutPathExpansion( |
- shill::kConnectableProperty, &connectable); |
- |
- // In case NetworkState was not available in ConnectToNetwork (e.g. it had |
- // been recently configured), we need to check Connectable again. |
- if (connectable && type != shill::kTypeVPN) { |
- // TODO(stevenjb): Shill needs to properly set Connectable for VPN. |
- CallShillConnect(service_path); |
- return; |
- } |
- |
- // Get VPN provider type and host (required for configuration) and ensure |
- // that required VPN non-cert properties are set. |
- const base::DictionaryValue* provider_properties = NULL; |
- std::string vpn_provider_type, vpn_provider_host, vpn_client_cert_id; |
- if (type == shill::kTypeVPN) { |
- // VPN Provider values are read from the "Provider" dictionary, not the |
- // "Provider.Type", etc keys (which are used only to set the values). |
- if (service_properties.GetDictionaryWithoutPathExpansion( |
- shill::kProviderProperty, &provider_properties)) { |
- provider_properties->GetStringWithoutPathExpansion( |
- shill::kTypeProperty, &vpn_provider_type); |
- provider_properties->GetStringWithoutPathExpansion( |
- shill::kHostProperty, &vpn_provider_host); |
- provider_properties->GetStringWithoutPathExpansion( |
- shill::kL2tpIpsecClientCertIdProperty, &vpn_client_cert_id); |
- } |
- if (vpn_provider_type.empty() || vpn_provider_host.empty()) { |
- ErrorCallbackForPendingRequest(service_path, kErrorConfigurationRequired); |
- return; |
- } |
- } |
- |
- std::string guid; |
- service_properties.GetStringWithoutPathExpansion(shill::kGuidProperty, &guid); |
- std::string profile; |
- service_properties.GetStringWithoutPathExpansion(shill::kProfileProperty, |
- &profile); |
- ::onc::ONCSource onc_source = onc::ONC_SOURCE_NONE; |
- const base::DictionaryValue* policy = |
- managed_configuration_handler_->FindPolicyByGuidAndProfile(guid, profile, |
- &onc_source); |
- |
- if (IsNetworkProhibitedByPolicy(type, guid, profile)) { |
- ErrorCallbackForPendingRequest(service_path, kErrorUnmanagedNetwork); |
- return; |
- } |
- |
- client_cert::ClientCertConfig cert_config_from_policy; |
- if (policy) { |
- client_cert::OncToClientCertConfig(onc_source, *policy, |
- &cert_config_from_policy); |
- } |
- |
- client_cert::ConfigType client_cert_type = client_cert::CONFIG_TYPE_NONE; |
- if (type == shill::kTypeVPN) { |
- if (vpn_provider_type == shill::kProviderOpenVpn) { |
- client_cert_type = client_cert::CONFIG_TYPE_OPENVPN; |
- } else { |
- // L2TP/IPSec only requires a certificate if one is specified in ONC |
- // or one was configured by the UI. Otherwise it is L2TP/IPSec with |
- // PSK and doesn't require a certificate. |
- // |
- // TODO(benchan): Modify shill to specify the authentication type via |
- // the kL2tpIpsecAuthenticationType property, so that Chrome doesn't need |
- // to deduce the authentication type based on the |
- // kL2tpIpsecClientCertIdProperty here (and also in VPNConfigView). |
- if (!vpn_client_cert_id.empty() || |
- cert_config_from_policy.client_cert_type != |
- onc::client_cert::kClientCertTypeNone) { |
- client_cert_type = client_cert::CONFIG_TYPE_IPSEC; |
- } |
- } |
- } else if (type == shill::kTypeWifi && |
- security_class == shill::kSecurity8021x) { |
- client_cert_type = client_cert::CONFIG_TYPE_EAP; |
- } |
- |
- base::DictionaryValue config_properties; |
- if (client_cert_type != client_cert::CONFIG_TYPE_NONE) { |
- // Note: if we get here then a certificate *may* be required, so we want |
- // to ensure that certificates have loaded successfully before attempting |
- // to connect. |
- |
- // User must be logged in to connect to a network requiring a certificate. |
- if (!logged_in_ || !cert_loader_) { |
- NET_LOG_ERROR("User not logged in", ""); |
- ErrorCallbackForPendingRequest(service_path, kErrorCertificateRequired); |
- return; |
- } |
- // If certificates have not been loaded yet, queue the connect request. |
- if (!certificates_loaded_) { |
- NET_LOG_EVENT("Certificates not loaded", ""); |
- QueueConnectRequest(service_path); |
- return; |
- } |
- |
- // Check certificate properties from policy. |
- if (cert_config_from_policy.client_cert_type == |
- onc::client_cert::kPattern) { |
- if (!ClientCertResolver::ResolveCertificatePatternSync( |
- client_cert_type, cert_config_from_policy, &config_properties)) { |
- ErrorCallbackForPendingRequest(service_path, kErrorCertificateRequired); |
- return; |
- } |
- } else if (check_error_state && |
- !client_cert::IsCertificateConfigured(client_cert_type, |
- service_properties)) { |
- // Network may not be configured. |
- ErrorCallbackForPendingRequest(service_path, kErrorConfigurationRequired); |
- return; |
- } |
- } |
- |
- if (type == shill::kTypeVPN) { |
- // VPN may require a username, and/or passphrase to be set. (Check after |
- // ensuring that any required certificates are configured). |
- DCHECK(provider_properties); |
- if (VPNRequiresCredentials( |
- service_path, vpn_provider_type, *provider_properties)) { |
- NET_LOG_USER("VPN Requires Credentials", service_path); |
- ErrorCallbackForPendingRequest(service_path, kErrorConfigurationRequired); |
- return; |
- } |
- |
- // If it's L2TP/IPsec PSK, there is no properties to configure, so proceed |
- // to connect. |
- if (client_cert_type == client_cert::CONFIG_TYPE_NONE) { |
- CallShillConnect(service_path); |
- return; |
- } |
- } |
- |
- if (!config_properties.empty()) { |
- NET_LOG_EVENT("Configuring Network", service_path); |
- configuration_handler_->SetShillProperties( |
- service_path, config_properties, |
- NetworkConfigurationObserver::SOURCE_USER_ACTION, |
- base::Bind(&NetworkConnectionHandler::CallShillConnect, AsWeakPtr(), |
- service_path), |
- base::Bind(&NetworkConnectionHandler::HandleConfigurationFailure, |
- AsWeakPtr(), service_path)); |
- return; |
- } |
- |
- // Otherwise, we probably still need to configure the network since |
- // 'Connectable' is false. If |check_error_state| is true, signal an |
- // error, otherwise attempt to connect to possibly gain additional error |
- // state from Shill (or in case 'Connectable' is improperly unset). |
- if (check_error_state) |
- ErrorCallbackForPendingRequest(service_path, kErrorConfigurationRequired); |
- else |
- CallShillConnect(service_path); |
-} |
- |
-bool NetworkConnectionHandler::IsNetworkProhibitedByPolicy( |
- const std::string& type, |
- const std::string& guid, |
- const std::string& profile_path) { |
- if (!logged_in_) |
- return false; |
- if (type != shill::kTypeWifi) |
- return false; |
- const base::DictionaryValue* global_network_config = |
- managed_configuration_handler_->GetGlobalConfigFromPolicy( |
- std::string() /* no username hash, device policy */); |
- if (!global_network_config) |
- return false; |
- bool policy_prohibites = false; |
- if (!global_network_config->GetBooleanWithoutPathExpansion( |
- ::onc::global_network_config::kAllowOnlyPolicyNetworksToConnect, |
- &policy_prohibites) || |
- !policy_prohibites) { |
- return false; |
- } |
- return !managed_configuration_handler_->FindPolicyByGuidAndProfile( |
- guid, profile_path, nullptr /* onc_source */); |
-} |
- |
-void NetworkConnectionHandler::QueueConnectRequest( |
- const std::string& service_path) { |
- ConnectRequest* request = GetPendingRequest(service_path); |
- if (!request) { |
- NET_LOG_ERROR("No pending request to queue", service_path); |
- return; |
- } |
- |
- const int kMaxCertLoadTimeSeconds = 15; |
- base::TimeDelta dtime = base::TimeTicks::Now() - logged_in_time_; |
- if (dtime > base::TimeDelta::FromSeconds(kMaxCertLoadTimeSeconds)) { |
- NET_LOG_ERROR("Certificate load timeout", service_path); |
- InvokeConnectErrorCallback(service_path, request->error_callback, |
- kErrorCertLoadTimeout); |
- return; |
- } |
- |
- NET_LOG_EVENT("Connect Request Queued", service_path); |
- queued_connect_.reset(new ConnectRequest( |
- service_path, request->profile_path, |
- request->success_callback, request->error_callback)); |
- pending_requests_.erase(service_path); |
- |
- // Post a delayed task to check to see if certificates have loaded. If they |
- // haven't, and queued_connect_ has not been cleared (e.g. by a successful |
- // connect request), cancel the request and notify the user. |
- base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
- FROM_HERE, base::Bind(&NetworkConnectionHandler::CheckCertificatesLoaded, |
- AsWeakPtr()), |
- base::TimeDelta::FromSeconds(kMaxCertLoadTimeSeconds) - dtime); |
-} |
- |
-void NetworkConnectionHandler::CheckCertificatesLoaded() { |
- if (certificates_loaded_) |
- return; |
- // If queued_connect_ has been cleared (e.g. another connect request occurred |
- // and wasn't queued), do nothing here. |
- if (!queued_connect_) |
- return; |
- // Otherwise, notify the user. |
- NET_LOG_ERROR("Certificate load timeout", queued_connect_->service_path); |
- InvokeConnectErrorCallback(queued_connect_->service_path, |
- queued_connect_->error_callback, |
- kErrorCertLoadTimeout); |
- queued_connect_.reset(); |
-} |
- |
-void NetworkConnectionHandler::ConnectToQueuedNetwork() { |
- DCHECK(queued_connect_); |
- |
- // Make a copy of |queued_connect_| parameters, because |queued_connect_| |
- // will get reset at the beginning of |ConnectToNetwork|. |
- std::string service_path = queued_connect_->service_path; |
- base::Closure success_callback = queued_connect_->success_callback; |
- network_handler::ErrorCallback error_callback = |
- queued_connect_->error_callback; |
- |
- NET_LOG_EVENT("Connecting to Queued Network", service_path); |
- ConnectToNetwork(service_path, success_callback, error_callback, |
- false /* check_error_state */); |
-} |
- |
-void NetworkConnectionHandler::CallShillConnect( |
- const std::string& service_path) { |
- NET_LOG_EVENT("Sending Connect Request to Shill", service_path); |
- network_state_handler_->ClearLastErrorForNetwork(service_path); |
- DBusThreadManager::Get()->GetShillServiceClient()->Connect( |
- dbus::ObjectPath(service_path), |
- base::Bind(&NetworkConnectionHandler::HandleShillConnectSuccess, |
- AsWeakPtr(), service_path), |
- base::Bind(&NetworkConnectionHandler::HandleShillConnectFailure, |
- AsWeakPtr(), service_path)); |
-} |
- |
-void NetworkConnectionHandler::HandleConfigurationFailure( |
- const std::string& service_path, |
- const std::string& error_name, |
- std::unique_ptr<base::DictionaryValue> error_data) { |
- ConnectRequest* request = GetPendingRequest(service_path); |
- if (!request) { |
- NET_LOG_ERROR("HandleConfigurationFailure called with no pending request.", |
- service_path); |
- return; |
- } |
- network_handler::ErrorCallback error_callback = request->error_callback; |
- pending_requests_.erase(service_path); |
- InvokeConnectErrorCallback(service_path, error_callback, |
- kErrorConfigureFailed); |
-} |
- |
-void NetworkConnectionHandler::HandleShillConnectSuccess( |
- const std::string& service_path) { |
- ConnectRequest* request = GetPendingRequest(service_path); |
- if (!request) { |
- NET_LOG_ERROR("HandleShillConnectSuccess called with no pending request.", |
- service_path); |
- return; |
- } |
- request->connect_state = ConnectRequest::CONNECT_STARTED; |
- NET_LOG_EVENT("Connect Request Acknowledged", service_path); |
- // Do not call success_callback here, wait for one of the following |
- // conditions: |
- // * State transitions to a non connecting state indicating success or failure |
- // * Network is no longer in the visible list, indicating failure |
- CheckPendingRequest(service_path); |
-} |
- |
-void NetworkConnectionHandler::HandleShillConnectFailure( |
- const std::string& service_path, |
- const std::string& dbus_error_name, |
- const std::string& dbus_error_message) { |
- ConnectRequest* request = GetPendingRequest(service_path); |
- if (!request) { |
- NET_LOG_ERROR("HandleShillConnectFailure called with no pending request.", |
- service_path); |
- return; |
- } |
- network_handler::ErrorCallback error_callback = request->error_callback; |
- pending_requests_.erase(service_path); |
- std::string error; |
- if (dbus_error_name == shill::kErrorResultAlreadyConnected) { |
- error = kErrorConnected; |
- } else if (dbus_error_name == shill::kErrorResultInProgress) { |
- error = kErrorConnecting; |
- } else { |
- NET_LOG_ERROR("Connect Failure, Shill error: " + dbus_error_name, |
- service_path); |
- error = kErrorConnectFailed; |
- } |
- InvokeConnectErrorCallback(service_path, error_callback, error); |
-} |
- |
-void NetworkConnectionHandler::CheckPendingRequest( |
- const std::string service_path) { |
- ConnectRequest* request = GetPendingRequest(service_path); |
- DCHECK(request); |
- if (request->connect_state == ConnectRequest::CONNECT_REQUESTED) |
- return; // Request has not started, ignore update |
- const NetworkState* network = |
- network_state_handler_->GetNetworkState(service_path); |
- if (!network) |
- return; // NetworkState may not be be updated yet. |
- |
- if (network->IsConnectingState()) { |
- request->connect_state = ConnectRequest::CONNECT_CONNECTING; |
- return; |
- } |
- if (network->IsConnectedState()) { |
- if (!request->profile_path.empty()) { |
- // If a profile path was specified, set it on a successful connection. |
- configuration_handler_->SetNetworkProfile( |
- service_path, |
- request->profile_path, |
- NetworkConfigurationObserver::SOURCE_USER_ACTION, |
- base::Bind(&base::DoNothing), |
- chromeos::network_handler::ErrorCallback()); |
- } |
- InvokeConnectSuccessCallback(request->service_path, |
- request->success_callback); |
- pending_requests_.erase(service_path); |
- return; |
- } |
- if (network->connection_state() == shill::kStateIdle && |
- request->connect_state != ConnectRequest::CONNECT_CONNECTING) { |
- // Connection hasn't started yet, keep waiting. |
- return; |
- } |
- |
- // Network is neither connecting or connected; an error occurred. |
- std::string error_name; // 'Canceled' or 'Failed' |
- if (network->connection_state() == shill::kStateIdle && |
- pending_requests_.size() > 1) { |
- // Another connect request canceled this one. |
- error_name = kErrorConnectCanceled; |
- } else { |
- error_name = kErrorConnectFailed; |
- if (network->connection_state() != shill::kStateFailure) { |
- NET_LOG_ERROR("Unexpected State: " + network->connection_state(), |
- service_path); |
- } |
- } |
- |
- network_handler::ErrorCallback error_callback = request->error_callback; |
- pending_requests_.erase(service_path); |
- InvokeConnectErrorCallback(service_path, error_callback, error_name); |
-} |
- |
-void NetworkConnectionHandler::CheckAllPendingRequests() { |
- for (std::map<std::string, ConnectRequest>::iterator iter = |
- pending_requests_.begin(); iter != pending_requests_.end(); ++iter) { |
- CheckPendingRequest(iter->first); |
- } |
-} |
- |
-// Connect callbacks |
- |
void NetworkConnectionHandler::InvokeConnectSuccessCallback( |
const std::string& service_path, |
const base::Closure& success_callback) { |
@@ -805,21 +92,6 @@ void NetworkConnectionHandler::InvokeConnectSuccessCallback( |
observer.ConnectSucceeded(service_path); |
} |
-void NetworkConnectionHandler::ErrorCallbackForPendingRequest( |
- const std::string& service_path, |
- const std::string& error_name) { |
- ConnectRequest* request = GetPendingRequest(service_path); |
- if (!request) { |
- NET_LOG_ERROR("ErrorCallbackForPendingRequest with no pending request.", |
- service_path); |
- return; |
- } |
- // Remove the entry before invoking the callback in case it triggers a retry. |
- network_handler::ErrorCallback error_callback = request->error_callback; |
- pending_requests_.erase(service_path); |
- InvokeConnectErrorCallback(service_path, error_callback, error_name); |
-} |
- |
void NetworkConnectionHandler::InvokeConnectErrorCallback( |
const std::string& service_path, |
const network_handler::ErrorCallback& error_callback, |
@@ -831,27 +103,18 @@ void NetworkConnectionHandler::InvokeConnectErrorCallback( |
observer.ConnectFailed(service_path, error_name); |
} |
-// Disconnect |
- |
-void NetworkConnectionHandler::CallShillDisconnect( |
- const std::string& service_path, |
+void NetworkConnectionHandler::InitiateTetherNetworkConnection( |
+ const std::string& tether_network_guid, |
const base::Closure& success_callback, |
const network_handler::ErrorCallback& error_callback) { |
- NET_LOG_USER("Disconnect Request", service_path); |
- DBusThreadManager::Get()->GetShillServiceClient()->Disconnect( |
- dbus::ObjectPath(service_path), |
- base::Bind(&NetworkConnectionHandler::HandleShillDisconnectSuccess, |
- AsWeakPtr(), service_path, success_callback), |
- base::Bind(&network_handler::ShillErrorCallbackFunction, |
- kErrorDisconnectFailed, service_path, error_callback)); |
-} |
- |
-void NetworkConnectionHandler::HandleShillDisconnectSuccess( |
- const std::string& service_path, |
- const base::Closure& success_callback) { |
- NET_LOG_EVENT("Disconnect Request Sent", service_path); |
- if (!success_callback.is_null()) |
- success_callback.Run(); |
+ DCHECK(tether_delegate_); |
+ tether_delegate_->ConnectToNetwork( |
+ tether_network_guid, |
+ base::Bind(&NetworkConnectionHandler::InvokeConnectSuccessCallback, |
+ weak_ptr_factory_.GetWeakPtr(), tether_network_guid, |
+ success_callback), |
+ base::Bind(&NetworkConnectionHandler::InvokeConnectErrorCallback, |
+ weak_ptr_factory_.GetWeakPtr(), tether_network_guid, |
+ error_callback)); |
} |
- |
} // namespace chromeos |