diff options
author | stevenjb@chromium.org <stevenjb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-14 04:37:56 +0000 |
---|---|---|
committer | stevenjb@chromium.org <stevenjb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-14 04:37:56 +0000 |
commit | 534190554ff15076010b53f879e8c17dc0ccb8b8 (patch) | |
tree | 68ff6b92205ddc09ef62a18c947eaeedf994f00d | |
parent | 9c48757cc3a705f6bb635747333dd3baccc48019 (diff) | |
download | chromium_src-534190554ff15076010b53f879e8c17dc0ccb8b8.zip chromium_src-534190554ff15076010b53f879e8c17dc0ccb8b8.tar.gz chromium_src-534190554ff15076010b53f879e8c17dc0ccb8b8.tar.bz2 |
Add NetworkConnectionHandler class
This moves NetworkConfigurationHandler::Connect ->
NetworkConnectionHandler::ConnectToNetwork and adds error handling
and certificate checking.
Depends on https://codereview.chromium.org/14522013/
Test with --use-new-network-configuration-handlers
BUG=235243
Review URL: https://chromiumcodereview.appspot.com/14566009
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@199893 0039d316-1c4b-4281-b951-d872f2087c98
33 files changed, 957 insertions, 294 deletions
diff --git a/ash/system/chromeos/network/network_state_list_detailed_view.cc b/ash/system/chromeos/network/network_state_list_detailed_view.cc index 296e3566..9ba3849 100644 --- a/ash/system/chromeos/network/network_state_list_detailed_view.cc +++ b/ash/system/chromeos/network/network_state_list_detailed_view.cc @@ -24,7 +24,7 @@ #include "base/utf_string_conversions.h" #include "chromeos/chromeos_switches.h" #include "chromeos/network/device_state.h" -#include "chromeos/network/network_configuration_handler.h" +#include "chromeos/network/network_connection_handler.h" #include "chromeos/network/network_state.h" #include "chromeos/network/network_state_handler.h" #include "grit/ash_resources.h" @@ -42,6 +42,7 @@ using chromeos::DeviceState; using chromeos::NetworkState; using chromeos::NetworkStateHandler; +using chromeos::NetworkConnectionHandler; namespace ash { namespace internal { @@ -759,26 +760,36 @@ views::View* NetworkStateListDetailedView::CreateNetworkInfoView() { void NetworkStateListDetailedView::ConnectToNetwork( const std::string& service_path) { - NetworkStateHandler* handler = NetworkStateHandler::Get(); - const NetworkState* network = handler->GetNetworkState(service_path); + const NetworkState* network = + NetworkStateHandler::Get()->GetNetworkState(service_path); if (!network) return; if (CommandLine::ForCurrentProcess()->HasSwitch( - chromeos::switches::kUseNewNetworkConfigurationHandlers) && - !network->IsConnectedState()) { - handler->SetConnectingNetwork(service_path); - chromeos::NetworkConfigurationHandler::Get()->Connect( + chromeos::switches::kUseNewNetworkConfigurationHandlers)) { + NetworkConnectionHandler::Get()->ConnectToNetwork( service_path, base::Bind(&base::DoNothing), - chromeos::network_handler::ErrorCallback()); + base::Bind(&NetworkStateListDetailedView::OnConnectFailed, + AsWeakPtr(), service_path)); } else { - // This will show the settings UI for a connected network. - // TODO(stevenjb): Change the API to explicitly show network settings. Shell::GetInstance()->system_tray_delegate()->ConnectToNetwork( service_path); } } +void NetworkStateListDetailedView::OnConnectFailed( + const std::string& service_path, + const std::string& error_name, + scoped_ptr<base::DictionaryValue> error_data) { + VLOG(1) << "ConnectFailed: " << error_name; + // This will show the settings UI for a connected/ing network or a connect + // dialog for unconfigured networks. + // TODO(stevenjb): Change the API to explicitly show network settings or + // connect dialog (i.e. explicitly handle different error types). + Shell::GetInstance()->system_tray_delegate()->ConnectToNetwork( + service_path); +} + void NetworkStateListDetailedView::CallRequestScan() { VLOG(1) << "Requesting Network Scan."; NetworkStateHandler::Get()->RequestScan(); diff --git a/ash/system/chromeos/network/network_state_list_detailed_view.h b/ash/system/chromeos/network/network_state_list_detailed_view.h index b176dde..9f689d6 100644 --- a/ash/system/chromeos/network/network_state_list_detailed_view.h +++ b/ash/system/chromeos/network/network_state_list_detailed_view.h @@ -110,6 +110,11 @@ class NetworkStateListDetailedView // Handle click (connect) action. void ConnectToNetwork(const std::string& service_path); + // Handle connect failures (new handlers only). + void OnConnectFailed(const std::string& service_path, + const std::string& error_name, + scoped_ptr<base::DictionaryValue> error_data); + // Periodically request a network scan. void CallRequestScan(); diff --git a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc index 3c1f05b..fca2918 100644 --- a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc +++ b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc @@ -112,6 +112,7 @@ #include "chromeos/network/network_change_notifier_chromeos.h" #include "chromeos/network/network_change_notifier_factory_chromeos.h" #include "chromeos/network/network_configuration_handler.h" +#include "chromeos/network/network_connection_handler.h" #include "chromeos/network/network_event_log.h" #include "chromeos/network/network_profile_handler.h" #include "chromeos/network/network_state_handler.h" @@ -335,6 +336,7 @@ class DBusServices { NetworkProfileHandler::Initialize(); NetworkConfigurationHandler::Initialize(); ManagedNetworkConfigurationHandler::Initialize(profile_handler); + NetworkConnectionHandler::Initialize(); // Initialize the network change notifier for Chrome OS. The network // change notifier starts to monitor changes from the power manager and @@ -378,6 +380,7 @@ class DBusServices { ManagedNetworkConfigurationHandler::Shutdown(); NetworkConfigurationHandler::Shutdown(); + NetworkConnectionHandler::Shutdown(); NetworkProfileHandler::Shutdown(); NetworkStateHandler::Shutdown(); diff --git a/chrome/browser/chromeos/cros/network_library.cc b/chrome/browser/chromeos/cros/network_library.cc index 2eac4b2..c453eb7 100644 --- a/chrome/browser/chromeos/cros/network_library.cc +++ b/chrome/browser/chromeos/cros/network_library.cc @@ -10,7 +10,6 @@ #include "base/json/json_writer.h" // for debug output only. #include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversion_utils.h" -#include "chrome/browser/chromeos/cros/certificate_pattern_matcher.h" #include "chrome/browser/chromeos/cros/cros_library.h" #include "chrome/browser/chromeos/cros/native_network_constants.h" #include "chrome/browser/chromeos/cros/native_network_parser.h" @@ -18,6 +17,7 @@ #include "chrome/browser/chromeos/cros/network_library_impl_stub.h" #include "chrome/common/net/x509_certificate_model.h" #include "chromeos/network/certificate_pattern.h" +#include "chromeos/network/certificate_pattern_matcher.h" #include "chromeos/network/cros_network_functions.h" #include "chromeos/network/network_state_handler.h" #include "content/public/browser/browser_thread.h" @@ -779,7 +779,7 @@ void VirtualNetwork::MatchCertificatePattern(bool allow_enroll, } scoped_refptr<net::X509Certificate> matching_cert = - GetCertificateMatch(client_cert_pattern()); + certificate_pattern::GetCertificateMatch(client_cert_pattern()); if (matching_cert.get()) { std::string client_cert_id = x509_certificate_model::GetPkcs11Id(matching_cert->os_cert_handle()); @@ -1301,7 +1301,7 @@ void WifiNetwork::MatchCertificatePattern(bool allow_enroll, } scoped_refptr<net::X509Certificate> matching_cert = - GetCertificateMatch(client_cert_pattern()); + certificate_pattern::GetCertificateMatch(client_cert_pattern()); if (matching_cert.get()) { SetEAPClientCertPkcs11Id( x509_certificate_model::GetPkcs11Id(matching_cert->os_cert_handle())); diff --git a/chrome/browser/chromeos/cros/network_library_impl_base.cc b/chrome/browser/chromeos/cros/network_library_impl_base.cc index a0a42a8..978ea1e 100644 --- a/chrome/browser/chromeos/cros/network_library_impl_base.cc +++ b/chrome/browser/chromeos/cros/network_library_impl_base.cc @@ -1160,7 +1160,7 @@ void NetworkLibraryImplBase::LoadOncNetworks( // Set the UIData. scoped_ptr<NetworkUIData> ui_data = - chromeos::CreateUIDataFromONC(source, *normalized_network); + NetworkUIData::CreateFromONC(source, *normalized_network); base::DictionaryValue ui_data_dict; ui_data->FillDictionary(&ui_data_dict); std::string ui_data_json; diff --git a/chrome/browser/chromeos/extensions/networking_private_api.cc b/chrome/browser/chromeos/extensions/networking_private_api.cc index aa946cf..9f3d519 100644 --- a/chrome/browser/chromeos/extensions/networking_private_api.cc +++ b/chrome/browser/chromeos/extensions/networking_private_api.cc @@ -17,6 +17,7 @@ #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/shill_manager_client.h" #include "chromeos/network/managed_network_configuration_handler.h" +#include "chromeos/network/network_connection_handler.h" #include "chromeos/network/network_state.h" #include "chromeos/network/network_state_handler.h" #include "chromeos/network/onc/onc_constants.h" @@ -290,7 +291,7 @@ bool NetworkingPrivateStartConnectFunction::RunImpl() { api::StartConnect::Params::Create(*args_); EXTENSION_FUNCTION_VALIDATE(params); - ManagedNetworkConfigurationHandler::Get()->Connect( + chromeos::NetworkConnectionHandler::Get()->ConnectToNetwork( params->network_guid, // service path base::Bind( &NetworkingPrivateStartConnectFunction::ConnectionStartSuccess, @@ -324,7 +325,7 @@ bool NetworkingPrivateStartDisconnectFunction::RunImpl() { api::StartDisconnect::Params::Create(*args_); EXTENSION_FUNCTION_VALIDATE(params); - ManagedNetworkConfigurationHandler::Get()->Disconnect( + chromeos::NetworkConnectionHandler::Get()->DisconnectNetwork( params->network_guid, // service path base::Bind( &NetworkingPrivateStartDisconnectFunction::DisconnectionStartSuccess, diff --git a/chrome/chrome_browser_chromeos.gypi b/chrome/chrome_browser_chromeos.gypi index cc1c78c..ba939ad 100644 --- a/chrome/chrome_browser_chromeos.gypi +++ b/chrome/chrome_browser_chromeos.gypi @@ -171,8 +171,6 @@ 'browser/chromeos/contacts/google_contact_store.h', 'browser/chromeos/cros/cert_library.cc', 'browser/chromeos/cros/cert_library.h', - 'browser/chromeos/cros/certificate_pattern_matcher.cc', - 'browser/chromeos/cros/certificate_pattern_matcher.h', 'browser/chromeos/cros/cros_library.cc', 'browser/chromeos/cros/cros_library.h', 'browser/chromeos/cros/enum_mapper.h', diff --git a/chrome/test/data/extensions/api_test/networking/test.js b/chrome/test/data/extensions/api_test/networking/test.js index 609ae86..36940fc 100644 --- a/chrome/test/data/extensions/api_test/networking/test.js +++ b/chrome/test/data/extensions/api_test/networking/test.js @@ -60,17 +60,21 @@ var availableTests = [ chrome.networkingPrivate.startConnect("stub_wifi2", callbackPass()); }, function startDisconnect() { - chrome.networkingPrivate.startDisconnect("stub_wifi2", callbackPass()); + // Must connect to a network before we can disconnect from it. + chrome.networkingPrivate.startConnect("stub_wifi2", callbackPass( + function() { + chrome.networkingPrivate.startDisconnect("stub_wifi2", callbackPass()); + })); }, function startConnectNonexistent() { chrome.networkingPrivate.startConnect( "nonexistent_path", - callbackFail("Error.InvalidService")); + callbackFail("not-found")); }, function startDisconnectNonexistent() { chrome.networkingPrivate.startDisconnect( "nonexistent_path", - callbackFail("Error.InvalidService")); + callbackFail("not-found")); }, function startGetPropertiesNonexistent() { chrome.networkingPrivate.getProperties( @@ -276,7 +280,7 @@ var availableTests = [ function onNetworksChangedEventConnect() { var network = "stub_wifi2"; var done = chrome.test.callbackAdded(); - var expectedStates = ["Connected", "Connecting"]; + var expectedStates = ["Connected"]; var listener = new privateHelpers.watchForStateChanges(network, expectedStates, done); chrome.networkingPrivate.startConnect(network, callbackPass()); diff --git a/chromeos/chromeos.gyp b/chromeos/chromeos.gyp index 2bd0161..f9477f5 100644 --- a/chromeos/chromeos.gyp +++ b/chromeos/chromeos.gyp @@ -238,6 +238,8 @@ 'network/certificate_handler.h', 'network/certificate_pattern.cc', 'network/certificate_pattern.h', + 'network/certificate_pattern_matcher.cc', + 'network/certificate_pattern_matcher.h', 'network/cros_network_functions.cc', 'network/cros_network_functions.h', 'network/device_state.cc', @@ -254,6 +256,8 @@ 'network/network_change_notifier_factory_chromeos.h', 'network/network_configuration_handler.cc', 'network/network_configuration_handler.h', + 'network/network_connection_handler.cc', + 'network/network_connection_handler.h', 'network/network_event_log.cc', 'network/network_event_log.h', 'network/network_handler_callbacks.cc', @@ -525,6 +529,7 @@ 'network/managed_network_configuration_handler_unittest.cc', 'network/network_change_notifier_chromeos_unittest.cc', 'network/network_configuration_handler_unittest.cc', + 'network/network_connection_handler_unittest.cc', 'network/network_event_log_unittest.cc', 'network/network_profile_handler_stub.h', 'network/network_sms_handler_unittest.cc', diff --git a/chromeos/dbus/shill_manager_client.h b/chromeos/dbus/shill_manager_client.h index 231da2c..e9fca9c 100644 --- a/chromeos/dbus/shill_manager_client.h +++ b/chromeos/dbus/shill_manager_client.h @@ -42,13 +42,6 @@ class CHROMEOS_EXPORT ShillManagerClient { virtual void AddDevice(const std::string& device_path) = 0; virtual void RemoveDevice(const std::string& device_path) = 0; virtual void ClearDevices() = 0; - virtual void AddService(const std::string& service_path, - bool add_to_watch_list) = 0; - virtual void AddServiceAtIndex(const std::string& service_path, - size_t index, - bool add_to_watch_list) = 0; - virtual void RemoveService(const std::string& service_path) = 0; - virtual void ClearServices() = 0; virtual void AddTechnology(const std::string& type, bool enabled) = 0; virtual void RemoveTechnology(const std::string& type) = 0; virtual void SetTechnologyInitializing(const std::string& type, @@ -65,6 +58,18 @@ class CHROMEOS_EXPORT ShillManagerClient { // Used to reset all properties; does not notify observers. virtual void ClearProperties() = 0; + // Move an existing service to a different index, e.g. to simulate the + // result of a successful connect. + virtual void MoveServiceToIndex(const std::string& service_path, + size_t index, + bool add_to_watch_list) = 0; + + // Add/Remove/ClearService should only be called from ShillServiceClient. + virtual void AddManagerService(const std::string& service_path, + bool add_to_watch_list) = 0; + virtual void RemoveManagerService(const std::string& service_path) = 0; + virtual void ClearManagerServices() = 0; + protected: virtual ~TestInterface() {} }; diff --git a/chromeos/dbus/shill_manager_client_stub.cc b/chromeos/dbus/shill_manager_client_stub.cc index cd406c3..6e20a6a 100644 --- a/chromeos/dbus/shill_manager_client_stub.cc +++ b/chromeos/dbus/shill_manager_client_stub.cc @@ -39,7 +39,7 @@ struct ValueEquals { } // namespace ShillManagerClientStub::ShillManagerClientStub() -: weak_ptr_factory_(this) { + : weak_ptr_factory_(this) { SetDefaultProperties(); } @@ -180,9 +180,6 @@ void ShillManagerClientStub::ConfigureService( const base::DictionaryValue& properties, const ObjectPathCallback& callback, const ErrorCallback& error_callback) { - if (callback.is_null()) - return; - ShillServiceClient::TestInterface* service_client = DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface(); @@ -190,10 +187,13 @@ void ShillManagerClientStub::ConfigureService( std::string type; if (!properties.GetString(flimflam::kGuidProperty, &guid) || !properties.GetString(flimflam::kTypeProperty, &type)) { + LOG(ERROR) << "ConfigureService requies GUID and Type to be defined"; // If the properties aren't filled out completely, then just return an empty // object path. - MessageLoop::current()->PostTask( - FROM_HERE, base::Bind(callback, dbus::ObjectPath())); + if (!callback.is_null()) { + MessageLoop::current()->PostTask( + FROM_HERE, base::Bind(callback, dbus::ObjectPath())); + } return; } @@ -231,8 +231,10 @@ void ShillManagerClientStub::ConfigureService( DBusThreadManager::Get()->GetShillProfileClient()->GetTestInterface(); profile_test->AddService(service_path); - MessageLoop::current()->PostTask( - FROM_HERE, base::Bind(callback, dbus::ObjectPath(service_path))); + if (!callback.is_null()) { + MessageLoop::current()->PostTask( + FROM_HERE, base::Bind(callback, dbus::ObjectPath(service_path))); + } } void ShillManagerClientStub::ConfigureServiceForProfile( @@ -320,53 +322,6 @@ void ShillManagerClientStub::ClearDevices() { CallNotifyObserversPropertyChanged(flimflam::kDevicesProperty, 0); } -void ShillManagerClientStub::ClearServices() { - GetListProperty(flimflam::kServicesProperty)->Clear(); - GetListProperty(flimflam::kServiceWatchListProperty)->Clear(); - CallNotifyObserversPropertyChanged(flimflam::kServicesProperty, 0); - CallNotifyObserversPropertyChanged(flimflam::kServiceWatchListProperty, 0); -} - -void ShillManagerClientStub::AddService(const std::string& service_path, - bool add_to_watch_list) { - if (GetListProperty(flimflam::kServicesProperty)->AppendIfNotPresent( - base::Value::CreateStringValue(service_path))) { - CallNotifyObserversPropertyChanged(flimflam::kServicesProperty, 0); - } - if (add_to_watch_list) - AddServiceToWatchList(service_path); -} - -void ShillManagerClientStub::AddServiceAtIndex(const std::string& service_path, - size_t index, - bool add_to_watch_list) { - base::StringValue path_value(service_path); - base::ListValue* service_list = - GetListProperty(flimflam::kServicesProperty); - base::ListValue::iterator iter = - std::find_if(service_list->begin(), service_list->end(), - ValueEquals(&path_value)); - if (iter != service_list->end()) - service_list->Erase(iter, NULL); - service_list->Insert(index, path_value.DeepCopy()); - CallNotifyObserversPropertyChanged(flimflam::kServicesProperty, 0); - if (add_to_watch_list) - AddServiceToWatchList(service_path); -} - -void ShillManagerClientStub::RemoveService(const std::string& service_path) { - base::StringValue service_path_value(service_path); - if (GetListProperty(flimflam::kServicesProperty)->Remove( - service_path_value, NULL)) { - CallNotifyObserversPropertyChanged(flimflam::kServicesProperty, 0); - } - if (GetListProperty(flimflam::kServiceWatchListProperty)->Remove( - service_path_value, NULL)) { - CallNotifyObserversPropertyChanged( - flimflam::kServiceWatchListProperty, 0); - } -} - void ShillManagerClientStub::AddTechnology(const std::string& type, bool enabled) { if (GetListProperty(flimflam::kAvailableTechnologiesProperty)-> @@ -417,6 +372,57 @@ void ShillManagerClientStub::ClearProperties() { stub_properties_.Clear(); } +void ShillManagerClientStub::MoveServiceToIndex( + const std::string& service_path, + size_t index, + bool add_to_watch_list) { + base::StringValue path_value(service_path); + base::ListValue* service_list = GetListProperty(flimflam::kServicesProperty); + base::ListValue::iterator iter = + std::find_if(service_list->begin(), service_list->end(), + ValueEquals(&path_value)); + if (iter == service_list->end()) { + LOG(ERROR) << "Service not found to move: " << service_path; + return; + } + service_list->Erase(iter, NULL); + service_list->Insert(index, path_value.DeepCopy()); + CallNotifyObserversPropertyChanged(flimflam::kServicesProperty, 0); + if (add_to_watch_list) + AddServiceToWatchList(service_path); +} + +void ShillManagerClientStub::AddManagerService(const std::string& service_path, + bool add_to_watch_list) { + if (GetListProperty(flimflam::kServicesProperty)->AppendIfNotPresent( + base::Value::CreateStringValue(service_path))) { + CallNotifyObserversPropertyChanged(flimflam::kServicesProperty, 0); + } + if (add_to_watch_list) + AddServiceToWatchList(service_path); +} + +void ShillManagerClientStub::RemoveManagerService( + const std::string& service_path) { + base::StringValue service_path_value(service_path); + if (GetListProperty(flimflam::kServicesProperty)->Remove( + service_path_value, NULL)) { + CallNotifyObserversPropertyChanged(flimflam::kServicesProperty, 0); + } + if (GetListProperty(flimflam::kServiceWatchListProperty)->Remove( + service_path_value, NULL)) { + CallNotifyObserversPropertyChanged( + flimflam::kServiceWatchListProperty, 0); + } +} + +void ShillManagerClientStub::ClearManagerServices() { + GetListProperty(flimflam::kServicesProperty)->Clear(); + GetListProperty(flimflam::kServiceWatchListProperty)->Clear(); + CallNotifyObserversPropertyChanged(flimflam::kServicesProperty, 0); + CallNotifyObserversPropertyChanged(flimflam::kServiceWatchListProperty, 0); +} + void ShillManagerClientStub::AddGeoNetwork( const std::string& technology, const base::DictionaryValue& network) { @@ -439,12 +445,13 @@ void ShillManagerClientStub::AddProfile(const std::string& profile_path) { void ShillManagerClientStub::AddServiceToWatchList( const std::string& service_path) { - if (GetListProperty( - flimflam::kServiceWatchListProperty)->AppendIfNotPresent( - base::Value::CreateStringValue(service_path))) { - CallNotifyObserversPropertyChanged( - flimflam::kServiceWatchListProperty, 0); - } + // Remove and insert the service, moving it to the front of the watch list. + GetListProperty(flimflam::kServiceWatchListProperty)->Remove( + base::StringValue(service_path), NULL); + GetListProperty(flimflam::kServiceWatchListProperty)->Insert( + 0, base::Value::CreateStringValue(service_path)); + CallNotifyObserversPropertyChanged( + flimflam::kServiceWatchListProperty, 0); } void ShillManagerClientStub::SetDefaultProperties() { @@ -479,12 +486,6 @@ void ShillManagerClientStub::PassStubGeoNetworks( void ShillManagerClientStub::CallNotifyObserversPropertyChanged( const std::string& property, int delay_ms) { - // Don't actually delay unless we're interactive. - if (!CommandLine::ForCurrentProcess()->HasSwitch( - chromeos::switches::kEnableStubInteractive)) { - delay_ms = 0; - } - // Avoid unnecessary delayed task if we have no observers (e.g. during // initial setup). if (observer_list_.size() == 0) diff --git a/chromeos/dbus/shill_manager_client_stub.h b/chromeos/dbus/shill_manager_client_stub.h index d1ff8de..53863a2 100644 --- a/chromeos/dbus/shill_manager_client_stub.h +++ b/chromeos/dbus/shill_manager_client_stub.h @@ -13,9 +13,9 @@ namespace chromeos { -// A stub implementation of ShillManagerClient. -// Implemented: Stub devices and services for NetworkStateManager tests. -// Implemented: Stub cellular device entry for SMS tests. +// A stub implementation of ShillManagerClient. This works in close coordination +// with ShillServiceClientStub. ShillDeviceClientStub, and +// ShillProfileClientStub, and is not intended to be used independently. class ShillManagerClientStub : public ShillManagerClient, public ShillManagerClient::TestInterface { public: @@ -78,17 +78,9 @@ class ShillManagerClientStub : public ShillManagerClient, virtual ShillManagerClient::TestInterface* GetTestInterface() OVERRIDE; // ShillManagerClient::TestInterface overrides. - virtual void AddDevice(const std::string& device_path) OVERRIDE; virtual void RemoveDevice(const std::string& device_path) OVERRIDE; virtual void ClearDevices() OVERRIDE; - virtual void ClearServices() OVERRIDE; - virtual void AddService(const std::string& service_path, - bool add_to_watch_list) OVERRIDE; - virtual void AddServiceAtIndex(const std::string& service_path, - size_t index, - bool add_to_watch_list) OVERRIDE; - virtual void RemoveService(const std::string& service_path) OVERRIDE; virtual void AddTechnology(const std::string& type, bool enabled) OVERRIDE; virtual void RemoveTechnology(const std::string& type) OVERRIDE; virtual void SetTechnologyInitializing(const std::string& type, @@ -97,6 +89,13 @@ class ShillManagerClientStub : public ShillManagerClient, const base::DictionaryValue& network) OVERRIDE; virtual void AddProfile(const std::string& profile_path) OVERRIDE; virtual void ClearProperties() OVERRIDE; + virtual void MoveServiceToIndex(const std::string& service_path, + size_t index, + bool add_to_watch_list) OVERRIDE; + virtual void AddManagerService(const std::string& service_path, + bool add_to_watch_list) OVERRIDE; + virtual void RemoveManagerService(const std::string& service_path) OVERRIDE; + virtual void ClearManagerServices() OVERRIDE; private: void AddServiceToWatchList(const std::string& service_path); diff --git a/chromeos/dbus/shill_service_client_stub.cc b/chromeos/dbus/shill_service_client_stub.cc index 677f9d6..434c4ce 100644 --- a/chromeos/dbus/shill_service_client_stub.cc +++ b/chromeos/dbus/shill_service_client_stub.cc @@ -112,8 +112,7 @@ void ShillServiceClientStub::SetProperty(const dbus::ObjectPath& service_path, if (value.GetAsString(&state) && state == flimflam::kStateOnline) { ShillManagerClient* manager_client = DBusThreadManager::Get()->GetShillManagerClient(); - manager_client->GetTestInterface()->RemoveService(service_path.value()); - manager_client->GetTestInterface()->AddServiceAtIndex( + manager_client->GetTestInterface()->MoveServiceToIndex( service_path.value(), 0, true); } } @@ -189,13 +188,18 @@ void ShillServiceClientStub::Connect(const dbus::ObjectPath& service_path, error_callback.Run("Error.InvalidService", "Invalid Service"); return; } - // Set Associating - base::StringValue associating_value(flimflam::kStateAssociation); - SetServiceProperty(service_path.value(), - flimflam::kStateProperty, - associating_value); + base::TimeDelta delay; + if (CommandLine::ForCurrentProcess()->HasSwitch( + chromeos::switches::kEnableStubInteractive)) { + // Set Associating + base::StringValue associating_value(flimflam::kStateAssociation); + SetServiceProperty(service_path.value(), + flimflam::kStateProperty, + associating_value); + const int kConnectDelaySeconds = 5; + delay = base::TimeDelta::FromSeconds(kConnectDelaySeconds); + } // Set Online after a delay - const int kConnectDelaySeconds = 5; base::StringValue online_value(flimflam::kStateOnline); MessageLoop::current()->PostDelayedTask( FROM_HERE, @@ -206,7 +210,7 @@ void ShillServiceClientStub::Connect(const dbus::ObjectPath& service_path, online_value, base::Bind(&base::DoNothing), error_callback), - base::TimeDelta::FromSeconds(kConnectDelaySeconds)); + delay); callback.Run(); } @@ -218,8 +222,13 @@ void ShillServiceClientStub::Disconnect(const dbus::ObjectPath& service_path, error_callback.Run("Error.InvalidService", "Invalid Service"); return; } + base::TimeDelta delay; + if (CommandLine::ForCurrentProcess()->HasSwitch( + chromeos::switches::kEnableStubInteractive)) { + const int kConnectDelaySeconds = 2; + delay = base::TimeDelta::FromSeconds(kConnectDelaySeconds); + } // Set Idle after a delay - const int kConnectDelaySeconds = 2; base::StringValue idle_value(flimflam::kStateIdle); MessageLoop::current()->PostDelayedTask( FROM_HERE, @@ -230,7 +239,7 @@ void ShillServiceClientStub::Disconnect(const dbus::ObjectPath& service_path, idle_value, base::Bind(&base::DoNothing), error_callback), - base::TimeDelta::FromSeconds(kConnectDelaySeconds)); + delay); callback.Run(); } @@ -290,7 +299,7 @@ void ShillServiceClientStub::AddServiceWithIPConfig( const std::string& ipconfig_path, bool add_to_watch_list) { DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface()-> - AddService(service_path, add_to_watch_list); + AddManagerService(service_path, add_to_watch_list); base::DictionaryValue* properties = GetModifiableServiceProperties(service_path); @@ -314,7 +323,7 @@ void ShillServiceClientStub::AddServiceWithIPConfig( void ShillServiceClientStub::RemoveService(const std::string& service_path) { DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface()-> - RemoveService(service_path); + RemoveManagerService(service_path); stub_services_.RemoveWithoutPathExpansion(service_path, NULL); } @@ -336,7 +345,7 @@ const base::DictionaryValue* ShillServiceClientStub::GetServiceProperties( void ShillServiceClientStub::ClearServices() { DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface()-> - ClearServices(); + ClearManagerServices(); stub_services_.Clear(); } diff --git a/chromeos/dbus/shill_service_client_stub.h b/chromeos/dbus/shill_service_client_stub.h index 2e9bfdd..e30a5f3 100644 --- a/chromeos/dbus/shill_service_client_stub.h +++ b/chromeos/dbus/shill_service_client_stub.h @@ -15,7 +15,8 @@ namespace chromeos { -// A stub implementation of ShillServiceClient. +// A stub implementation of ShillServiceClient. This works in close coordination +// with ShillManagerClientStub and is not intended to be used independently. class ShillServiceClientStub : public ShillServiceClient, public ShillServiceClient::TestInterface { public: diff --git a/chromeos/network/cert_loader.cc b/chromeos/network/cert_loader.cc index 1198acc..2eb14a4 100644 --- a/chromeos/network/cert_loader.cc +++ b/chromeos/network/cert_loader.cc @@ -8,6 +8,7 @@ #include "base/chromeos/chromeos_version.h" #include "base/observer_list.h" +#include "base/strings/string_number_conversions.h" #include "base/task_runner_util.h" #include "base/threading/worker_pool.h" #include "chromeos/dbus/cryptohome_client.h" @@ -27,7 +28,8 @@ const int kRequestDelayMs = 500; net::CertificateList* LoadNSSCertificates() { net::CertificateList* cert_list(new net::CertificateList()); - net::NSSCertDatabase::GetInstance()->ListCerts(cert_list); + if (base::chromeos::IsRunningOnChromeOS()) + net::NSSCertDatabase::GetInstance()->ListCerts(cert_list); return cert_list; } @@ -119,6 +121,36 @@ void CertLoader::RequestCertificates() { return; } +// For background see this discussion on dev-tech-crypto.lists.mozilla.org: +// http://web.archiveorange.com/archive/v/6JJW7E40sypfZGtbkzxX +// +// NOTE: This function relies on the convention that the same PKCS#11 ID +// is shared between a certificate and its associated private and public +// keys. I tried to implement this with PK11_GetLowLevelKeyIDForCert(), +// but that always returns NULL on Chrome OS for me. +std::string CertLoader::GetPkcs11IdForCert( + const net::X509Certificate& cert) const { + if (!IsHardwareBacked()) + return std::string(); + + CERTCertificateStr* cert_handle = cert.os_cert_handle(); + SECKEYPrivateKey *priv_key = + PK11_FindKeyByAnyCert(cert_handle, NULL /* wincx */); + if (!priv_key) + return std::string(); + + // Get the CKA_ID attribute for a key. + SECItem* sec_item = PK11_GetLowLevelKeyIDForPrivateKey(priv_key); + std::string pkcs11_id; + if (sec_item) { + pkcs11_id = base::HexEncode(sec_item->data, sec_item->len); + SECITEM_FreeItem(sec_item, PR_TRUE); + } + SECKEY_DestroyPrivateKey(priv_key); + + return pkcs11_id; +} + void CertLoader::OnTpmIsEnabled(DBusMethodCallStatus call_status, bool tpm_is_enabled) { VLOG(1) << "OnTpmIsEnabled: " << tpm_is_enabled; @@ -172,7 +204,8 @@ void CertLoader::OnPkcs11GetTpmTokenInfo(DBusMethodCallStatus call_status, void CertLoader::InitializeTPMToken() { VLOG(1) << "InitializeTPMToken"; - if (!crypto::InitializeTPMToken(tpm_token_name_, tpm_user_pin_)) { + if (base::chromeos::IsRunningOnChromeOS() && + !crypto::InitializeTPMToken(tpm_token_name_, tpm_user_pin_)) { MaybeRetryRequestCertificates(); return; } @@ -213,6 +246,8 @@ void CertLoader::MaybeRetryRequestCertificates() { if (!request_task_.is_null()) return; + LOG(WARNING) << "Re-Requesting Certificates."; + // Cryptohome does not notify us when the token is ready, so call // this again after a delay. request_task_ = base::Bind(&CertLoader::RequestCertificatesTask, diff --git a/chromeos/network/cert_loader.h b/chromeos/network/cert_loader.h index f3b69ae..dd9f4c3 100644 --- a/chromeos/network/cert_loader.h +++ b/chromeos/network/cert_loader.h @@ -64,6 +64,8 @@ class CHROMEOS_EXPORT CertLoader : public net::CertDatabase::Observer, // Returns true if the TPM is available for hardware-backed certificates. bool IsHardwareBacked() const; + std::string GetPkcs11IdForCert(const net::X509Certificate& cert) const; + bool certificates_loaded() const { return certificates_loaded_; } // TPM info is only valid once the TPM is available (IsHardwareBacked is diff --git a/chrome/browser/chromeos/cros/certificate_pattern_matcher.cc b/chromeos/network/certificate_pattern_matcher.cc index f733d60..816b5f6 100644 --- a/chrome/browser/chromeos/cros/certificate_pattern_matcher.cc +++ b/chromeos/network/certificate_pattern_matcher.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/chromeos/cros/certificate_pattern_matcher.h" +#include "chromeos/network/certificate_pattern_matcher.h" #include <cert.h> #include <pk11pub.h> @@ -130,6 +130,8 @@ class IssuerCaRefFilter { } // namespace +namespace certificate_pattern { + scoped_refptr<net::X509Certificate> GetCertificateMatch( const CertificatePattern& pattern) { typedef std::list<scoped_refptr<net::X509Certificate> > CertificateStlList; @@ -190,4 +192,6 @@ scoped_refptr<net::X509Certificate> GetCertificateMatch( return latest; } +} // namespace certificate_pattern + } // namespace chromeos diff --git a/chrome/browser/chromeos/cros/certificate_pattern_matcher.h b/chromeos/network/certificate_pattern_matcher.h index 9412606..a79a548 100644 --- a/chrome/browser/chromeos/cros/certificate_pattern_matcher.h +++ b/chromeos/network/certificate_pattern_matcher.h @@ -2,10 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_CHROMEOS_CROS_CERTIFICATE_PATTERN_MATCHER_H_ -#define CHROME_BROWSER_CHROMEOS_CROS_CERTIFICATE_PATTERN_MATCHER_H_ +#ifndef CHROMEOS_NETWORK_CERTIFICATE_PATTERN_MATCHER_H_ +#define CHROMEOS_NETWORK_CERTIFICATE_PATTERN_MATCHER_H_ #include "base/memory/ref_counted.h" +#include "chromeos/chromeos_export.h" namespace net { class X509Certificate; @@ -15,11 +16,15 @@ namespace chromeos { class CertificatePattern; +namespace certificate_pattern { + // Fetches the matching certificate that has the latest valid start date. // Returns a NULL refptr if there is no such match. -scoped_refptr<net::X509Certificate> GetCertificateMatch( +CHROMEOS_EXPORT scoped_refptr<net::X509Certificate> GetCertificateMatch( const CertificatePattern& pattern); +} // namespace certificate_pattern + } // namespace chromeos -#endif // CHROME_BROWSER_CHROMEOS_CROS_CERTIFICATE_PATTERN_MATCHER_H_ +#endif // CHROMEOS_NETWORK_CERTIFICATE_PATTERN_MATCHER_H_ diff --git a/chromeos/network/managed_network_configuration_handler.cc b/chromeos/network/managed_network_configuration_handler.cc index ea772f6..122bdcd 100644 --- a/chromeos/network/managed_network_configuration_handler.cc +++ b/chromeos/network/managed_network_configuration_handler.cc @@ -87,26 +87,6 @@ void RunErrorCallback(const std::string& service_path, error_message))); } -// Returns the NetworkUIData parsed from the UIData property of -// |shill_dictionary|. If parsing fails or the field doesn't exist, returns -// NULL. -scoped_ptr<NetworkUIData> GetUIData( - const base::DictionaryValue& shill_dictionary) { - std::string ui_data_blob; - if (shill_dictionary.GetStringWithoutPathExpansion( - flimflam::kUIDataProperty, - &ui_data_blob) && - !ui_data_blob.empty()) { - scoped_ptr<base::DictionaryValue> ui_data_dict = - onc::ReadDictionaryFromJson(ui_data_blob); - if (ui_data_dict) - return make_scoped_ptr(new NetworkUIData(*ui_data_dict)); - else - LOG(ERROR) << "UIData is not a valid JSON dictionary."; - } - return scoped_ptr<NetworkUIData>(); -} - // Sets the UIData property in |shill_dictionary| to the serialization of // |ui_data|. void SetUIData(const NetworkUIData& ui_data, @@ -125,7 +105,7 @@ void IgnoreString(const std::string& str) { void LogErrorWithDict(const tracked_objects::Location& from_where, const std::string& error_name, - const scoped_ptr<base::DictionaryValue> error_data) { + scoped_ptr<base::DictionaryValue> error_data) { LOG(ERROR) << from_where.ToString() << ": " << error_name; } @@ -228,7 +208,7 @@ scoped_ptr<base::DictionaryValue> CreateShillConfiguration( scoped_ptr<NetworkUIData> ui_data; if (policy) - ui_data = CreateUIDataFromONC(onc_source, *policy); + ui_data = NetworkUIData::CreateFromONC(onc_source, *policy); else ui_data.reset(new NetworkUIData()); @@ -345,6 +325,25 @@ ManagedNetworkConfigurationHandler* ManagedNetworkConfigurationHandler::Get() { return g_configuration_handler_instance; } +// static +scoped_ptr<NetworkUIData> ManagedNetworkConfigurationHandler::GetUIData( + const base::DictionaryValue& shill_dictionary) { + std::string ui_data_blob; + if (shill_dictionary.GetStringWithoutPathExpansion( + flimflam::kUIDataProperty, + &ui_data_blob) && + !ui_data_blob.empty()) { + scoped_ptr<base::DictionaryValue> ui_data_dict = + onc::ReadDictionaryFromJson(ui_data_blob); + if (ui_data_dict) + return make_scoped_ptr(new NetworkUIData(*ui_data_dict)); + else + LOG(ERROR) << "UIData is not a valid JSON dictionary."; + } + VLOG(2) << "JSON dictionary has no UIData blob: " << shill_dictionary; + return scoped_ptr<NetworkUIData>(); +} + void ManagedNetworkConfigurationHandler::GetManagedProperties( const std::string& userhash, const std::string& service_path, @@ -540,24 +539,6 @@ void ManagedNetworkConfigurationHandler::SetProperties( error_callback); } -void ManagedNetworkConfigurationHandler::Connect( - const std::string& service_path, - const base::Closure& callback, - const network_handler::ErrorCallback& error_callback) const { - NetworkConfigurationHandler::Get()->Connect(service_path, - callback, - error_callback); -} - -void ManagedNetworkConfigurationHandler::Disconnect( - const std::string& service_path, - const base::Closure& callback, - const network_handler::ErrorCallback& error_callback) const { - NetworkConfigurationHandler::Get()->Disconnect(service_path, - callback, - error_callback); -} - void ManagedNetworkConfigurationHandler::CreateConfiguration( const std::string& userhash, const base::DictionaryValue& properties, diff --git a/chromeos/network/managed_network_configuration_handler.h b/chromeos/network/managed_network_configuration_handler.h index db7e47d..295fd1e 100644 --- a/chromeos/network/managed_network_configuration_handler.h +++ b/chromeos/network/managed_network_configuration_handler.h @@ -25,6 +25,7 @@ class ListValue; namespace chromeos { class NetworkProfileHandler; +class NetworkUIData; // The ManagedNetworkConfigurationHandler class is used to create and configure // networks in ChromeOS using ONC and takes care of network policies. @@ -69,6 +70,12 @@ class CHROMEOS_EXPORT ManagedNetworkConfigurationHandler // Initialize() must be called before this. static ManagedNetworkConfigurationHandler* Get(); + // Returns the NetworkUIData parsed from the UIData property of + // |shill_dictionary|. If parsing fails or the field doesn't exist, returns + // NULL. + static scoped_ptr<NetworkUIData> GetUIData( + const base::DictionaryValue& shill_dictionary); + // Provides the properties of the network with |service_path| to |callback|. void GetProperties( const std::string& service_path, @@ -95,20 +102,6 @@ class CHROMEOS_EXPORT ManagedNetworkConfigurationHandler const base::Closure& callback, const network_handler::ErrorCallback& error_callback) const; - // Initiates a connection with network that has |service_path|. |callback| is - // called if the connection request was successfully handled. That doesn't - // mean that the connection was successfully established. - void Connect(const std::string& service_path, - const base::Closure& callback, - const network_handler::ErrorCallback& error_callback) const; - - // Initiates a disconnect with the network at |service_path|. |callback| is - // called if the diconnect request was successfully handled. That doesn't mean - // that the network is already diconnected. - void Disconnect(const std::string& service_path, - const base::Closure& callback, - const network_handler::ErrorCallback& error_callback) const; - // Initially configures an unconfigured network with the given user settings // and returns the new identifier to |callback| if successful. Fails if the // network was already configured by a call to this function or because of a diff --git a/chromeos/network/network_configuration_handler.cc b/chromeos/network/network_configuration_handler.cc index ee950d3..b38fb56 100644 --- a/chromeos/network/network_configuration_handler.cc +++ b/chromeos/network/network_configuration_handler.cc @@ -168,28 +168,6 @@ void NetworkConfigurationHandler::ClearProperties( kLogModule, service_path, error_callback)); } -void NetworkConfigurationHandler::Connect( - const std::string& service_path, - const base::Closure& callback, - const network_handler::ErrorCallback& error_callback) const { - DBusThreadManager::Get()->GetShillServiceClient()->Connect( - dbus::ObjectPath(service_path), - callback, - base::Bind(&network_handler::ShillErrorCallbackFunction, - kLogModule, service_path, error_callback)); -} - -void NetworkConfigurationHandler::Disconnect( - const std::string& service_path, - const base::Closure& callback, - const network_handler::ErrorCallback& error_callback) const { - DBusThreadManager::Get()->GetShillServiceClient()->Disconnect( - dbus::ObjectPath(service_path), - callback, - base::Bind(&network_handler::ShillErrorCallbackFunction, - kLogModule, service_path, error_callback)); -} - void NetworkConfigurationHandler::CreateConfiguration( const base::DictionaryValue& properties, const network_handler::StringResultCallback& callback, diff --git a/chromeos/network/network_configuration_handler.h b/chromeos/network/network_configuration_handler.h index 2a00989..1707ca0 100644 --- a/chromeos/network/network_configuration_handler.h +++ b/chromeos/network/network_configuration_handler.h @@ -80,19 +80,6 @@ class CHROMEOS_EXPORT NetworkConfigurationHandler { const base::Closure& callback, const network_handler::ErrorCallback& error_callback); - // Initiates a connection with network that has id |service_path|. See note on - // |callback| and |error_callback|, in class description above. - void Connect(const std::string& service_path, - const base::Closure& callback, - const network_handler::ErrorCallback& error_callback) const; - - // Initiates a disconnect with the network at |service_path|. See note on - // |callback| and |error_callback|, in class description above. - void Disconnect(const std::string& service_path, - const base::Closure& callback, - const network_handler::ErrorCallback& error_callback) const; - - // Creates a network with the given properties in the active Shill profile, // and returns the new service_path to |callback| if successful. See note on // |callback| and |error_callback|, in class description above. diff --git a/chromeos/network/network_configuration_handler_unittest.cc b/chromeos/network/network_configuration_handler_unittest.cc index e33f64a..c5f4f3a7 100644 --- a/chromeos/network/network_configuration_handler_unittest.cc +++ b/chromeos/network/network_configuration_handler_unittest.cc @@ -50,7 +50,7 @@ void DictionaryValueCallback( void ErrorCallback(bool error_expected, const std::string& expected_id, const std::string& error_name, - const scoped_ptr<base::DictionaryValue> error_data) { + scoped_ptr<base::DictionaryValue> error_data) { EXPECT_TRUE(error_expected) << "Unexpected error: " << error_name << " with associated data: \n" << PrettyJson(*error_data); @@ -134,18 +134,6 @@ class NetworkConfigurationHandlerTest : public testing::Test { callback.Run(result); } - void OnConnect(const dbus::ObjectPath& service_path, - const base::Closure& callback, - const ShillClientHelper::ErrorCallback& error_callback) { - callback.Run(); - } - - void OnDisconnect(const dbus::ObjectPath& service_path, - const base::Closure& callback, - const ShillClientHelper::ErrorCallback& error_callback) { - callback.Run(); - } - void OnGetService(const base::DictionaryValue& properties, const ObjectPathCallback& callback, const ShillClientHelper::ErrorCallback& error_callback) { @@ -296,34 +284,6 @@ TEST_F(NetworkConfigurationHandlerTest, ClearPropertiesError) { message_loop_.RunUntilIdle(); } -TEST_F(NetworkConfigurationHandlerTest, Connect) { - std::string service_path = "/service/1"; - - EXPECT_CALL(*mock_service_client_, - Connect(_, _, _)).WillOnce( - Invoke(this, - &NetworkConfigurationHandlerTest::OnConnect)); - NetworkConfigurationHandler::Get()->Connect( - service_path, - base::Bind(&base::DoNothing), - base::Bind(&ErrorCallback, false, service_path)); - message_loop_.RunUntilIdle(); -} - -TEST_F(NetworkConfigurationHandlerTest, Disconnect) { - std::string service_path = "/service/1"; - - EXPECT_CALL(*mock_service_client_, - Disconnect(_, _, _)).WillOnce( - Invoke(this, - &NetworkConfigurationHandlerTest::OnDisconnect)); - NetworkConfigurationHandler::Get()->Disconnect( - service_path, - base::Bind(&base::DoNothing), - base::Bind(&ErrorCallback, false, service_path)); - message_loop_.RunUntilIdle(); -} - TEST_F(NetworkConfigurationHandlerTest, CreateConfiguration) { std::string expected_json = "{\n \"SSID\": \"MyNetwork\"\n}\n"; std::string networkName = "MyNetwork"; diff --git a/chromeos/network/network_connection_handler.cc b/chromeos/network/network_connection_handler.cc new file mode 100644 index 0000000..0d98a458 --- /dev/null +++ b/chromeos/network/network_connection_handler.cc @@ -0,0 +1,309 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chromeos/network/network_connection_handler.h" + +#include "base/bind.h" +#include "base/json/json_reader.h" +#include "chromeos/dbus/dbus_thread_manager.h" +#include "chromeos/dbus/shill_manager_client.h" +#include "chromeos/dbus/shill_service_client.h" +#include "chromeos/network/cert_loader.h" +#include "chromeos/network/certificate_pattern_matcher.h" +#include "chromeos/network/managed_network_configuration_handler.h" +#include "chromeos/network/network_configuration_handler.h" +#include "chromeos/network/network_event_log.h" +#include "chromeos/network/network_handler_callbacks.h" +#include "chromeos/network/network_state.h" +#include "chromeos/network/network_state_handler.h" +#include "chromeos/network/network_ui_data.h" +#include "dbus/object_path.h" +#include "net/cert/x509_certificate.h" +#include "third_party/cros_system_api/dbus/service_constants.h" + +namespace chromeos { + +namespace { + +const char kLogModule[] = "NetworkConnectionHandler"; + +void InvokeErrorCallback( + const std::string& service_path, + const network_handler::ErrorCallback& error_callback, + const std::string& error_name) { + network_handler::ShillErrorCallbackFunction( + kLogModule, service_path, error_callback, error_name, "Connect Error"); +} + +bool NetworkMayNeedCredentials(const NetworkState* network) { + if (network->type() == flimflam::kTypeWifi && + (network->security() == flimflam::kSecurity8021x || + network->security() == flimflam::kSecurityWep /* For dynamic WEP*/)) + return true; + if (network->type() == flimflam::kTypeVPN) + return true; + return false; +} + +bool NetworkRequiresActivation(const NetworkState* network) { + return (network->type() == flimflam::kTypeCellular && + (network->activation_state() != flimflam::kActivationStateActivated || + network->cellular_out_of_credits())); +} + +bool VPNIsConfigured(const base::DictionaryValue& properties) { + std::string provider_type; + // Note: we use Value path expansion to extract Provider.Type. + properties.GetString(flimflam::kProviderTypeProperty, &provider_type); + if (provider_type == flimflam::kProviderOpenVpn) { + std::string hostname; + properties.GetString(flimflam::kProviderHostProperty, &hostname); + if (hostname.empty()) + return false; + std::string username; + properties.GetStringWithoutPathExpansion( + flimflam::kOpenVPNUserProperty, &username); + if (username.empty()) + return false; + std::string client_cert_id; + properties.GetStringWithoutPathExpansion( + flimflam::kOpenVPNClientCertIdProperty, &client_cert_id); + if (client_cert_id.empty()) + return false; + } else { + bool passphrase_required = false; + std::string passphrase; + properties.GetBooleanWithoutPathExpansion( + flimflam::kL2tpIpsecPskRequiredProperty, &passphrase_required); + properties.GetStringWithoutPathExpansion( + flimflam::kL2tpIpsecPskProperty, &passphrase); + if (passphrase_required && passphrase.empty()) + return false; + } + return true; +} + +bool CertificateIsConfigured(NetworkUIData* ui_data) { + if (ui_data->certificate_type() != CLIENT_CERT_TYPE_PATTERN) + return true; // No certificate or a reference. + if (ui_data->onc_source() == onc::ONC_SOURCE_DEVICE_POLICY) { + // We skip checking certificate patterns for device policy ONC so that an + // unmanaged user can't get to the place where a cert is presented for them + // involuntarily. + return true; + } + if (ui_data->certificate_pattern().Empty()) + return false; + + // Find the matching certificate. + scoped_refptr<net::X509Certificate> matching_cert = + certificate_pattern::GetCertificateMatch( + ui_data->certificate_pattern()); + if (!matching_cert.get()) + return false; + return true; +} + +} // namespace + +static NetworkConnectionHandler* g_connection_handler_instance = NULL; + +const char NetworkConnectionHandler::kErrorNotFound[] = "not-found"; +const char NetworkConnectionHandler::kErrorConnected[] = "connected"; +const char NetworkConnectionHandler::kErrorConnecting[] = "connecting"; +const char NetworkConnectionHandler::kErrorNotConnected[] = "not-connected"; +const char NetworkConnectionHandler::kErrorPassphraseRequired[] = + "passphrase-required"; +const char NetworkConnectionHandler::kErrorActivationRequired[] = + "activation-required"; +const char NetworkConnectionHandler::kErrorCertificateRequired[] = + "certificate-required"; +const char NetworkConnectionHandler::kErrorConfigurationRequired[] = + "configuration-required"; +const char NetworkConnectionHandler::kErrorShillError[] = "shill-error"; + +// static +void NetworkConnectionHandler::Initialize() { + CHECK(!g_connection_handler_instance); + g_connection_handler_instance = new NetworkConnectionHandler; +} + +// static +void NetworkConnectionHandler::Shutdown() { + CHECK(g_connection_handler_instance); + delete g_connection_handler_instance; + g_connection_handler_instance = NULL; +} + +// static +NetworkConnectionHandler* NetworkConnectionHandler::Get() { + CHECK(g_connection_handler_instance) + << "NetworkConnectionHandler::Get() called before Initialize()"; + return g_connection_handler_instance; +} + +NetworkConnectionHandler::NetworkConnectionHandler() { +} + +NetworkConnectionHandler::~NetworkConnectionHandler() { +} + +void NetworkConnectionHandler::ConnectToNetwork( + const std::string& service_path, + const base::Closure& success_callback, + const network_handler::ErrorCallback& error_callback) { + const NetworkState* network = + NetworkStateHandler::Get()->GetNetworkState(service_path); + if (!network) { + InvokeErrorCallback(service_path, error_callback, kErrorNotFound); + return; + } + if (network->IsConnectedState()) { + InvokeErrorCallback(service_path, error_callback, kErrorConnected); + return; + } + if (network->IsConnectingState() || + pending_requests_.find(service_path) != pending_requests_.end()) { + InvokeErrorCallback(service_path, error_callback, kErrorConnecting); + return; + } + if (network->passphrase_required()) { + InvokeErrorCallback(service_path, error_callback, kErrorPassphraseRequired); + return; + } + if (NetworkRequiresActivation(network)) { + InvokeErrorCallback(service_path, error_callback, kErrorActivationRequired); + return; + } + + // All synchronous checks passed, add |service_path| to connecting list. + pending_requests_.insert(service_path); + + if (!network->connectable() && NetworkMayNeedCredentials(network)) { + // Request additional properties to check. + NetworkConfigurationHandler::Get()->GetProperties( + network->path(), + base::Bind(&NetworkConnectionHandler::VerifyConfiguredAndConnect, + AsWeakPtr(), success_callback, error_callback), + base::Bind(&NetworkConnectionHandler::HandleConfigurationFailure, + AsWeakPtr(), network->path(), error_callback)); + return; + } + // All checks passed, send connect request. + CallShillConnect(service_path, success_callback, error_callback); +} + +void NetworkConnectionHandler::DisconnectNetwork( + const std::string& service_path, + const base::Closure& success_callback, + const network_handler::ErrorCallback& error_callback) { + const NetworkState* network = + NetworkStateHandler::Get()->GetNetworkState(service_path); + if (!network) { + InvokeErrorCallback(service_path, error_callback, kErrorNotFound); + return; + } + if (!network->IsConnectedState()) { + InvokeErrorCallback(service_path, error_callback, kErrorNotConnected); + return; + } + CallShillDisconnect(service_path, success_callback, error_callback); +} + +void NetworkConnectionHandler::CallShillConnect( + const std::string& service_path, + const base::Closure& success_callback, + const network_handler::ErrorCallback& error_callback) { + // TODO(stevenjb): Remove SetConnectingNetwork and use this class to maintain + // the connecting network(s) once NetworkLibrary path is eliminated. + NetworkStateHandler::Get()->SetConnectingNetwork(service_path); + network_event_log::AddEntry(kLogModule, "Connect Request", service_path); + DBusThreadManager::Get()->GetShillServiceClient()->Connect( + dbus::ObjectPath(service_path), + base::Bind(&NetworkConnectionHandler::HandleShillSuccess, + AsWeakPtr(), service_path, success_callback), + base::Bind(&NetworkConnectionHandler::HandleShillFailure, + AsWeakPtr(), service_path, error_callback)); +} + +void NetworkConnectionHandler::CallShillDisconnect( + const std::string& service_path, + const base::Closure& success_callback, + const network_handler::ErrorCallback& error_callback) { + network_event_log::AddEntry(kLogModule, "Disconnect Request", service_path); + DBusThreadManager::Get()->GetShillServiceClient()->Disconnect( + dbus::ObjectPath(service_path), + base::Bind(&NetworkConnectionHandler::HandleShillSuccess, + AsWeakPtr(), service_path, success_callback), + base::Bind(&NetworkConnectionHandler::HandleShillFailure, + AsWeakPtr(), service_path, error_callback)); +} + +void NetworkConnectionHandler::VerifyConfiguredAndConnect( + const base::Closure& success_callback, + const network_handler::ErrorCallback& error_callback, + const std::string& service_path, + const base::DictionaryValue& properties) { + const NetworkState* network = + NetworkStateHandler::Get()->GetNetworkState(service_path); + if (!network) { + InvokeErrorCallback(service_path, error_callback, kErrorNotFound); + return; + } + + // VPN requires a host and username to be set. + if (network->type() == flimflam::kTypeVPN && + !VPNIsConfigured(properties)) { + InvokeErrorCallback(service_path, error_callback, + kErrorConfigurationRequired); + return; + } + + // Check certificate properties in kUIDataProperty. + scoped_ptr<NetworkUIData> ui_data = + ManagedNetworkConfigurationHandler::GetUIData(properties); + if (ui_data && !CertificateIsConfigured(ui_data.get())) { + InvokeErrorCallback(service_path, error_callback, + kErrorCertificateRequired); + return; + } + + CallShillConnect(service_path, success_callback, error_callback); +} + +void NetworkConnectionHandler::HandleConfigurationFailure( + const std::string& service_path, + const network_handler::ErrorCallback& error_callback, + const std::string& error_name, + scoped_ptr<base::DictionaryValue> error_data) { + pending_requests_.erase(service_path); + if (!error_callback.is_null()) + error_callback.Run(error_name, error_data.Pass()); +} + +void NetworkConnectionHandler::HandleShillSuccess( + const std::string& service_path, + const base::Closure& success_callback) { + // TODO(stevenjb): Currently, this only indicates that the connect request + // succeeded. It might be preferable to wait for the actually connect + // attempt to succeed or fail here and only call |success_callback| at that + // point (or maybe call it twice, once indicating in-progress, then success + // or failure). + pending_requests_.erase(service_path); + network_event_log::AddEntry(kLogModule, "Connected", service_path); + success_callback.Run(); +} + +void NetworkConnectionHandler::HandleShillFailure( + const std::string& service_path, + const network_handler::ErrorCallback& error_callback, + const std::string& error_name, + const std::string& error_message) { + pending_requests_.erase(service_path); + std::string error = "Connect Failure: " + error_name + ": " + error_message; + network_handler::ShillErrorCallbackFunction( + kLogModule, service_path, error_callback, error_name, error_message); +} + +} // namespace chromeos diff --git a/chromeos/network/network_connection_handler.h b/chromeos/network/network_connection_handler.h new file mode 100644 index 0000000..afe09e4 --- /dev/null +++ b/chromeos/network/network_connection_handler.h @@ -0,0 +1,141 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROMEOS_NETWORK_NETWORK_CONNECTION_HANDLER_H_ +#define CHROMEOS_NETWORK_NETWORK_CONNECTION_HANDLER_H_ + +#include <set> +#include <string> + +#include "base/basictypes.h" +#include "base/callback.h" +#include "base/memory/weak_ptr.h" +#include "base/values.h" +#include "chromeos/chromeos_export.h" +#include "chromeos/dbus/dbus_method_call_status.h" +#include "chromeos/network/network_handler_callbacks.h" + +namespace chromeos { + +class NetworkState; + +// The NetworkConnectionHandler class is used to manage network connection +// requests. This is the only class that should make Shill Connect calls. +// It handles the following steps: +// 1. Determine whether or not sufficient information (e.g. passphrase) is +// known to be available to connect to the network. +// 2. Request additional information (e.g. user data which contains certificate +// information) and determine whether sufficient information is available. +// 3. Send the connect request. +// 4. Invoke the appropriate callback (always) on success or failure. +// +// NetworkConnectionHandler depends on NetworkStateHandler for immediately +// available State information, and NetworkConfigurationHandler for any +// configuration calls. + +class CHROMEOS_EXPORT NetworkConnectionHandler + : public base::SupportsWeakPtr<NetworkConnectionHandler> { + public: + // Constants for |error_name| from |error_callback| for Connect/Disconnect. + static const char kErrorNotFound[]; + static const char kErrorConnected[]; + static const char kErrorConnecting[]; + static const char kErrorNotConnected[]; + static const char kErrorPassphraseRequired[]; + static const char kErrorActivationRequired[]; + static const char kErrorCertificateRequired[]; + static const char kErrorConfigurationRequired[]; + static const char kErrorShillError[]; + + // Sets the global instance. Must be called before any calls to Get(). + static void Initialize(); + + // Destroys the global instance. + static void Shutdown(); + + // Gets the global instance. Initialize() must be called first. + static NetworkConnectionHandler* Get(); + + // ConnectToNetwork() will start an asynchronous connection attempt. + // On success, |success_callback| will be called. + // On failure, |error_callback| will be called with |error_name| one of: + // kErrorNotFound if no network matching |service_path| is found + // (hidden networks must be configured before connecting). + // kErrorConnected if already connected to the network. + // kErrorConnecting if already connecting to the network. + // kErrorCertificateRequired if the network requires a cert and none exists. + // kErrorPassphraseRequired if passphrase only is required. + // kErrorConfigurationRequired if additional configuration is required. + // kErrorShillError if a DBus or Shill error occurred. + // |error_message| will contain an additional error string for debugging. + void ConnectToNetwork(const std::string& service_path, + const base::Closure& success_callback, + const network_handler::ErrorCallback& error_callback); + + // DisconnectToNetwork() will send a Disconnect request to Shill. + // On success, |success_callback| will be called. + // On failure, |error_callback| will be called with |error_name| one of: + // kErrorNotFound if no network matching |service_path| is found. + // kErrorNotConnected if not connected to the network. + // kErrorShillError if a DBus or Shill error occurred. + // |error_message| will contain and additional error string for debugging. + void DisconnectNetwork(const std::string& service_path, + const base::Closure& success_callback, + const network_handler::ErrorCallback& error_callback); + + private: + NetworkConnectionHandler(); + ~NetworkConnectionHandler(); + + // Calls Shill.Manager.Connect asynchronously. + void CallShillConnect( + const std::string& service_path, + const base::Closure& success_callback, + const network_handler::ErrorCallback& error_callback); + + // Calls Shill.Manager.Disconnect asynchronously. + void CallShillDisconnect( + const std::string& service_path, + const base::Closure& success_callback, + const network_handler::ErrorCallback& error_callback); + + // Callback from Shill.Service.GetProperties. Parses |properties| to verify + // whether or not the network appears to be configured. If configured, + // attempts a connection, otherwise invokes |error_callback|. + void VerifyConfiguredAndConnect( + const base::Closure& success_callback, + const network_handler::ErrorCallback& error_callback, + const std::string& service_path, + const base::DictionaryValue& properties); + + // Sets the property for the service with an empty callback (logs errors). + void SetServiceProperty(const std::string& service_path, + const std::string& property, + const std::string& value) const; + + // Handle failure from ConfigurationHandler calls. + void HandleConfigurationFailure( + const std::string& service_path, + const network_handler::ErrorCallback& error_callback, + const std::string& error_name, + scoped_ptr<base::DictionaryValue> error_data); + + // Handle success or failure from Shill.Service.Connect. + void HandleShillSuccess(const std::string& service_path, + const base::Closure& success_callback); + void HandleShillFailure(const std::string& service_path, + const network_handler::ErrorCallback& error_callback, + const std::string& error_name, + const std::string& error_message); + + // Set of pending connect requests, used to prevent repeat attempts while + // waiting for Shill. + std::set<std::string> pending_requests_; + + DISALLOW_COPY_AND_ASSIGN(NetworkConnectionHandler); +}; + +} // namespace chromeos + +#endif // CHROMEOS_NETWORK_NETWORK_CONNECTION_HANDLER_H_ diff --git a/chromeos/network/network_connection_handler_unittest.cc b/chromeos/network/network_connection_handler_unittest.cc new file mode 100644 index 0000000..7b4ab2b --- /dev/null +++ b/chromeos/network/network_connection_handler_unittest.cc @@ -0,0 +1,210 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chromeos/network/network_connection_handler.h" + +#include "base/bind.h" +#include "base/memory/scoped_ptr.h" +#include "base/message_loop.h" +#include "chromeos/dbus/dbus_thread_manager.h" +#include "chromeos/dbus/shill_manager_client.h" +#include "chromeos/dbus/shill_service_client.h" +#include "chromeos/network/network_configuration_handler.h" +#include "chromeos/network/network_state_handler.h" +#include "chromeos/network/onc/onc_utils.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/cros_system_api/dbus/service_constants.h" + +namespace { + +const char* kSuccessResult = "success"; + +} // namespace + +namespace chromeos { + +class NetworkConnectionHandlerTest : public testing::Test { + public: + NetworkConnectionHandlerTest() { + } + virtual ~NetworkConnectionHandlerTest() { + } + + virtual void SetUp() OVERRIDE { + // Initialize DBusThreadManager with a stub implementation. + DBusThreadManager::InitializeWithStub(); + message_loop_.RunUntilIdle(); + DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface() + ->ClearServices(); + message_loop_.RunUntilIdle(); + NetworkStateHandler::Initialize(); + NetworkConfigurationHandler::Initialize(); + NetworkConnectionHandler::Initialize(); + } + + virtual void TearDown() OVERRIDE { + NetworkConnectionHandler::Shutdown(); + NetworkConfigurationHandler::Shutdown(); + NetworkStateHandler::Shutdown(); + DBusThreadManager::Shutdown(); + } + + protected: + bool Configure(const std::string& json_string) { + scoped_ptr<base::DictionaryValue> json_dict = + onc::ReadDictionaryFromJson(json_string); + if (!json_dict) { + LOG(ERROR) << "Error parsing json: " << json_string; + return false; + } + DBusThreadManager::Get()->GetShillManagerClient()->ConfigureService( + *json_dict, + ObjectPathCallback(), ShillManagerClient::ErrorCallback()); + message_loop_.RunUntilIdle(); + return true; + } + + void Connect(const std::string& service_path) { + NetworkConnectionHandler::Get()->ConnectToNetwork( + service_path, + base::Bind(&NetworkConnectionHandlerTest::SuccessCallback, + base::Unretained(this)), + base::Bind(&NetworkConnectionHandlerTest::ErrorCallback, + base::Unretained(this))); + message_loop_.RunUntilIdle(); + } + + void Disconnect(const std::string& service_path) { + NetworkConnectionHandler::Get()->DisconnectNetwork( + service_path, + base::Bind(&NetworkConnectionHandlerTest::SuccessCallback, + base::Unretained(this)), + base::Bind(&NetworkConnectionHandlerTest::ErrorCallback, + base::Unretained(this))); + message_loop_.RunUntilIdle(); + } + + void SuccessCallback() { + result_ = kSuccessResult; + } + + void ErrorCallback(const std::string& error_name, + scoped_ptr<base::DictionaryValue> error_data) { + result_ = error_name; + } + + std::string GetResultAndReset() { + std::string result; + result.swap(result_); + return result; + } + + std::string GetServiceStringProperty(const std::string& service_path, + const std::string& key) { + std::string result; + const base::DictionaryValue* properties = + DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface()-> + GetServiceProperties(service_path); + if (properties) + properties->GetStringWithoutPathExpansion(key, &result); + return result; + } + + MessageLoopForUI message_loop_; + std::string result_; + + private: + DISALLOW_COPY_AND_ASSIGN(NetworkConnectionHandlerTest); +}; + +namespace { + +const char* kConfigConnectable = + "{ \"GUID\": \"wifi0\", \"Type\": \"wifi\", \"State\": \"idle\" }"; +const char* kConfigConnected = + "{ \"GUID\": \"wifi1\", \"Type\": \"wifi\", \"State\": \"online\" }"; +const char* kConfigConnecting = + "{ \"GUID\": \"wifi2\", \"Type\": \"wifi\", \"State\": \"association\" }"; +const char* kConfigRequiresPassphrase = + "{ \"GUID\": \"wifi3\", \"Type\": \"wifi\", " + "\"PassphraseRequired\": true }"; +const char* kConfigRequiresActivation = + "{ \"GUID\": \"cellular1\", \"Type\": \"cellular\"," + " \"Cellular.ActivationState\": \"not-activated\" }"; + +} // namespace + +TEST_F(NetworkConnectionHandlerTest, NetworkConnectionHandlerConnectSuccess) { + EXPECT_TRUE(Configure(kConfigConnectable)); + Connect("wifi0"); + EXPECT_EQ(kSuccessResult, GetResultAndReset()); + EXPECT_EQ(flimflam::kStateOnline, + GetServiceStringProperty("wifi0", flimflam::kStateProperty)); +} + +// Handles basic failure cases. +TEST_F(NetworkConnectionHandlerTest, NetworkConnectionHandlerConnectFailure) { + Connect("no-network"); + EXPECT_EQ(NetworkConnectionHandler::kErrorNotFound, GetResultAndReset()); + + EXPECT_TRUE(Configure(kConfigConnected)); + Connect("wifi1"); + EXPECT_EQ(NetworkConnectionHandler::kErrorConnected, GetResultAndReset()); + + EXPECT_TRUE(Configure(kConfigConnecting)); + Connect("wifi2"); + EXPECT_EQ(NetworkConnectionHandler::kErrorConnecting, GetResultAndReset()); + + EXPECT_TRUE(Configure(kConfigRequiresPassphrase)); + Connect("wifi3"); + EXPECT_EQ(NetworkConnectionHandler::kErrorPassphraseRequired, + GetResultAndReset()); + + EXPECT_TRUE(Configure(kConfigRequiresActivation)); + Connect("cellular1"); + EXPECT_EQ(NetworkConnectionHandler::kErrorActivationRequired, + GetResultAndReset()); +} + +namespace { + +const char* kConfigRequiresCertificate = + "{ \"GUID\": \"wifi4\", \"Type\": \"wifi\", \"Connectable\": false," + " \"Security\": \"802_1x\"," + " \"UIData\": \"{" + " \\\"certificate_type\\\": \\\"pattern\\\"," + " \\\"certificate_pattern\\\": {" + " \\\"Subject\\\": { \\\"CommonName\\\": \\\"Foo\\\" }" + " } }\" }"; + +} // namespace + +// Handle certificates. TODO(stevenjb): Add certificate stubs to improve +// test coverage. +TEST_F(NetworkConnectionHandlerTest, + NetworkConnectionHandlerConnectCertificate) { + EXPECT_TRUE(Configure(kConfigRequiresCertificate)); + Connect("wifi4"); + EXPECT_EQ(NetworkConnectionHandler::kErrorCertificateRequired, + GetResultAndReset()); +} + +TEST_F(NetworkConnectionHandlerTest, + NetworkConnectionHandlerDisconnectSuccess) { + EXPECT_TRUE(Configure(kConfigConnected)); + Disconnect("wifi1"); + EXPECT_EQ(kSuccessResult, GetResultAndReset()); +} + +TEST_F(NetworkConnectionHandlerTest, + NetworkConnectionHandlerDisconnectFailure) { + Connect("no-network"); + EXPECT_EQ(NetworkConnectionHandler::kErrorNotFound, GetResultAndReset()); + + EXPECT_TRUE(Configure(kConfigConnectable)); + Disconnect("wifi0"); + EXPECT_EQ(NetworkConnectionHandler::kErrorNotConnected, GetResultAndReset()); +} + +} // namespace chromeos diff --git a/chromeos/network/network_handler_callbacks.h b/chromeos/network/network_handler_callbacks.h index da62bbd..7618757 100644 --- a/chromeos/network/network_handler_callbacks.h +++ b/chromeos/network/network_handler_callbacks.h @@ -22,7 +22,7 @@ namespace network_handler { // handler to receive error results from the API. typedef base::Callback< void(const std::string& error_name, - const scoped_ptr<base::DictionaryValue> error_data)> ErrorCallback; + scoped_ptr<base::DictionaryValue> error_data)> ErrorCallback; typedef base::Callback< void(const std::string& service_path, diff --git a/chromeos/network/network_state.cc b/chromeos/network/network_state.cc index 3aa0472..7092c21 100644 --- a/chromeos/network/network_state.cc +++ b/chromeos/network/network_state.cc @@ -59,6 +59,8 @@ NetworkState::NetworkState(const std::string& path) favorite_(false), priority_(0), signal_strength_(0), + connectable_(false), + passphrase_required_(false), activate_over_non_cellular_networks_(false), cellular_out_of_credits_(false) { } @@ -75,6 +77,10 @@ bool NetworkState::PropertyChanged(const std::string& key, return GetIntegerValue(key, value, &signal_strength_); } else if (key == flimflam::kStateProperty) { return GetStringValue(key, value, &connection_state_); + } else if (key == flimflam::kConnectableProperty) { + return GetBooleanValue(key, value, &connectable_); + } else if (key == flimflam::kPassphraseRequiredProperty) { + return GetBooleanValue(key, value, &passphrase_required_); } else if (key == flimflam::kErrorProperty) { return GetStringValue(key, value, &error_); } else if (key == IPConfigProperty(flimflam::kAddressProperty)) { @@ -130,46 +136,50 @@ void NetworkState::GetProperties(base::DictionaryValue* dictionary) const { dictionary->SetStringWithoutPathExpansion(flimflam::kNameProperty, name()); dictionary->SetStringWithoutPathExpansion(flimflam::kTypeProperty, type()); dictionary->SetIntegerWithoutPathExpansion(flimflam::kSignalStrengthProperty, - signal_strength()); + signal_strength_); dictionary->SetStringWithoutPathExpansion(flimflam::kStateProperty, - connection_state()); + connection_state_); + dictionary->SetBooleanWithoutPathExpansion(flimflam::kConnectableProperty, + connectable_); + dictionary->SetBooleanWithoutPathExpansion( + flimflam::kPassphraseRequiredProperty, passphrase_required_); dictionary->SetStringWithoutPathExpansion(flimflam::kErrorProperty, - error()); + error_); base::DictionaryValue* ipconfig_properties = new DictionaryValue; ipconfig_properties->SetStringWithoutPathExpansion(flimflam::kAddressProperty, - ip_address()); + ip_address_); base::ListValue* name_servers = new ListValue; - name_servers->AppendStrings(dns_servers()); + name_servers->AppendStrings(dns_servers_); ipconfig_properties->SetWithoutPathExpansion(flimflam::kNameServersProperty, name_servers); dictionary->SetWithoutPathExpansion(shill::kIPConfigProperty, ipconfig_properties); dictionary->SetStringWithoutPathExpansion(flimflam::kActivationStateProperty, - activation_state()); + activation_state_); dictionary->SetStringWithoutPathExpansion(flimflam::kRoamingStateProperty, - roaming()); + roaming_); dictionary->SetStringWithoutPathExpansion(flimflam::kSecurityProperty, - security()); + security_); dictionary->SetBooleanWithoutPathExpansion(flimflam::kAutoConnectProperty, - auto_connect()); + auto_connect_); dictionary->SetBooleanWithoutPathExpansion(flimflam::kFavoriteProperty, - favorite()); + favorite_); dictionary->SetIntegerWithoutPathExpansion(flimflam::kPriorityProperty, - priority()); + priority_); dictionary->SetStringWithoutPathExpansion( flimflam::kNetworkTechnologyProperty, - technology()); + technology_); dictionary->SetStringWithoutPathExpansion(flimflam::kDeviceProperty, - device_path()); - dictionary->SetStringWithoutPathExpansion(flimflam::kGuidProperty, guid()); + device_path_); + dictionary->SetStringWithoutPathExpansion(flimflam::kGuidProperty, guid_); dictionary->SetStringWithoutPathExpansion(flimflam::kProfileProperty, - profile_path()); + profile_path_); dictionary->SetBooleanWithoutPathExpansion( shill::kActivateOverNonCellularNetworkProperty, - activate_over_non_cellular_networks()); + activate_over_non_cellular_networks_); dictionary->SetBooleanWithoutPathExpansion(shill::kOutOfCreditsProperty, - cellular_out_of_credits()); + cellular_out_of_credits_); } bool NetworkState::IsConnectedState() const { diff --git a/chromeos/network/network_state.h b/chromeos/network/network_state.h index 1e89638..d49c5d8 100644 --- a/chromeos/network/network_state.h +++ b/chromeos/network/network_state.h @@ -51,6 +51,9 @@ class CHROMEOS_EXPORT NetworkState : public ManagedState { int priority() const { return priority_; } // Wireless property accessors int signal_strength() const { return signal_strength_; } + bool connectable() const { return connectable_; } + // Wifi property accessors + bool passphrase_required() const { return passphrase_required_; } // Cellular property accessors const std::string& technology() const { return technology_; } const std::string& activation_state() const { return activation_state_; } @@ -103,9 +106,11 @@ class CHROMEOS_EXPORT NetworkState : public ManagedState { std::vector<std::string> dns_servers_; // Wireless properties int signal_strength_; + bool connectable_; // Wifi properties std::string hex_ssid_; std::string country_code_; + bool passphrase_required_; // Cellular properties std::string technology_; std::string activation_state_; diff --git a/chromeos/network/network_state_handler_unittest.cc b/chromeos/network/network_state_handler_unittest.cc index 23f9207..c5e7040 100644 --- a/chromeos/network/network_state_handler_unittest.cc +++ b/chromeos/network/network_state_handler_unittest.cc @@ -262,7 +262,7 @@ TEST_F(NetworkStateHandlerTest, TechnologyState) { TEST_F(NetworkStateHandlerTest, ServicePropertyChanged) { // Set a service property. - const std::string eth0 = "stub_ethernet"; + const std::string eth0 = kShillManagerClientStubDefaultService; EXPECT_EQ("", network_state_handler_->GetNetworkState(eth0)->security()); EXPECT_EQ(1, test_observer_->PropertyUpdatesForService(eth0)); base::StringValue security_value("TestSecurity"); @@ -280,7 +280,7 @@ TEST_F(NetworkStateHandlerTest, NetworkConnectionStateChanged) { // Change a network state. ShillServiceClient::TestInterface* service_test = DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface(); - const std::string eth0 = "stub_ethernet"; + const std::string eth0 = kShillManagerClientStubDefaultService; base::StringValue connection_state_idle_value(flimflam::kStateIdle); service_test->SetServiceProperty(eth0, flimflam::kStateProperty, connection_state_idle_value); @@ -304,11 +304,11 @@ TEST_F(NetworkStateHandlerTest, DefaultServiceChanged) { DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface(); ASSERT_TRUE(service_test); - // Change the default network by inserting wifi1 at the front of the list + // Change the default network by moving wifi1 to the front of the list // and changing the state of stub_ethernet to Idle. - const std::string wifi1 = "stub_wifi1"; - manager_test->AddServiceAtIndex(wifi1, 0, true); - const std::string eth0 = "stub_ethernet"; + const std::string wifi1 = kShillManagerClientStubDefaultWireless; + manager_test->MoveServiceToIndex(wifi1, 0, true); + const std::string eth0 = kShillManagerClientStubDefaultService; base::StringValue connection_state_idle_value(flimflam::kStateIdle); service_test->SetServiceProperty(eth0, flimflam::kStateProperty, connection_state_idle_value); diff --git a/chromeos/network/network_ui_data.cc b/chromeos/network/network_ui_data.cc index a80ee3e..2eeac35 100644 --- a/chromeos/network/network_ui_data.cc +++ b/chromeos/network/network_ui_data.cc @@ -218,7 +218,8 @@ void TranslateONCHierarchy(const onc::OncValueSignature& signature, } // namespace -scoped_ptr<NetworkUIData> CreateUIDataFromONC( +// static +scoped_ptr<NetworkUIData> NetworkUIData::CreateFromONC( onc::ONCSource onc_source, const base::DictionaryValue& onc_network) { scoped_ptr<NetworkUIData> ui_data(new NetworkUIData()); diff --git a/chromeos/network/network_ui_data.h b/chromeos/network/network_ui_data.h index b65987e..05abfbc 100644 --- a/chromeos/network/network_ui_data.h +++ b/chromeos/network/network_ui_data.h @@ -78,6 +78,14 @@ class CHROMEOS_EXPORT NetworkUIData { // keys appropriate for Network::ui_data() as defined below (kKeyXXX). void FillDictionary(base::DictionaryValue* dict) const; + // Creates a NetworkUIData object from |onc_network|, which has to be a valid + // ONC NetworkConfiguration dictionary. + // This function is used to create the "UIData" field of the Shill + // configuration. + static scoped_ptr<NetworkUIData> CreateFromONC( + onc::ONCSource onc_source, + const base::DictionaryValue& onc_network); + // Key for storing source of the ONC network. static const char kKeyONCSource[]; @@ -98,15 +106,6 @@ class CHROMEOS_EXPORT NetworkUIData { std::string policy_guid_; }; -// Creates a NetworkUIData object from |onc_network|, which has to be a valid -// ONC NetworkConfiguration dictionary. -// -// This function is used to create the "UIData" field of the Shill -// configuration. -CHROMEOS_EXPORT scoped_ptr<NetworkUIData> CreateUIDataFromONC( - onc::ONCSource onc_source, - const base::DictionaryValue& onc_network); - } // namespace chromeos #endif // CHROMEOS_NETWORK_NETWORK_UI_DATA_H_ diff --git a/chromeos/network/network_ui_data_unittest.cc b/chromeos/network/network_ui_data_unittest.cc index d1df65c..8333629 100644 --- a/chromeos/network/network_ui_data_unittest.cc +++ b/chromeos/network/network_ui_data_unittest.cc @@ -90,7 +90,8 @@ TEST_P(CreateUIDataTest, CreateUIDataFromONC) { test_utils::ReadTestDictionary(GetParam().second); scoped_ptr<NetworkUIData> actual_uidata = - CreateUIDataFromONC(onc::ONC_SOURCE_USER_POLICY, *onc_network); + NetworkUIData::CreateFromONC( + onc::ONC_SOURCE_USER_POLICY, *onc_network); EXPECT_TRUE(actual_uidata != NULL); base::DictionaryValue actual_uidata_dict; |