diff options
15 files changed, 678 insertions, 0 deletions
diff --git a/chrome/browser/chromeos/extensions/networking_private_api.cc b/chrome/browser/chromeos/extensions/networking_private_api.cc new file mode 100644 index 0000000..077619e --- /dev/null +++ b/chrome/browser/chromeos/extensions/networking_private_api.cc @@ -0,0 +1,303 @@ +// 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 "chrome/browser/chromeos/extensions/networking_private_api.h" + +#include "base/bind_helpers.h" +#include "chrome/browser/extensions/extension_function_registry.h" +#include "chrome/common/extensions/api/networking_private.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/onc/onc_constants.h" +#include "chromeos/network/onc/onc_signature.h" +#include "chromeos/network/onc/onc_translation_tables.h" +#include "chromeos/network/onc/onc_translator.h" +#include "dbus/object_path.h" +#include "third_party/cros_system_api/dbus/service_constants.h" + +using namespace chromeos; +namespace api = extensions::api::networking_private; + +namespace { + +// An error returned when no valid services were found. +const char kInvalidResponseError[] = "Error.invalidResponse"; + +// This creates a new ONC dictionary that only contains the information we're +// interested in passing on to JavaScript. +scoped_ptr<api::NetworkProperties> CreateFilteredResult( + const base::DictionaryValue& properties) { + scoped_ptr<base::DictionaryValue> onc_properties( + onc::TranslateShillServiceToONCPart( + properties, + &onc::kNetworkConfigurationSignature)); + + // Now we filter it so we only include properties that we care about for this + // interface. + static const char* const desired_fields[] = { + onc::network_config::kWiFi, + onc::network_config::kName, + onc::network_config::kGUID, + onc::network_config::kType, + onc::network_config::kConnectionState, + }; + + scoped_ptr<api::NetworkProperties> filtered_result( + new api::NetworkProperties); + for (size_t i = 0; i < arraysize(desired_fields); ++i) { + base::Value* value; + if (onc_properties->Get(desired_fields[i], &value)) + filtered_result->additional_properties.Set(desired_fields[i], + value->DeepCopy()); + } + + return filtered_result.Pass(); +} + +class ResultList : public base::RefCounted<ResultList> { + public: + typedef base::Callback<void(const std::string& error, + scoped_ptr<base::ListValue>)> ResultCallback; + + ResultList(const std::string& type, const ResultCallback& callback) + : callback_(callback) { + DBusThreadManager::Get()->GetShillManagerClient()->GetProperties( + base::Bind(&ResultList::ManagerPropertiesCallback, this, type)); + } + + scoped_ptr<base::ListValue> GetResults() { + return api::GetVisibleNetworks::Results::Create(list_); + } + + private: + friend class base::RefCounted<ResultList>; + + ~ResultList() { + callback_.Run(std::string(), GetResults()); + } + + void Append(api::NetworkProperties* value) { + list_.push_back(linked_ptr<api::NetworkProperties>(value)); + } + + // Receives the result of a call to GetProperties on the Shill Manager API. + void ManagerPropertiesCallback(const std::string& network_type, + chromeos::DBusMethodCallStatus call_status, + const base::DictionaryValue& result); + + // Receives the result of a call to GetProperties on the Shill Service API. + void ServicePropertiesCallback(const std::string& service_path, + const std::string& network_type, + chromeos::DBusMethodCallStatus call_status, + const base::DictionaryValue& result); + + std::vector<linked_ptr<api::NetworkProperties> > list_; + ResultCallback callback_; + + DISALLOW_COPY_AND_ASSIGN(ResultList); +}; + +// For each of the available services, fire off a request for its properties. +void ResultList::ManagerPropertiesCallback( + const std::string& network_type, + DBusMethodCallStatus call_status, + const base::DictionaryValue& result) { + const base::ListValue* available_services; + if (!result.GetList(flimflam::kServicesProperty, &available_services)) { + LOG(ERROR) + << "ShillManagerClient::GetProperties returned malformed service list."; + callback_.Run(kInvalidResponseError, make_scoped_ptr(new base::ListValue)); + return; + } + // If there just are no services, return an empty list. + if (available_services->GetSize() == 0) { + callback_.Run(std::string(), make_scoped_ptr(new base::ListValue)); + return; + } + for (base::ListValue::const_iterator iter = available_services->begin(); + iter != available_services->end(); ++iter) { + std::string service_path; + if (!(*iter)->GetAsString(&service_path)) { + LOG(ERROR) + << "ShillManagerClient::GetProperties returned malformed service."; + continue; + } + + DBusThreadManager::Get()->GetShillServiceClient()->GetProperties( + dbus::ObjectPath(service_path), + base::Bind( + &ResultList::ServicePropertiesCallback, + this, + service_path, + network_type)); + } +} + +void ResultList::ServicePropertiesCallback( + const std::string& service_path, + const std::string& network_type, + DBusMethodCallStatus call_status, + const base::DictionaryValue& result) { + if (call_status == DBUS_METHOD_CALL_SUCCESS) { + scoped_ptr<api::NetworkProperties> filtered_result( + CreateFilteredResult(result)); + + std::string onc_type; + if (filtered_result->additional_properties.GetString( + onc::network_config::kType, &onc_type) && + (onc_type == network_type || + network_type == onc::network_type::kAllTypes)) { + // TODO(gspencer): For now the "GUID" we send back is going to look + // remarkably like the service path. Once this code starts using the + // NetworkStateHandler instead of Shill directly, we should remove + // this line so that we're sending back the actual GUID. The + // JavaScript shouldn't care: this ID is opaque to it, and it + // shouldn't store it anywhere. + filtered_result->additional_properties.SetString( + onc::network_config::kGUID, service_path); + + Append(filtered_result.release()); + } + } +} + +} // namespace + +//////////////////////////////////////////////////////////////////////////////// +// NetworkingPrivateGetPropertiesFunction + +NetworkingPrivateGetPropertiesFunction:: + ~NetworkingPrivateGetPropertiesFunction() { +} + +bool NetworkingPrivateGetPropertiesFunction::RunImpl() { + scoped_ptr<api::GetProperties::Params> params = + api::GetProperties::Params::Create(*args_); + EXTENSION_FUNCTION_VALIDATE(params); + + // TODO(gspencer): Currently we're using the service path as the + // |network_guid|. Eventually this should be using the real GUID. + DBusThreadManager::Get()->GetShillServiceClient()->GetProperties( + dbus::ObjectPath(params->network_guid), + base::Bind(&NetworkingPrivateGetPropertiesFunction::ResultCallback, + this)); + return true; +} + +void NetworkingPrivateGetPropertiesFunction::ResultCallback( + DBusMethodCallStatus call_status, + const base::DictionaryValue& result) { + scoped_ptr<api::NetworkProperties> filtered_result( + CreateFilteredResult(result)); + results_ = api::GetProperties::Results::Create(*filtered_result); + SendResponse(true); +} + +//////////////////////////////////////////////////////////////////////////////// +// NetworkingPrivateGetVisibleNetworksFunction + +NetworkingPrivateGetVisibleNetworksFunction:: +~NetworkingPrivateGetVisibleNetworksFunction() { +} + +bool NetworkingPrivateGetVisibleNetworksFunction::RunImpl() { + scoped_ptr<api::GetVisibleNetworks::Params> params = + api::GetVisibleNetworks::Params::Create(*args_); + EXTENSION_FUNCTION_VALIDATE(params); + + scoped_refptr<ResultList> result_list(new ResultList( + api::GetVisibleNetworks::Params::ToString(params->type), + base::Bind( + &NetworkingPrivateGetVisibleNetworksFunction::SendResultCallback, + this))); + return true; +} + +void NetworkingPrivateGetVisibleNetworksFunction::SendResultCallback( + const std::string& error, + scoped_ptr<base::ListValue> result_list) { + if (!error.empty()) { + error_ = error; + SendResponse(false); + } else { + results_.reset(result_list.release()); + SendResponse(true); + } +} + +//////////////////////////////////////////////////////////////////////////////// +// NetworkingPrivateStartConnectFunction + +NetworkingPrivateStartConnectFunction:: + ~NetworkingPrivateStartConnectFunction() { +} + +void NetworkingPrivateStartConnectFunction::ConnectionStartSuccess() { + SendResponse(true); +} + +void NetworkingPrivateStartConnectFunction::ConnectionStartFailed( + const std::string& error_name, + const std::string& error_message) { + error_ = error_name; + SendResponse(false); +} + +bool NetworkingPrivateStartConnectFunction::RunImpl() { + scoped_ptr<api::StartConnect::Params> params = + api::StartConnect::Params::Create(*args_); + EXTENSION_FUNCTION_VALIDATE(params); + + // TODO(gspencer): For now, the "GUID" we receive from the JavaScript is going + // to be the service path. Fix this so it actually looks up the service path + // from the GUID once we're using the NetworkStateHandler. + std::string service_path = params->network_guid; + + DBusThreadManager::Get()->GetShillServiceClient()->Connect( + dbus::ObjectPath(service_path), + base::Bind( + &NetworkingPrivateStartConnectFunction::ConnectionStartSuccess, + this), + base::Bind(&NetworkingPrivateStartConnectFunction::ConnectionStartFailed, + this)); + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +// NetworkingPrivateStartDisconnectFunction + +NetworkingPrivateStartDisconnectFunction:: + ~NetworkingPrivateStartDisconnectFunction() { +} + +void NetworkingPrivateStartDisconnectFunction::DisconnectionStartSuccess() { + SendResponse(true); +} + +void NetworkingPrivateStartDisconnectFunction::DisconnectionStartFailed( + const std::string& error_name, + const std::string& error_message) { + error_ = error_name; + SendResponse(false); +} + +bool NetworkingPrivateStartDisconnectFunction::RunImpl() { + scoped_ptr<api::StartDisconnect::Params> params = + api::StartDisconnect::Params::Create(*args_); + EXTENSION_FUNCTION_VALIDATE(params); + + // TODO(gspencer): Currently the |network_guid| parameter is storing the + // service path. Convert to using the actual GUID when we start using + // the NetworkStateHandler. + DBusThreadManager::Get()->GetShillServiceClient()->Connect( + dbus::ObjectPath(params->network_guid), + base::Bind( + &NetworkingPrivateStartDisconnectFunction::DisconnectionStartSuccess, + this), + base::Bind( + &NetworkingPrivateStartDisconnectFunction::DisconnectionStartFailed, + this)); + return true; +} diff --git a/chrome/browser/chromeos/extensions/networking_private_api.h b/chrome/browser/chromeos/extensions/networking_private_api.h new file mode 100644 index 0000000..df4d567 --- /dev/null +++ b/chrome/browser/chromeos/extensions/networking_private_api.h @@ -0,0 +1,110 @@ +// 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. + +// These classes implement the chrome.networkingPrivate JavaScript extension +// API. + +#ifndef CHROME_BROWSER_CHROMEOS_EXTENSIONS_NETWORKING_PRIVATE_API_H_ +#define CHROME_BROWSER_CHROMEOS_EXTENSIONS_NETWORKING_PRIVATE_API_H_ + +#include <string> + +#include "base/memory/ref_counted.h" +#include "base/values.h" +#include "chrome/browser/extensions/extension_function.h" +#include "chrome/browser/profiles/profile_keyed_service.h" +#include "chromeos/dbus/dbus_method_call_status.h" + +// Implements the chrome.networkingPrivate.getProperties method. +class NetworkingPrivateGetPropertiesFunction : public AsyncExtensionFunction { + public: + NetworkingPrivateGetPropertiesFunction() {} + DECLARE_EXTENSION_FUNCTION("networkingPrivate.getProperties", + NETWORKINGPRIVATE_GETPROPERTIES); + + protected: + virtual ~NetworkingPrivateGetPropertiesFunction(); + + // AsyncExtensionFunction overrides. + virtual bool RunImpl() OVERRIDE; + + private: + void ResultCallback(chromeos::DBusMethodCallStatus call_status, + const base::DictionaryValue& result); + DISALLOW_COPY_AND_ASSIGN(NetworkingPrivateGetPropertiesFunction); +}; + +// Implements the chrome.networkingPrivate.getVisibleNetworks method. +class NetworkingPrivateGetVisibleNetworksFunction + : public AsyncExtensionFunction { + public: + NetworkingPrivateGetVisibleNetworksFunction() {} + DECLARE_EXTENSION_FUNCTION("networkingPrivate.getVisibleNetworks", + NETWORKINGPRIVATE_GETVISIBLENETWORKS); + + protected: + virtual ~NetworkingPrivateGetVisibleNetworksFunction(); + + // AsyncExtensionFunction overrides. + virtual bool RunImpl() OVERRIDE; + + // Gets called when all the results are in. + void SendResultCallback(const std::string& error, + scoped_ptr<base::ListValue> result_list); + + private: + + DISALLOW_COPY_AND_ASSIGN(NetworkingPrivateGetVisibleNetworksFunction); +}; + +// Implements the chrome.networkingPrivate.startConnect method. +class NetworkingPrivateStartConnectFunction : public AsyncExtensionFunction { + public: + NetworkingPrivateStartConnectFunction() {} + DECLARE_EXTENSION_FUNCTION("networkingPrivate.startConnect", + NETWORKINGPRIVATE_STARTCONNECT); + + protected: + virtual ~NetworkingPrivateStartConnectFunction(); + + // AsyncExtensionFunction overrides. + virtual bool RunImpl() OVERRIDE; + + private: + // Called when the request to connect succeeds. Doesn't mean that the connect + // itself succeeded, just that the request did. + void ConnectionStartSuccess(); + + void ConnectionStartFailed(const std::string& error_name, + const std::string& error_message); + + DISALLOW_COPY_AND_ASSIGN(NetworkingPrivateStartConnectFunction); +}; + +// Implements the chrome.networkingPrivate.startDisconnect method. +class NetworkingPrivateStartDisconnectFunction + : public AsyncExtensionFunction { + public: + NetworkingPrivateStartDisconnectFunction() {} + DECLARE_EXTENSION_FUNCTION("networkingPrivate.startDisconnect", + NETWORKINGPRIVATE_STARTDISCONNECT); + + protected: + virtual ~NetworkingPrivateStartDisconnectFunction(); + + // AsyncExtensionFunction overrides. + virtual bool RunImpl() OVERRIDE; + + private: + // Called when the request to disconnect succeeds. Doesn't mean that the + // disconnect itself succeeded, just that the request did. + void DisconnectionStartSuccess(); + + void DisconnectionStartFailed(const std::string& error_name, + const std::string& error_message); + + DISALLOW_COPY_AND_ASSIGN(NetworkingPrivateStartDisconnectFunction); +}; + +#endif // CHROME_BROWSER_CHROMEOS_EXTENSIONS_NETWORKING_PRIVATE_API_H_ diff --git a/chrome/browser/chromeos/extensions/networking_private_apitest.cc b/chrome/browser/chromeos/extensions/networking_private_apitest.cc new file mode 100644 index 0000000..d911ff9 --- /dev/null +++ b/chrome/browser/chromeos/extensions/networking_private_apitest.cc @@ -0,0 +1,28 @@ +// 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 <stdio.h> + +#include "base/stl_util.h" +#include "chrome/browser/extensions/extension_apitest.h" +#include "chrome/common/chrome_switches.h" +#include "chrome/test/base/ui_test_utils.h" + +namespace chromeos { + +class ExtensionNetworkingPrivateApiTest : public ExtensionApiTest { + public: + // Whitelist the extension ID of the test extension. + virtual void SetUpCommandLine(CommandLine* command_line) { + ExtensionApiTest::SetUpCommandLine(command_line); + command_line->AppendSwitchASCII( + switches::kWhitelistedExtensionID, "epcifkihnkjgphfkloaaleeakhpmgdmn"); + } +}; + +IN_PROC_BROWSER_TEST_F(ExtensionNetworkingPrivateApiTest, BasicFunctions) { + ASSERT_TRUE(RunComponentExtensionTest("networking")) << message_; +} + +} // namespace chromeos diff --git a/chrome/browser/extensions/extension_function_histogram_value.h b/chrome/browser/extensions/extension_function_histogram_value.h index 76f0f92..831aabd 100644 --- a/chrome/browser/extensions/extension_function_histogram_value.h +++ b/chrome/browser/extensions/extension_function_histogram_value.h @@ -466,6 +466,10 @@ enum HistogramValue { FILEBROWSERPRIVATE_VALIDATEPATHNAMELENGTH, BROWSINGDATA_SETTINGS, WEBSTOREPRIVATE_GETISLAUNCHERENABLED, + NETWORKINGPRIVATE_GETPROPERTIES, + NETWORKINGPRIVATE_GETVISIBLENETWORKS, + NETWORKINGPRIVATE_STARTCONNECT, + NETWORKINGPRIVATE_STARTDISCONNECT, ENUM_BOUNDARY // Last entry: Add new entries above. }; diff --git a/chrome/chrome_browser_chromeos.gypi b/chrome/chrome_browser_chromeos.gypi index 90f6dfa..7667702 100644 --- a/chrome/chrome_browser_chromeos.gypi +++ b/chrome/chrome_browser_chromeos.gypi @@ -681,6 +681,8 @@ 'browser/chromeos/extensions/input_method_api.h', 'browser/chromeos/extensions/media_player_api.cc', 'browser/chromeos/extensions/media_player_api.h', + 'browser/chromeos/extensions/networking_private_api.cc', + 'browser/chromeos/extensions/networking_private_api.h', 'browser/chromeos/extensions/wallpaper_manager_util.cc', 'browser/chromeos/extensions/wallpaper_manager_util.h', 'browser/chromeos/extensions/wallpaper_private_api.cc', diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index 3c77ec9..932371f 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -995,6 +995,7 @@ 'browser/chromeos/extensions/file_browser_resource_throttle_browsertest.cc', 'browser/chromeos/extensions/info_private_apitest.cc', 'browser/chromeos/extensions/input_method_apitest_chromeos.cc', + 'browser/chromeos/extensions/networking_private_apitest.cc', 'browser/chromeos/extensions/power/power_api_browsertest.cc', 'browser/chromeos/extensions/wallpaper_private_apitest.cc', 'browser/chromeos/kiosk_mode/mock_kiosk_mode_settings.cc', diff --git a/chrome/common/extensions/api/_permission_features.json b/chrome/common/extensions/api/_permission_features.json index 3a48fe7..2bc79bd 100644 --- a/chrome/common/extensions/api/_permission_features.json +++ b/chrome/common/extensions/api/_permission_features.json @@ -252,6 +252,11 @@ "ionpfmkccalenbmnddpbmocokhaknphg" // Quickoffice dev ] }, + "networkingPrivate": { + "channel": "dev", + "extension_types": ["extension", "packaged_app"], + "location": "component" + }, "notifications": { "channel": "stable", "extension_types": [ diff --git a/chrome/common/extensions/api/api.gyp b/chrome/common/extensions/api/api.gyp index 3215b1b..a2c7457 100644 --- a/chrome/common/extensions/api/api.gyp +++ b/chrome/common/extensions/api/api.gyp @@ -54,6 +54,7 @@ 'management.json', 'media_galleries.idl', 'media_galleries_private.idl', + 'networking_private.json', 'page_capture.json', 'permissions.json', 'push_messaging.idl', diff --git a/chrome/common/extensions/api/networking_private.json b/chrome/common/extensions/api/networking_private.json new file mode 100644 index 0000000..a567709 --- /dev/null +++ b/chrome/common/extensions/api/networking_private.json @@ -0,0 +1,104 @@ +// 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. + +[ + { + "namespace":"networkingPrivate", + "compiler_options": { + "implemented_in": "chrome/browser/chromeos/extensions/networking_private_api.h" + }, + "platforms": ["chromeos"], + "types" : [ + { + "id": "NetworkProperties", + "type": "object", + "additionalProperties": { "type": "any" } + } + ], + "functions": [ + { + "name": "getProperties", + "description": "Gets the properties of the network with id networkGuid.", + "parameters": [ + { + "name": "networkGuid", + "type": "string", + "description": "The unique identifier of the network to get properties from." + }, + { + "name": "callback", + "type": "function", + "parameters": [ + { + "name": "properties", + "$ref": "NetworkProperties", + "description": "Results of the query for network properties." + } + ] + } + ] + }, + { + "name": "getVisibleNetworks", + "description": "Gets the list of visible networks.", + "parameters": [ + { + "name": "type", + "type": "string", + "enum": ["Ethernet", "WiFi", "Bluetooth", "Cellular", "VPN", "All"], + "description": "The type of networks to return." + }, + { + "name": "callback", + "type": "function", + "optional": true, + "parameters": [ + { + "name": "networkList", + "type": "array", + "items": { "$ref": "NetworkProperties" } + } + ] + } + ] + }, + { + "name": "startConnect", + "description": "Starts a connection to the network with networkGuid.", + "parameters": [ + { + "name": "networkGuid", + "type": "string", + "description": "The unique identifier of the network to connect to." + }, + { + "name": "callback", + "type": "function", + "optional": true, + "parameters": [], + "description": "A callback function that indicates that a connection has been initiated." + } + ] + }, + { + "name": "startDisconnect", + "description": "Starts a disconnect from the network with networkGuid.", + "parameters": [ + { + "name": "networkGuid", + "type": "string", + "description": "The unique identifier of the network to disconnect from." + }, + { + "name": "callback", + "type": "function", + "optional": true, + "parameters": [], + "description": "A callback function that indicates that a disconnect has been initiated." + } + ] + } + ] + } +] diff --git a/chrome/common/extensions/permissions/api_permission.cc b/chrome/common/extensions/permissions/api_permission.cc index d5ca037..22ac180 100644 --- a/chrome/common/extensions/permissions/api_permission.cc +++ b/chrome/common/extensions/permissions/api_permission.cc @@ -256,6 +256,8 @@ void APIPermissionInfo::RegisterAllPermissions( kFlagCannotBeOptional }, { APIPermission::kFileBrowserPrivate, "fileBrowserPrivate", kFlagCannotBeOptional }, + { APIPermission::kNetworkingPrivate, "networkingPrivate", + kFlagCannotBeOptional }, { APIPermission::kManagedModePrivate, "managedModePrivate", kFlagCannotBeOptional }, { APIPermission::kMediaPlayerPrivate, "mediaPlayerPrivate", diff --git a/chrome/common/extensions/permissions/api_permission.h b/chrome/common/extensions/permissions/api_permission.h index 3336de7..f0cc58c 100644 --- a/chrome/common/extensions/permissions/api_permission.h +++ b/chrome/common/extensions/permissions/api_permission.h @@ -86,6 +86,7 @@ class APIPermission { kMediaGalleriesPrivate, kMediaPlayerPrivate, kMetricsPrivate, + kNetworkingPrivate, kNotification, kPageCapture, kPointerLock, diff --git a/chrome/common/extensions/permissions/permission_set_unittest.cc b/chrome/common/extensions/permissions/permission_set_unittest.cc index 77fe843..836f090 100644 --- a/chrome/common/extensions/permissions/permission_set_unittest.cc +++ b/chrome/common/extensions/permissions/permission_set_unittest.cc @@ -721,6 +721,7 @@ TEST(PermissionsTest, PermissionMessages) { skip.insert(APIPermission::kMediaGalleriesPrivate); skip.insert(APIPermission::kMediaPlayerPrivate); skip.insert(APIPermission::kMetricsPrivate); + skip.insert(APIPermission::kNetworkingPrivate); skip.insert(APIPermission::kRtcPrivate); skip.insert(APIPermission::kSystemPrivate); skip.insert(APIPermission::kTerminalPrivate); diff --git a/chrome/test/data/extensions/api_test/networking/manifest.json b/chrome/test/data/extensions/api_test/networking/manifest.json new file mode 100644 index 0000000..0847c01 --- /dev/null +++ b/chrome/test/data/extensions/api_test/networking/manifest.json @@ -0,0 +1,13 @@ +{ + "key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC74Vbx3EbhPc/FOvn6+HxCjMSml0HdPMiuRjj5a3b+MnRML1iJ9OAgbKUYJ/u3s25/cGq8pNB0NbyupHGEqvqAE7TcNr1mdgs0PWxh2IOI1GKrxlzxpqzQuFmxq5WHKr5RrwZ4/Xq0t/+e8JkvhZdW0jarz/28Jom0gkM5lorsewIDAQAB", + "name": "ChromeOS networking private extension API test", + "version": "0.1", + "manifest_version": 2, + "description": "Test of chrome.networkingPrivate methods", + "background": { + "scripts": ["test.js"] + }, + "permissions": [ + "networkingPrivate" + ] +} diff --git a/chrome/test/data/extensions/api_test/networking/test.js b/chrome/test/data/extensions/api_test/networking/test.js new file mode 100644 index 0000000..5503ced --- /dev/null +++ b/chrome/test/data/extensions/api_test/networking/test.js @@ -0,0 +1,98 @@ +// 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. + +var callbackPass = chrome.test.callbackPass; +var callbackFail = chrome.test.callbackFail; +var assertTrue = chrome.test.assertTrue; +var assertEq = chrome.test.assertEq; + +chrome.test.runTests([ + function getVisibleNetworks() { + chrome.networkingPrivate.getVisibleNetworks( + "All", + callbackPass(function(result) { + assertTrue(!!result); + assertEq(4, result.length); + assertEq([{ "Name": "eth0", + "GUID": "stub_ethernet", + "ConnectionState": "Connected", + "Type": "Ethernet" + }, + { "Name": "wifi1", + "GUID": "stub_wifi1", + "ConnectionState": "Connected", + "Type": "WiFi", + "WiFi": { + "SSID": "stub_wifi1", + "Type": "WiFi" + } + }, + { "Name": "wifi2_PSK", + "GUID": "stub_wifi2", + "ConnectionState": "NotConnected", + "Type": "WiFi", + "WiFi": { + "SSID": "stub_wifi2", + "Type": "WiFi" + } + }, + { "Name": "cellular1", + "GUID": "stub_cellular1", + "ConnectionState": "NotConnected", + "Type": "Cellular" + }], result); + })); + }, + function getVisibleNetworksWifi() { + chrome.networkingPrivate.getVisibleNetworks( + "WiFi", + callbackPass(function(result) { + assertTrue(!!result); + assertEq(2, result.length); + assertEq([{ "Name": "wifi1", + "GUID": "stub_wifi1", + "ConnectionState": "Connected", + "Type": "WiFi", + "WiFi": { + "SSID": "stub_wifi1", + "Type":"WiFi" + } + }, + { "Name": "wifi2_PSK", + "GUID": "stub_wifi2", + "ConnectionState": "NotConnected", + "Type": "WiFi", + "WiFi": { + "SSID": "stub_wifi2", + "Type": "WiFi" + } + }], result); + })); + }, + function getProperties() { + chrome.networkingPrivate.getProperties( + "stub_wifi2", + callbackPass(function(result) { + assertTrue(!!result); + assertEq("wifi2_PSK", result.Name); + assertEq("NotConnected", result.ConnectionState); + assertEq("WiFi", result.Type); + })); + }, + function startConnect() { + chrome.networkingPrivate.startConnect("stub_wifi2", + callbackPass(function() {})); + }, + function startDisconnect() { + chrome.networkingPrivate.startDisconnect("stub_wifi2", + callbackPass(function() {})); + }, + function startConnectNonexistent() { + // Make sure we get an error when we try to connect to a nonexistent + // network. + chrome.networkingPrivate.startConnect( + "nonexistent_path", + callbackFail("Error.InvalidService", function() {})); + } +]); diff --git a/chromeos/dbus/shill_service_client.cc b/chromeos/dbus/shill_service_client.cc index 16d7767..8e0ede0 100644 --- a/chromeos/dbus/shill_service_client.cc +++ b/chromeos/dbus/shill_service_client.cc @@ -312,6 +312,11 @@ class ShillServiceClientStubImpl : public ShillServiceClient, virtual void Connect(const dbus::ObjectPath& service_path, const base::Closure& callback, const ErrorCallback& error_callback) OVERRIDE { + base::Value* service; + if (!stub_services_.Get(service_path.value(), &service)) { + error_callback.Run("Error.InvalidService", "Invalid Service"); + return; + } // Set Associating base::StringValue associating_value(flimflam::kStateAssociation); SetServiceProperty(service_path.value(), |