| 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
|
|
|