summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorstevenjb@chromium.org <stevenjb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-14 04:37:56 +0000
committerstevenjb@chromium.org <stevenjb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-14 04:37:56 +0000
commit534190554ff15076010b53f879e8c17dc0ccb8b8 (patch)
tree68ff6b92205ddc09ef62a18c947eaeedf994f00d
parent9c48757cc3a705f6bb635747333dd3baccc48019 (diff)
downloadchromium_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
-rw-r--r--ash/system/chromeos/network/network_state_list_detailed_view.cc31
-rw-r--r--ash/system/chromeos/network/network_state_list_detailed_view.h5
-rw-r--r--chrome/browser/chromeos/chrome_browser_main_chromeos.cc3
-rw-r--r--chrome/browser/chromeos/cros/network_library.cc6
-rw-r--r--chrome/browser/chromeos/cros/network_library_impl_base.cc2
-rw-r--r--chrome/browser/chromeos/extensions/networking_private_api.cc5
-rw-r--r--chrome/chrome_browser_chromeos.gypi2
-rw-r--r--chrome/test/data/extensions/api_test/networking/test.js12
-rw-r--r--chromeos/chromeos.gyp5
-rw-r--r--chromeos/dbus/shill_manager_client.h19
-rw-r--r--chromeos/dbus/shill_manager_client_stub.cc135
-rw-r--r--chromeos/dbus/shill_manager_client_stub.h21
-rw-r--r--chromeos/dbus/shill_service_client_stub.cc37
-rw-r--r--chromeos/dbus/shill_service_client_stub.h3
-rw-r--r--chromeos/network/cert_loader.cc39
-rw-r--r--chromeos/network/cert_loader.h2
-rw-r--r--chromeos/network/certificate_pattern_matcher.cc (renamed from chrome/browser/chromeos/cros/certificate_pattern_matcher.cc)6
-rw-r--r--chromeos/network/certificate_pattern_matcher.h (renamed from chrome/browser/chromeos/cros/certificate_pattern_matcher.h)13
-rw-r--r--chromeos/network/managed_network_configuration_handler.cc61
-rw-r--r--chromeos/network/managed_network_configuration_handler.h21
-rw-r--r--chromeos/network/network_configuration_handler.cc22
-rw-r--r--chromeos/network/network_configuration_handler.h13
-rw-r--r--chromeos/network/network_configuration_handler_unittest.cc42
-rw-r--r--chromeos/network/network_connection_handler.cc309
-rw-r--r--chromeos/network/network_connection_handler.h141
-rw-r--r--chromeos/network/network_connection_handler_unittest.cc210
-rw-r--r--chromeos/network/network_handler_callbacks.h2
-rw-r--r--chromeos/network/network_state.cc44
-rw-r--r--chromeos/network/network_state.h5
-rw-r--r--chromeos/network/network_state_handler_unittest.cc12
-rw-r--r--chromeos/network/network_ui_data.cc3
-rw-r--r--chromeos/network/network_ui_data.h17
-rw-r--r--chromeos/network/network_ui_data_unittest.cc3
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;