diff options
32 files changed, 1834 insertions, 295 deletions
diff --git a/chrome/browser/extensions/api/networking_private/DEPS b/chrome/browser/extensions/api/networking_private/DEPS index 273d26b..e979e2a 100644 --- a/chrome/browser/extensions/api/networking_private/DEPS +++ b/chrome/browser/extensions/api/networking_private/DEPS @@ -1,3 +1,4 @@ include_rules = [ "+components/onc", + "+components/wifi", ] diff --git a/chrome/browser/extensions/api/networking_private/networking_private_api.h b/chrome/browser/extensions/api/networking_private/networking_private_api.h index 2abe33e..b5a23882 100644 --- a/chrome/browser/extensions/api/networking_private/networking_private_api.h +++ b/chrome/browser/extensions/api/networking_private/networking_private_api.h @@ -123,7 +123,7 @@ class NetworkingPrivateCreateNetworkFunction // Implements the chrome.networkingPrivate.getVisibleNetworks method. class NetworkingPrivateGetVisibleNetworksFunction - : public ChromeSyncExtensionFunction { + : public ChromeAsyncExtensionFunction { public: NetworkingPrivateGetVisibleNetworksFunction() {} DECLARE_EXTENSION_FUNCTION("networkingPrivate.getVisibleNetworks", @@ -132,10 +132,12 @@ class NetworkingPrivateGetVisibleNetworksFunction protected: virtual ~NetworkingPrivateGetVisibleNetworksFunction(); - // SyncExtensionFunction overrides. + // AsyncExtensionFunction overrides. virtual bool RunImpl() OVERRIDE; private: + void ResultCallback(const base::ListValue& network_list); + DISALLOW_COPY_AND_ASSIGN(NetworkingPrivateGetVisibleNetworksFunction); }; diff --git a/chrome/browser/extensions/api/networking_private/networking_private_api_chromeos.cc b/chrome/browser/extensions/api/networking_private/networking_private_api_chromeos.cc index 82633a5..3742a09 100644 --- a/chrome/browser/extensions/api/networking_private/networking_private_api_chromeos.cc +++ b/chrome/browser/extensions/api/networking_private/networking_private_api_chromeos.cc @@ -303,6 +303,7 @@ bool NetworkingPrivateGetVisibleNetworksFunction::RunImpl() { } SetResult(network_properties_list); + SendResponse(true); return true; } diff --git a/chrome/browser/extensions/api/networking_private/networking_private_api_nonchromeos.cc b/chrome/browser/extensions/api/networking_private/networking_private_api_nonchromeos.cc index 4c717e5..f2930bd 100644 --- a/chrome/browser/extensions/api/networking_private/networking_private_api_nonchromeos.cc +++ b/chrome/browser/extensions/api/networking_private/networking_private_api_nonchromeos.cc @@ -10,29 +10,22 @@ #include "base/command_line.h" #include "base/json/json_reader.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/extensions/api/networking_private/networking_private_service_client.h" +#include "chrome/browser/extensions/api/networking_private/networking_private_service_client_factory.h" #include "chrome/browser/extensions/extension_function_registry.h" #include "chrome/browser/extensions/extension_system.h" -#include "chrome/browser/profiles/profile.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/extensions/api/networking_private.h" +#include "components/onc/onc_constants.h" #include "extensions/browser/event_router.h" -using extensions::EventRouter; -using extensions::ExtensionSystem; +using extensions::NetworkingPrivateServiceClient; +using extensions::NetworkingPrivateServiceClientFactory; namespace api = extensions::api::networking_private; //////////////////////////////////////////////////////////////////////////////// // NetworkingPrivateGetPropertiesFunction - -const char kNetworkingPrivateProperties[] = "NetworkingPrivateProperties"; - -struct NetworkingPrivatePropertiesData : base::SupportsUserData::Data { - explicit NetworkingPrivatePropertiesData(const base::DictionaryValue* prop) : - properties_(prop->DeepCopy()) { } - scoped_ptr<base::DictionaryValue> properties_; -}; - NetworkingPrivateGetPropertiesFunction:: ~NetworkingPrivateGetPropertiesFunction() { } @@ -42,38 +35,32 @@ bool NetworkingPrivateGetPropertiesFunction::RunImpl() { api::GetProperties::Params::Create(*args_); EXTENSION_FUNCTION_VALIDATE(params); - // If there are properties set by SetProperties function, use those. - NetworkingPrivatePropertiesData* stored_properties = - static_cast<NetworkingPrivatePropertiesData*>( - GetProfile()->GetUserData(kNetworkingPrivateProperties)); - if (stored_properties != NULL) { - SetResult(stored_properties->properties_.release()); - SendResponse(true); - return true; - } + NetworkingPrivateServiceClient* process_client = + NetworkingPrivateServiceClientFactory::GetForProfile(GetProfile()); - const std::string network_properties = - "{\"ConnectionState\":\"NotConnected\"," - "\"GUID\":\"stub_wifi2\"," - "\"Name\":\"wifi2_PSK\"," - "\"Type\":\"WiFi\"," - "\"WiFi\":{" - "\"Frequency\":5000," - "\"FrequencyList\":[2400,5000]," - "\"SSID\":\"wifi2_PSK\"," - "\"Security\":\"WPA-PSK\"," - "\"SignalStrength\":80}}"; - - if (params->network_guid == "nonexistent_path") { - error_ = "Error.DBusFailed"; - SendResponse(false); - } else { - SetResult(base::JSONReader::Read(network_properties)); - SendResponse(true); - } + process_client->GetProperties( + params->network_guid, + base::Bind(&NetworkingPrivateGetPropertiesFunction::GetPropertiesSuccess, + this), + base::Bind(&NetworkingPrivateGetPropertiesFunction::GetPropertiesFailed, + this)); return true; } +void NetworkingPrivateGetPropertiesFunction::GetPropertiesSuccess( + const std::string& network_guid, + const base::DictionaryValue& dictionary) { + SetResult(dictionary.DeepCopy()); + SendResponse(true); +} + +void NetworkingPrivateGetPropertiesFunction::GetPropertiesFailed( + const std::string& error_name, + scoped_ptr<base::DictionaryValue> error_data) { + error_ = error_name; + SendResponse(false); +} + //////////////////////////////////////////////////////////////////////////////// // NetworkingPrivateGetManagedPropertiesFunction @@ -184,14 +171,28 @@ bool NetworkingPrivateSetPropertiesFunction::RunImpl() { scoped_ptr<base::DictionaryValue> properties_dict( params->properties.ToValue()); - // Store properties_dict in profile to return from GetProperties. - GetProfile()->SetUserData( - kNetworkingPrivateProperties, - new NetworkingPrivatePropertiesData(properties_dict.get())); - SendResponse(true); + NetworkingPrivateServiceClient* process_client = + NetworkingPrivateServiceClientFactory::GetForProfile(GetProfile()); + + process_client->SetProperties( + params->network_guid, + *properties_dict, + base::Bind(&NetworkingPrivateSetPropertiesFunction::ResultCallback, this), + base::Bind(&NetworkingPrivateSetPropertiesFunction::ErrorCallback, this)); return true; } +void NetworkingPrivateSetPropertiesFunction::ResultCallback() { + SendResponse(true); +} + +void NetworkingPrivateSetPropertiesFunction::ErrorCallback( + const std::string& error_name, + const scoped_ptr<base::DictionaryValue> error_data) { + error_ = error_name; + SendResponse(false); +} + //////////////////////////////////////////////////////////////////////////////// // NetworkingPrivateCreateNetworkFunction @@ -204,14 +205,6 @@ bool NetworkingPrivateCreateNetworkFunction::RunImpl() { api::CreateNetwork::Params::Create(*args_); EXTENSION_FUNCTION_VALIDATE(params); - // Store properties_dict in profile to return from GetProperties. - scoped_ptr<base::DictionaryValue> properties_dict( - params->properties.ToValue()); - properties_dict->SetString("GUID", "fake_guid"); - GetProfile()->SetUserData( - kNetworkingPrivateProperties, - new NetworkingPrivatePropertiesData(properties_dict.get())); - results_ = api::CreateNetwork::Results::Create("fake_guid"); SendResponse(true); return true; @@ -228,66 +221,46 @@ bool NetworkingPrivateGetVisibleNetworksFunction::RunImpl() { scoped_ptr<api::GetVisibleNetworks::Params> params = api::GetVisibleNetworks::Params::Create(*args_); EXTENSION_FUNCTION_VALIDATE(params); - const std::string networks_json = - "[{" - " \"ConnectionState\": \"Connected\"," - " \"GUID\": \"stub_ethernet\"," - " \"Name\": \"eth0\"," - " \"Type\": \"Ethernet\"," - " \"Ethernet\": {" - " \"Authentication\": \"None\"" - " }" - " }," - " {" - " \"ConnectionState\": \"Connected\"," - " \"GUID\": \"stub_wifi1\"," - " \"Name\": \"wifi1\"," - " \"Type\": \"WiFi\"," - " \"WiFi\": {" - " \"Security\": \"WEP-PSK\"," - " \"SignalStrength\": 0" - " }" - " }," - " {" - " \"ConnectionState\": \"Connected\"," - " \"GUID\": \"stub_vpn1\"," - " \"Name\": \"vpn1\"," - " \"Type\": \"VPN\"" - " }," - " {" - " \"ConnectionState\": \"NotConnected\"," - " \"GUID\": \"stub_wifi2\"," - " \"Name\": \"wifi2_PSK\"," - " \"Type\": \"WiFi\"," - " \"WiFi\": {" - " \"Security\": \"WPA-PSK\"," - " \"SignalStrength\": 80" - " }" - " }," - " {" - " \"Cellular\": {" - " \"ActivateOverNonCellularNetwork\": false," - " \"ActivationState\": \"not-activated\"," - " \"NetworkTechnology\": \"GSM\"," - " \"RoamingState\": \"home\"" - " }," - " \"ConnectionState\": \"NotConnected\"," - " \"GUID\": \"stub_cellular1\"," - " \"Name\": \"cellular1\"," - " \"Type\": \"Cellular\"" - " }]"; - ListValue* visible_networks = - static_cast<ListValue*>(base::JSONReader::Read(networks_json)); - // If caller only needs WiFi networks, then remove all other networks. - if (params->type == api::GetVisibleNetworks::Params::TYPE_WIFI) { - visible_networks->Remove(4, NULL); - visible_networks->Remove(2, NULL); - visible_networks->Remove(0, NULL); + + NetworkingPrivateServiceClient* process_client = + NetworkingPrivateServiceClientFactory::GetForProfile(GetProfile()); + + process_client->GetVisibleNetworks(base::Bind( + &NetworkingPrivateGetVisibleNetworksFunction::ResultCallback, this)); + + return true; +} + +void NetworkingPrivateGetVisibleNetworksFunction::ResultCallback( + const base::ListValue& network_list) { + scoped_ptr<api::GetVisibleNetworks::Params> params = + api::GetVisibleNetworks::Params::Create(*args_); + ListValue* result = new ListValue(); + std::string params_type = + api::GetVisibleNetworks::Params::ToString(params->type); + bool request_all = params->type == api::GetVisibleNetworks::Params::TYPE_ALL; + + // Copy networks of requested type; + for (base::ListValue::const_iterator it = network_list.begin(); + it != network_list.end(); + ++it) { + const base::Value* network_value = *it; + const DictionaryValue* network_dict = NULL; + if (!network_value->GetAsDictionary(&network_dict)) { + LOG(ERROR) << "Value is not a dictionary"; + continue; + } + if (!request_all) { + std::string network_type; + network_dict->GetString(onc::network_config::kType, &network_type); + if (network_type != params_type) + continue; + } + result->Append(network_value->DeepCopy()); } - SetResult(visible_networks); + SetResult(result); SendResponse(true); - return true; } //////////////////////////////////////////////////////////////////////////////// @@ -344,21 +317,9 @@ NetworkingPrivateRequestNetworkScanFunction:: } bool NetworkingPrivateRequestNetworkScanFunction::RunImpl() { - // Generate onNetworkListChanged event. - std::vector<std::string> changes; - changes.push_back("stub_ethernet"); - changes.push_back("stub_wifi1"); - changes.push_back("stub_vpn1"); - changes.push_back("stub_wifi2"); - changes.push_back("stub_cellular1"); - - EventRouter* event_router = - ExtensionSystem::Get(GetProfile())->event_router(); - scoped_ptr<base::ListValue> args(api::OnNetworkListChanged::Create(changes)); - scoped_ptr<extensions::Event> extension_event(new extensions::Event( - api::OnNetworkListChanged::kEventName, args.Pass())); - event_router->BroadcastEvent(extension_event.Pass()); - + NetworkingPrivateServiceClient* process_client = + NetworkingPrivateServiceClientFactory::GetForProfile(GetProfile()); + process_client->RequestNetworkScan(); return true; } @@ -373,55 +334,28 @@ bool NetworkingPrivateStartConnectFunction::RunImpl() { scoped_ptr<api::StartConnect::Params> params = api::StartConnect::Params::Create(*args_); EXTENSION_FUNCTION_VALIDATE(params); - if (params->network_guid == "nonexistent_path") { - error_ = "configure-failed"; - SendResponse(false); - } else { - SendResponse(true); - // Set Properties to reflect connected state - const std::string network_properties = - "{\"ConnectionState\":\"Connected\"," - "\"GUID\":\"stub_wifi2\"," - "\"Name\":\"wifi2_PSK\"," - "\"Type\":\"WiFi\"," - "\"WiFi\":{" - "\"SSID\":\"stub_wifi2\"," - "\"Security\":\"WPA-PSK\"," - "\"SignalStrength\":80}}"; - - // Store network_properties in profile to return from GetProperties. - scoped_ptr<Value> network_properties_value( - base::JSONReader::Read(network_properties)); - GetProfile()->SetUserData( - kNetworkingPrivateProperties, - new NetworkingPrivatePropertiesData( - static_cast<DictionaryValue*>(network_properties_value.get()))); - - // Broadcast NetworksChanged Event that network is connected - EventRouter* event_router = - ExtensionSystem::Get(GetProfile())->event_router(); - scoped_ptr<base::ListValue> args(api::OnNetworksChanged::Create( - std::vector<std::string>(1, params->network_guid))); - scoped_ptr<extensions::Event> netchanged_event( - new extensions::Event(api::OnNetworksChanged::kEventName, args.Pass())); - event_router->BroadcastEvent(netchanged_event.Pass()); - - // Generate NetworkListChanged event. - std::vector<std::string> list; - list.push_back("stub_ethernet"); - list.push_back("stub_wifi2"); - list.push_back("stub_vpn1"); - list.push_back("stub_wifi1"); - list.push_back("stub_cellular1"); - - scoped_ptr<base::ListValue> arg2(api::OnNetworkListChanged::Create(list)); - scoped_ptr<extensions::Event> netlist_event(new extensions::Event( - api::OnNetworkListChanged::kEventName, arg2.Pass())); - event_router->BroadcastEvent(netlist_event.Pass()); - } + NetworkingPrivateServiceClient* process_client = + NetworkingPrivateServiceClientFactory::GetForProfile(GetProfile()); + process_client->StartConnect( + params->network_guid, + base::Bind(&NetworkingPrivateStartConnectFunction::ConnectionStartSuccess, + this), + base::Bind(&NetworkingPrivateStartConnectFunction::ConnectionStartFailed, + this)); return true; } +void NetworkingPrivateStartConnectFunction::ConnectionStartSuccess() { + SendResponse(true); +} + +void NetworkingPrivateStartConnectFunction::ConnectionStartFailed( + const std::string& error_name, + const scoped_ptr<base::DictionaryValue> error_data) { + error_ = error_name; + SendResponse(false); +} + //////////////////////////////////////////////////////////////////////////////// // NetworkingPrivateStartDisconnectFunction @@ -433,40 +367,64 @@ bool NetworkingPrivateStartDisconnectFunction::RunImpl() { scoped_ptr<api::StartDisconnect::Params> params = api::StartDisconnect::Params::Create(*args_); EXTENSION_FUNCTION_VALIDATE(params); - if (params->network_guid == "nonexistent_path") { - error_ = "not-found"; - SendResponse(false); - } else { - SendResponse(true); - - // Send Event that network is disconnected. Listener will use GetProperties. - EventRouter* event_router = - ExtensionSystem::Get(GetProfile())->event_router(); - scoped_ptr<base::ListValue> args(api::OnNetworksChanged::Create( - std::vector<std::string>(1, params->network_guid))); - scoped_ptr<extensions::Event> extension_event( - new extensions::Event(api::OnNetworksChanged::kEventName, args.Pass())); - event_router->BroadcastEvent(extension_event.Pass()); - } + NetworkingPrivateServiceClient* process_client = + NetworkingPrivateServiceClientFactory::GetForProfile(GetProfile()); + process_client->StartDisconnect( + params->network_guid, + base::Bind( + &NetworkingPrivateStartDisconnectFunction::DisconnectionStartSuccess, + this), + base::Bind( + &NetworkingPrivateStartDisconnectFunction::DisconnectionStartFailed, + this)); return true; } +void NetworkingPrivateStartDisconnectFunction::DisconnectionStartSuccess() { + SendResponse(true); +} + +void NetworkingPrivateStartDisconnectFunction::DisconnectionStartFailed( + const std::string& error_name, + const scoped_ptr<base::DictionaryValue> error_data) { + error_ = error_name; + SendResponse(false); +} + //////////////////////////////////////////////////////////////////////////////// // NetworkingPrivateVerifyDestinationFunction NetworkingPrivateVerifyDestinationFunction:: - ~NetworkingPrivateVerifyDestinationFunction() { -} + ~NetworkingPrivateVerifyDestinationFunction() {} bool NetworkingPrivateVerifyDestinationFunction::RunImpl() { scoped_ptr<api::VerifyDestination::Params> params = api::VerifyDestination::Params::Create(*args_); EXTENSION_FUNCTION_VALIDATE(params); - SetResult(new base::FundamentalValue(true)); - SendResponse(true); + NetworkingPrivateServiceClient* process_client = + NetworkingPrivateServiceClientFactory::GetForProfile(GetProfile()); + process_client->VerifyDestination( + args_.Pass(), + base::Bind( + &NetworkingPrivateVerifyDestinationFunction::ResultCallback, + this), + base::Bind( + &NetworkingPrivateVerifyDestinationFunction::ErrorCallback, + this)); return true; } +void NetworkingPrivateVerifyDestinationFunction::ResultCallback(bool result) { + SetResult(new base::FundamentalValue(result)); + SendResponse(true); +} + +void NetworkingPrivateVerifyDestinationFunction::ErrorCallback( + const std::string& error_name, const std::string& error) { + error_ = error_name; + SendResponse(false); +} + //////////////////////////////////////////////////////////////////////////////// // NetworkingPrivateVerifyAndEncryptCredentialsFunction @@ -494,7 +452,27 @@ bool NetworkingPrivateVerifyAndEncryptDataFunction::RunImpl() { scoped_ptr<api::VerifyAndEncryptData::Params> params = api::VerifyAndEncryptData::Params::Create(*args_); EXTENSION_FUNCTION_VALIDATE(params); - SetResult(new base::StringValue("encrypted_data")); - SendResponse(true); + NetworkingPrivateServiceClient* process_client = + NetworkingPrivateServiceClientFactory::GetForProfile(GetProfile()); + process_client->VerifyAndEncryptData( + args_.Pass(), + base::Bind( + &NetworkingPrivateVerifyAndEncryptDataFunction::ResultCallback, + this), + base::Bind( + &NetworkingPrivateVerifyAndEncryptDataFunction::ErrorCallback, + this)); return true; } + +void NetworkingPrivateVerifyAndEncryptDataFunction::ResultCallback( + const std::string& result) { + SetResult(new base::StringValue(result)); + SendResponse(true); +} + +void NetworkingPrivateVerifyAndEncryptDataFunction::ErrorCallback( + const std::string& error_name, const std::string& error) { + error_ = error_name; + SendResponse(false); +} diff --git a/chrome/browser/extensions/api/networking_private/networking_private_apitest.cc b/chrome/browser/extensions/api/networking_private/networking_private_apitest.cc index ee4810c..0d82a95 100644 --- a/chrome/browser/extensions/api/networking_private/networking_private_apitest.cc +++ b/chrome/browser/extensions/api/networking_private/networking_private_apitest.cc @@ -30,15 +30,53 @@ #include "components/policy/core/common/policy_types.h" #include "policy/policy_constants.h" #include "third_party/cros_system_api/dbus/service_constants.h" -#endif // OS_CHROMEOS +#else // !defined(OS_CHROMEOS) +#include "chrome/browser/extensions/api/networking_private/networking_private_service_client.h" +#include "chrome/browser/extensions/api/networking_private/networking_private_service_client_factory.h" +#include "components/wifi/wifi_service.h" +#endif // defined(OS_CHROMEOS) using testing::Return; using testing::_; -namespace chromeos { +#if defined(OS_CHROMEOS) +using chromeos::CryptohomeClient; +using chromeos::DBUS_METHOD_CALL_SUCCESS; +using chromeos::DBusMethodCallStatus; +using chromeos::DBusThreadManager; +using chromeos::ShillDeviceClient; +using chromeos::ShillManagerClient; +using chromeos::ShillProfileClient; +using chromeos::ShillServiceClient; +#else // !defined(OS_CHROMEOS) +using extensions::NetworkingPrivateServiceClientFactory; +#endif // defined(OS_CHROMEOS) + +namespace { #if defined(OS_CHROMEOS) const char kUser1ProfilePath[] = "/profile/user1/shill"; +#else // !defined(OS_CHROMEOS) + +// Stub Verify* methods implementation to satisfy expectations of +// networking_private_apitest. +// TODO(mef): Fix ChromeOS implementation to use NetworkingPrivateCrypto, +// and update networking_private_apitest to use and expect valid data. +// That will eliminate the need for mock implementation. +class CryptoVerifyStub + : public extensions::NetworkingPrivateServiceClient::CryptoVerify { + virtual void VerifyDestination(scoped_ptr<base::ListValue> args, + bool* verified, + std::string* error) OVERRIDE { + *verified = true; + } + + virtual void VerifyAndEncryptData(scoped_ptr<base::ListValue> args, + std::string* encoded_data, + std::string* error) OVERRIDE { + *encoded_data = "encrypted_data"; + } +}; #endif // defined(OS_CHROMEOS) class ExtensionNetworkingPrivateApiTest : @@ -78,10 +116,11 @@ class ExtensionNetworkingPrivateApiTest : // TODO(pneubeck): Remove the following hack, once the NetworkingPrivateAPI // uses the ProfileHelper to obtain the userhash crbug/238623. std::string login_user = - command_line->GetSwitchValueNative(switches::kLoginUser); + command_line->GetSwitchValueNative(chromeos::switches::kLoginUser); std::string sanitized_user = CryptohomeClient::GetStubSanitizedUsername( login_user); - command_line->AppendSwitchASCII(switches::kLoginProfile, sanitized_user); + command_line->AppendSwitchASCII(chromeos::switches::kLoginProfile, + sanitized_user); if (GetParam()) command_line->AppendSwitch(::switches::kMultiProfiles); } @@ -132,8 +171,8 @@ class ExtensionNetworkingPrivateApiTest : service_test->SetServiceProperty( "stub_ethernet", shill::kProfileProperty, - base::StringValue(shill_stub_helper::kSharedProfilePath)); - profile_test->AddService(shill_stub_helper::kSharedProfilePath, + base::StringValue(chromeos::shill_stub_helper::kSharedProfilePath)); + profile_test->AddService(chromeos::shill_stub_helper::kSharedProfilePath, "stub_ethernet"); service_test->AddService("stub_wifi1", "wifi1", @@ -218,10 +257,21 @@ class ExtensionNetworkingPrivateApiTest : "epcifkihnkjgphfkloaaleeakhpmgdmn"); } + static BrowserContextKeyedService* + CreateNetworkingPrivateServiceClient(content::BrowserContext* profile) { + return new extensions::NetworkingPrivateServiceClient( + wifi::WiFiService::CreateForTest(), + new CryptoVerifyStub()); + } + virtual void SetUpOnMainThread() OVERRIDE { ExtensionApiTest::SetUpOnMainThread(); content::RunAllPendingInMessageLoop(); + NetworkingPrivateServiceClientFactory::GetInstance()->SetTestingFactory( + profile(), + &CreateNetworkingPrivateServiceClient); } + #endif // OS_CHROMEOS protected: @@ -259,10 +309,6 @@ IN_PROC_BROWSER_TEST_P(ExtensionNetworkingPrivateApiTest, << message_; } -IN_PROC_BROWSER_TEST_P(ExtensionNetworkingPrivateApiTest, CreateNetwork) { - EXPECT_TRUE(RunNetworkingSubtest("createNetwork")) << message_; -} - IN_PROC_BROWSER_TEST_P(ExtensionNetworkingPrivateApiTest, GetVisibleNetworks) { EXPECT_TRUE(RunNetworkingSubtest("getVisibleNetworks")) << message_; } @@ -291,6 +337,10 @@ IN_PROC_BROWSER_TEST_P(ExtensionNetworkingPrivateApiTest, SetProperties) { } #if defined(OS_CHROMEOS) +IN_PROC_BROWSER_TEST_P(ExtensionNetworkingPrivateApiTest, CreateNetwork) { + EXPECT_TRUE(RunNetworkingSubtest("createNetwork")) << message_; +} + IN_PROC_BROWSER_TEST_P(ExtensionNetworkingPrivateApiTest, GetStateNonExistent) { EXPECT_TRUE(RunNetworkingSubtest("getStateNonExistent")) << message_; } @@ -385,4 +435,5 @@ INSTANTIATE_TEST_CASE_P(ExtensionNetworkingPrivateApiTestInstantiation, ExtensionNetworkingPrivateApiTest, testing::Bool()); -} // namespace chromeos +} // namespace + diff --git a/chrome/browser/extensions/api/networking_private/networking_private_crypto.cc b/chrome/browser/extensions/api/networking_private/networking_private_crypto.cc index a302154..2698452 100644 --- a/chrome/browser/extensions/api/networking_private/networking_private_crypto.cc +++ b/chrome/browser/extensions/api/networking_private/networking_private_crypto.cc @@ -67,7 +67,6 @@ bool GetDERFromPEM(const std::string& pem_data, } // namespace - NetworkingPrivateCrypto::NetworkingPrivateCrypto() {} NetworkingPrivateCrypto::~NetworkingPrivateCrypto() {} diff --git a/chrome/browser/extensions/api/networking_private/networking_private_crypto.h b/chrome/browser/extensions/api/networking_private/networking_private_crypto.h index 2488473..0df9506 100644 --- a/chrome/browser/extensions/api/networking_private/networking_private_crypto.h +++ b/chrome/browser/extensions/api/networking_private/networking_private_crypto.h @@ -28,8 +28,8 @@ class NetworkingPrivateCrypto { const std::string& connected_mac); // Encrypt |data| with |public_key|. |public_key| is a DER-encoded - // RSAPublicKey. |data| is some string of bytes at smaller than the - // maximum length permissable for encryption with a key of |public_key| size. + // RSAPublicKey. |data| is some string of bytes that is smaller than the + // maximum length permissible for PKCS#1 v1.5 with a key of |public_key| size. // // Returns true on success, storing the encrypted result in // |encrypted_output|. diff --git a/chrome/browser/extensions/api/networking_private/networking_private_crypto_unittest.cc b/chrome/browser/extensions/api/networking_private/networking_private_crypto_unittest.cc index 8267db0..486166f 100644 --- a/chrome/browser/extensions/api/networking_private/networking_private_crypto_unittest.cc +++ b/chrome/browser/extensions/api/networking_private/networking_private_crypto_unittest.cc @@ -1,15 +1,14 @@ // Copyright 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/extensions/api/networking_private/networking_private_crypto.h" #include "base/base64.h" #include "base/logging.h" #include "base/strings/stringprintf.h" -#include "chrome/browser/extensions/api/networking_private/networking_private_crypto.h" #include "testing/gtest/include/gtest/gtest.h" // Tests of NetworkingPrivateCrypto support for Networking Private API. -// Based on chromeos_public//.../network_DestinationVerification.py class NetworkingPrivateCryptoTest : public testing::Test { protected: // Verify that decryption of |encrypted| data using |private_key_pem| matches diff --git a/chrome/browser/extensions/api/networking_private/networking_private_event_router.h b/chrome/browser/extensions/api/networking_private/networking_private_event_router.h index 442db09..68f0fdb 100644 --- a/chrome/browser/extensions/api/networking_private/networking_private_event_router.h +++ b/chrome/browser/extensions/api/networking_private/networking_private_event_router.h @@ -5,52 +5,29 @@ #ifndef CHROME_BROWSER_EXTENSIONS_API_NETWORKING_PRIVATE_NETWORKING_PRIVATE_EVENT_ROUTER_H_ #define CHROME_BROWSER_EXTENSIONS_API_NETWORKING_PRIVATE_NETWORKING_PRIVATE_EVENT_ROUTER_H_ -#include "chromeos/network/network_state_handler_observer.h" #include "components/browser_context_keyed_service/browser_context_keyed_service.h" #include "extensions/browser/event_router.h" class Profile; -namespace chromeos { +namespace extensions { -// This is a factory class used by the BrowserContextDependencyManager -// to instantiate the event router that will forward events +// This is an event router that will observe listeners to |NetworksChanged| and +// |NetworkListChanged| events. On ChromeOS it will forward these events // from the NetworkStateHandler to the JavaScript Networking API. class NetworkingPrivateEventRouter : public BrowserContextKeyedService, - public extensions::EventRouter::Observer, - public NetworkStateHandlerObserver { + public EventRouter::Observer { public: - explicit NetworkingPrivateEventRouter(Profile* profile); - virtual ~NetworkingPrivateEventRouter(); + static NetworkingPrivateEventRouter* Create(Profile* profile); protected: - // BrowserContextKeyedService overrides: - virtual void Shutdown() OVERRIDE; - - // EventRouter::Observer overrides: - virtual void OnListenerAdded( - const extensions::EventListenerInfo& details) OVERRIDE; - virtual void OnListenerRemoved( - const extensions::EventListenerInfo& details) OVERRIDE; - - // NetworkStateHandlerObserver overrides: - virtual void NetworkListChanged() OVERRIDE; - virtual void NetworkPropertiesUpdated(const NetworkState* network) OVERRIDE; + NetworkingPrivateEventRouter() {} private: - // Decide if we should listen for network changes or not. If there are any - // JavaScript listeners registered for the onNetworkChanged event, then we - // want to register for change notification from the network state handler. - // Otherwise, we want to unregister and not be listening to network changes. - void StartOrStopListeningForNetworkChanges(); - - Profile* profile_; - bool listening_; - DISALLOW_COPY_AND_ASSIGN(NetworkingPrivateEventRouter); }; -} // namespace chromeos +} // namespace extensions #endif // CHROME_BROWSER_EXTENSIONS_API_NETWORKING_PRIVATE_NETWORKING_PRIVATE_EVENT_ROUTER_H_ diff --git a/chrome/browser/extensions/api/networking_private/networking_private_event_router_chromeos.cc b/chrome/browser/extensions/api/networking_private/networking_private_event_router_chromeos.cc index 9699833..adf110c 100644 --- a/chrome/browser/extensions/api/networking_private/networking_private_event_router_chromeos.cc +++ b/chrome/browser/extensions/api/networking_private/networking_private_event_router_chromeos.cc @@ -15,19 +15,53 @@ #include "chromeos/network/network_event_log.h" #include "chromeos/network/network_state.h" #include "chromeos/network/network_state_handler.h" +#include "chromeos/network/network_state_handler_observer.h" #include "chromeos/network/onc/onc_signature.h" #include "chromeos/network/onc/onc_translator.h" #include "components/browser_context_keyed_service/browser_context_dependency_manager.h" #include "components/onc/onc_constants.h" #include "third_party/cros_system_api/dbus/service_constants.h" -using extensions::EventRouter; -using extensions::ExtensionSystem; -namespace api = extensions::api::networking_private; +using chromeos::NetworkHandler; +using chromeos::NetworkState; +using chromeos::NetworkStateHandler; -namespace chromeos { +namespace extensions { -NetworkingPrivateEventRouter::NetworkingPrivateEventRouter(Profile* profile) +class NetworkingPrivateEventRouterImpl + : public NetworkingPrivateEventRouter, + public chromeos::NetworkStateHandlerObserver { + public: + explicit NetworkingPrivateEventRouterImpl(Profile* profile); + virtual ~NetworkingPrivateEventRouterImpl(); + + protected: + // BrowserContextKeyedService overrides: + virtual void Shutdown() OVERRIDE; + + // EventRouter::Observer overrides: + virtual void OnListenerAdded(const EventListenerInfo& details) OVERRIDE; + virtual void OnListenerRemoved(const EventListenerInfo& details) OVERRIDE; + + // NetworkStateHandlerObserver overrides: + virtual void NetworkListChanged() OVERRIDE; + virtual void NetworkPropertiesUpdated(const NetworkState* network) OVERRIDE; + + private: + // Decide if we should listen for network changes or not. If there are any + // JavaScript listeners registered for the onNetworkChanged event, then we + // want to register for change notification from the network state handler. + // Otherwise, we want to unregister and not be listening to network changes. + void StartOrStopListeningForNetworkChanges(); + + Profile* profile_; + bool listening_; + + DISALLOW_COPY_AND_ASSIGN(NetworkingPrivateEventRouterImpl); +}; + +NetworkingPrivateEventRouterImpl::NetworkingPrivateEventRouterImpl( + Profile* profile) : profile_(profile), listening_(false) { // Register with the event router so we know when renderers are listening to // our events. We first check and see if there *is* an event router, because @@ -36,18 +70,18 @@ NetworkingPrivateEventRouter::NetworkingPrivateEventRouter(Profile* profile) EventRouter* event_router = ExtensionSystem::Get(profile_)->event_router(); if (event_router) { event_router->RegisterObserver( - this, api::OnNetworksChanged::kEventName); + this, api::networking_private::OnNetworksChanged::kEventName); event_router->RegisterObserver( - this, api::OnNetworkListChanged::kEventName); + this, api::networking_private::OnNetworkListChanged::kEventName); StartOrStopListeningForNetworkChanges(); } } -NetworkingPrivateEventRouter::~NetworkingPrivateEventRouter() { +NetworkingPrivateEventRouterImpl::~NetworkingPrivateEventRouterImpl() { DCHECK(!listening_); } -void NetworkingPrivateEventRouter::Shutdown() { +void NetworkingPrivateEventRouterImpl::Shutdown() { // Unregister with the event router. We first check and see if there *is* an // event router, because some unit tests try to shutdown all profile services, // but didn't initialize the event router first. @@ -62,24 +96,26 @@ void NetworkingPrivateEventRouter::Shutdown() { listening_ = false; } -void NetworkingPrivateEventRouter::OnListenerAdded( - const extensions::EventListenerInfo& details) { +void NetworkingPrivateEventRouterImpl::OnListenerAdded( + const EventListenerInfo& details) { // Start listening to events from the network state handler. StartOrStopListeningForNetworkChanges(); } -void NetworkingPrivateEventRouter::OnListenerRemoved( - const extensions::EventListenerInfo& details) { +void NetworkingPrivateEventRouterImpl::OnListenerRemoved( + const EventListenerInfo& details) { // Stop listening to events from the network state handler if there are no // more listeners. StartOrStopListeningForNetworkChanges(); } -void NetworkingPrivateEventRouter::StartOrStopListeningForNetworkChanges() { +void NetworkingPrivateEventRouterImpl::StartOrStopListeningForNetworkChanges() { EventRouter* event_router = ExtensionSystem::Get(profile_)->event_router(); bool should_listen = - event_router->HasEventListener(api::OnNetworksChanged::kEventName) || - event_router->HasEventListener(api::OnNetworkListChanged::kEventName); + event_router->HasEventListener( + api::networking_private::OnNetworksChanged::kEventName) || + event_router->HasEventListener( + api::networking_private::OnNetworkListChanged::kEventName); if (should_listen && !listening_) { NetworkHandler::Get()->network_state_handler()->AddObserver( @@ -91,11 +127,12 @@ void NetworkingPrivateEventRouter::StartOrStopListeningForNetworkChanges() { listening_ = should_listen; } -void NetworkingPrivateEventRouter::NetworkListChanged() { +void NetworkingPrivateEventRouterImpl::NetworkListChanged() { EventRouter* event_router = ExtensionSystem::Get(profile_)->event_router(); NetworkStateHandler::NetworkStateList networks; NetworkHandler::Get()->network_state_handler()->GetNetworkList(&networks); - if (!event_router->HasEventListener(api::OnNetworkListChanged::kEventName)) { + if (!event_router->HasEventListener( + api::networking_private::OnNetworkListChanged::kEventName)) { // TODO(stevenjb): Remove logging once crbug.com/256881 is fixed // (or at least reduce to LOG_DEBUG). Same with NET_LOG events below. NET_LOG_EVENT("NetworkingPrivate.NetworkListChanged: No Listeners", ""); @@ -106,35 +143,44 @@ void NetworkingPrivateEventRouter::NetworkListChanged() { std::vector<std::string> changes; for (NetworkStateHandler::NetworkStateList::const_iterator iter = - networks.begin(); iter != networks.end(); ++iter) { + networks.begin(); + iter != networks.end(); + ++iter) { // TODO(gspencer): Currently the "GUID" is actually the service path. Fix // this to be the real GUID once we're using // ManagedNetworkConfigurationManager. changes.push_back((*iter)->path()); } - scoped_ptr<base::ListValue> args(api::OnNetworkListChanged::Create(changes)); - scoped_ptr<extensions::Event> extension_event(new extensions::Event( - api::OnNetworkListChanged::kEventName, args.Pass())); + scoped_ptr<base::ListValue> args( + api::networking_private::OnNetworkListChanged::Create(changes)); + scoped_ptr<Event> extension_event(new Event( + api::networking_private::OnNetworkListChanged::kEventName, args.Pass())); event_router->BroadcastEvent(extension_event.Pass()); } -void NetworkingPrivateEventRouter::NetworkPropertiesUpdated( +void NetworkingPrivateEventRouterImpl::NetworkPropertiesUpdated( const NetworkState* network) { EventRouter* event_router = ExtensionSystem::Get(profile_)->event_router(); - if (!event_router->HasEventListener(api::OnNetworksChanged::kEventName)) { + if (!event_router->HasEventListener( + api::networking_private::OnNetworksChanged::kEventName)) { NET_LOG_EVENT("NetworkingPrivate.NetworkPropertiesUpdated: No Listeners", network->path()); return; } NET_LOG_EVENT("NetworkingPrivate.NetworkPropertiesUpdated", network->path()); - scoped_ptr<base::ListValue> args(api::OnNetworksChanged::Create( - std::vector<std::string>(1, network->path()))); - scoped_ptr<extensions::Event> extension_event( - new extensions::Event(api::OnNetworksChanged::kEventName, args.Pass())); + scoped_ptr<base::ListValue> args( + api::networking_private::OnNetworksChanged::Create( + std::vector<std::string>(1, network->path()))); + scoped_ptr<Event> extension_event(new Event( + api::networking_private::OnNetworksChanged::kEventName, args.Pass())); event_router->BroadcastEvent(extension_event.Pass()); } -} // namespace chromeos +NetworkingPrivateEventRouter* NetworkingPrivateEventRouter::Create( + Profile* profile) { + return new NetworkingPrivateEventRouterImpl(profile); +} +} // namespace extensions diff --git a/chrome/browser/extensions/api/networking_private/networking_private_event_router_factory.cc b/chrome/browser/extensions/api/networking_private/networking_private_event_router_factory.cc index 6814ffe..689cdee 100644 --- a/chrome/browser/extensions/api/networking_private/networking_private_event_router_factory.cc +++ b/chrome/browser/extensions/api/networking_private/networking_private_event_router_factory.cc @@ -5,12 +5,13 @@ #include "chrome/browser/extensions/api/networking_private/networking_private_event_router_factory.h" #include "chrome/browser/extensions/api/networking_private/networking_private_event_router.h" +#include "chrome/browser/extensions/api/networking_private/networking_private_service_client_factory.h" #include "chrome/browser/extensions/extension_system_factory.h" #include "chrome/browser/profiles/incognito_helpers.h" #include "chrome/browser/profiles/profile.h" #include "components/browser_context_keyed_service/browser_context_dependency_manager.h" -namespace chromeos { +namespace extensions { // static NetworkingPrivateEventRouter* @@ -30,6 +31,9 @@ NetworkingPrivateEventRouterFactory::NetworkingPrivateEventRouterFactory() "NetworkingPrivateEventRouter", BrowserContextDependencyManager::GetInstance()) { DependsOn(extensions::ExtensionSystemFactory::GetInstance()); +#if !defined(OS_CHROMEOS) + DependsOn(extensions::NetworkingPrivateServiceClientFactory::GetInstance()); +#endif } NetworkingPrivateEventRouterFactory::~NetworkingPrivateEventRouterFactory() { @@ -38,11 +42,7 @@ NetworkingPrivateEventRouterFactory::~NetworkingPrivateEventRouterFactory() { BrowserContextKeyedService* NetworkingPrivateEventRouterFactory::BuildServiceInstanceFor( content::BrowserContext* profile) const { -#if defined(OS_CHROMEOS) - return new NetworkingPrivateEventRouter(static_cast<Profile*>(profile)); -#else // OS_CHROMEOS - return NULL; -#endif // OS_CHROMEOS + return NetworkingPrivateEventRouter::Create(static_cast<Profile*>(profile)); } content::BrowserContext* @@ -60,4 +60,4 @@ bool NetworkingPrivateEventRouterFactory::ServiceIsNULLWhileTesting() const { return true; } -} // namespace chromeos +} // namespace extensions diff --git a/chrome/browser/extensions/api/networking_private/networking_private_event_router_factory.h b/chrome/browser/extensions/api/networking_private/networking_private_event_router_factory.h index bcd2eba..da9d829 100644 --- a/chrome/browser/extensions/api/networking_private/networking_private_event_router_factory.h +++ b/chrome/browser/extensions/api/networking_private/networking_private_event_router_factory.h @@ -10,7 +10,7 @@ class Profile; -namespace chromeos { +namespace extensions { class NetworkingPrivateEventRouter; @@ -47,7 +47,7 @@ class NetworkingPrivateEventRouterFactory DISALLOW_COPY_AND_ASSIGN(NetworkingPrivateEventRouterFactory); }; -} // namespace chromeos +} // namespace extensions #endif // CHROME_BROWSER_EXTENSIONS_API_NETWORKING_PRIVATE_NETWORKING_PRIVATE_EVENT_ROUTER_FACTORY_H_ diff --git a/chrome/browser/extensions/api/networking_private/networking_private_event_router_nonchromeos.cc b/chrome/browser/extensions/api/networking_private/networking_private_event_router_nonchromeos.cc new file mode 100644 index 0000000..0d242e2 --- /dev/null +++ b/chrome/browser/extensions/api/networking_private/networking_private_event_router_nonchromeos.cc @@ -0,0 +1,157 @@ +// Copyright 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/extensions/api/networking_private/networking_private_event_router.h" + +#include "chrome/browser/extensions/api/networking_private/networking_private_api.h" +#include "chrome/browser/extensions/api/networking_private/networking_private_service_client.h" +#include "chrome/browser/extensions/api/networking_private/networking_private_service_client_factory.h" +#include "chrome/browser/extensions/extension_system.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/common/extensions/api/networking_private.h" + +namespace extensions { + +// This is an event router that will observe listeners to |NetworksChanged| and +// |NetworkListChanged| events. +class NetworkingPrivateEventRouterImpl + : public NetworkingPrivateEventRouter, + NetworkingPrivateServiceClient::Observer { + public: + explicit NetworkingPrivateEventRouterImpl(Profile* profile); + virtual ~NetworkingPrivateEventRouterImpl(); + + protected: + // BrowserContextKeyedService overrides: + virtual void Shutdown() OVERRIDE; + + // EventRouter::Observer overrides: + virtual void OnListenerAdded(const EventListenerInfo& details) OVERRIDE; + virtual void OnListenerRemoved(const EventListenerInfo& details) OVERRIDE; + + // NetworkingPrivateServiceClient::Observer overrides: + virtual void OnNetworksChangedEvent( + const std::vector<std::string>& network_guids) OVERRIDE; + virtual void OnNetworkListChangedEvent( + const std::vector<std::string>& network_guids) OVERRIDE; + + private: + // Decide if we should listen for network changes or not. If there are any + // JavaScript listeners registered for the onNetworkChanged event, then we + // want to register for change notification from the network state handler. + // Otherwise, we want to unregister and not be listening to network changes. + void StartOrStopListeningForNetworkChanges(); + + Profile* profile_; + bool listening_; + + DISALLOW_COPY_AND_ASSIGN(NetworkingPrivateEventRouterImpl); +}; + +NetworkingPrivateEventRouterImpl::NetworkingPrivateEventRouterImpl( + Profile* profile) + : profile_(profile), listening_(false) { + // Register with the event router so we know when renderers are listening to + // our events. We first check and see if there *is* an event router, because + // some unit tests try to create all profile services, but don't initialize + // the event router first. + EventRouter* event_router = ExtensionSystem::Get(profile_)->event_router(); + if (!event_router) + return; + event_router->RegisterObserver( + this, api::networking_private::OnNetworksChanged::kEventName); + event_router->RegisterObserver( + this, api::networking_private::OnNetworkListChanged::kEventName); + StartOrStopListeningForNetworkChanges(); +} + +NetworkingPrivateEventRouterImpl::~NetworkingPrivateEventRouterImpl() { + DCHECK(!listening_); +} + +void NetworkingPrivateEventRouterImpl::Shutdown() { + // Unregister with the event router. We first check and see if there *is* an + // event router, because some unit tests try to shutdown all profile services, + // but didn't initialize the event router first. + EventRouter* event_router = ExtensionSystem::Get(profile_)->event_router(); + if (event_router) + event_router->UnregisterObserver(this); + + if (!listening_) + return; + listening_ = false; + NetworkingPrivateServiceClient* process_client = + NetworkingPrivateServiceClientFactory::GetForProfile(profile_); + process_client->RemoveObserver(this); +} + +void NetworkingPrivateEventRouterImpl::OnListenerAdded( + const EventListenerInfo& details) { + // Start listening to events from the network state handler. + StartOrStopListeningForNetworkChanges(); +} + +void NetworkingPrivateEventRouterImpl::OnListenerRemoved( + const EventListenerInfo& details) { + // Stop listening to events from the network state handler if there are no + // more listeners. + StartOrStopListeningForNetworkChanges(); +} + +void NetworkingPrivateEventRouterImpl::StartOrStopListeningForNetworkChanges() { + EventRouter* event_router = ExtensionSystem::Get(profile_)->event_router(); + if (!event_router) + return; + bool should_listen = + event_router->HasEventListener( + api::networking_private::OnNetworksChanged::kEventName) || + event_router->HasEventListener( + api::networking_private::OnNetworkListChanged::kEventName); + + if (should_listen && !listening_) { + NetworkingPrivateServiceClient* process_client = + NetworkingPrivateServiceClientFactory::GetForProfile(profile_); + process_client->AddObserver(this); + } + + if (!should_listen && listening_) { + NetworkingPrivateServiceClient* process_client = + NetworkingPrivateServiceClientFactory::GetForProfile(profile_); + process_client->RemoveObserver(this); + } + + listening_ = should_listen; +} + +void NetworkingPrivateEventRouterImpl::OnNetworksChangedEvent( + const std::vector<std::string>& network_guids) { + EventRouter* event_router = ExtensionSystem::Get(profile_)->event_router(); + if (!event_router) + return; + scoped_ptr<base::ListValue> args( + api::networking_private::OnNetworksChanged::Create(network_guids)); + scoped_ptr<extensions::Event> netchanged_event(new extensions::Event( + api::networking_private::OnNetworksChanged::kEventName, args.Pass())); + event_router->BroadcastEvent(netchanged_event.Pass()); +} + +void NetworkingPrivateEventRouterImpl::OnNetworkListChangedEvent( + const std::vector<std::string>& network_guids) { + EventRouter* event_router = ExtensionSystem::Get(profile_)->event_router(); + if (!event_router) + return; + scoped_ptr<base::ListValue> args( + api::networking_private::OnNetworkListChanged::Create(network_guids)); + scoped_ptr<extensions::Event> netlistchanged_event(new extensions::Event( + api::networking_private::OnNetworkListChanged::kEventName, + args.Pass())); + event_router->BroadcastEvent(netlistchanged_event.Pass()); +} + +NetworkingPrivateEventRouter* NetworkingPrivateEventRouter::Create( + Profile* profile) { + return new NetworkingPrivateEventRouterImpl(profile); +} + +} // namespace extensions diff --git a/chrome/browser/extensions/api/networking_private/networking_private_service_client.cc b/chrome/browser/extensions/api/networking_private/networking_private_service_client.cc new file mode 100644 index 0000000..cb56224 --- /dev/null +++ b/chrome/browser/extensions/api/networking_private/networking_private_service_client.cc @@ -0,0 +1,470 @@ +// Copyright 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/extensions/api/networking_private/networking_private_service_client.h" + +#include "base/base64.h" +#include "base/bind.h" +#include "base/sequenced_task_runner.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/string_util.h" +#include "base/threading/worker_pool.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/extensions/api/networking_private/networking_private_crypto.h" +#include "chrome/common/extensions/api/networking_private.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/utility_process_host.h" + +using content::BrowserThread; +using extensions::api::networking_private::VerificationProperties; + +namespace extensions { + +namespace { + +const char kNetworkingPrivateServiceClient[] = "NetworkingPrivateServiceClient"; +const char kNetworkingPrivateSequenceTokenName[] = "NetworkingPrivate"; + +// Implementation of Verify* methods using NetworkingPrivateCrypto. +// TODO(mef): Move this into NetworkingPrivateCrypto class. +class CryptoVerifyImpl : public NetworkingPrivateServiceClient::CryptoVerify { + bool VerifyDestination(const VerificationProperties& properties) { + std::vector<std::string> data_parts; + data_parts.push_back(properties.device_ssid); + data_parts.push_back(properties.device_serial); + data_parts.push_back(properties.device_bssid); + data_parts.push_back(properties.public_key); + data_parts.push_back(properties.nonce); + std::string unsigned_data = JoinString(data_parts, ","); + std::string signed_data; + if (!base::Base64Decode(properties.signed_data, &signed_data)) + return false; + NetworkingPrivateCrypto crypto; + return crypto.VerifyCredentials(properties.certificate, + signed_data, + unsigned_data, + properties.device_bssid); + } + + virtual void VerifyDestination(scoped_ptr<base::ListValue> args, + bool* verified, + std::string* error) OVERRIDE { + using extensions::api::networking_private::VerifyDestination::Params; + scoped_ptr<Params> params = Params::Create(*args); + *verified = VerifyDestination(params->properties); + } + + virtual void VerifyAndEncryptData(scoped_ptr<base::ListValue> args, + std::string* base64_encoded_ciphertext, + std::string* error) OVERRIDE { + using extensions::api::networking_private::VerifyAndEncryptData::Params; + scoped_ptr<Params> params = Params::Create(*args); + + if (!VerifyDestination(params->properties)) { + *error = "VerifyError"; + return; + } + + std::string public_key; + if (!base::Base64Decode(params->properties.public_key, &public_key)) { + *error = "DecodeError"; + return; + } + + NetworkingPrivateCrypto crypto; + std::string ciphertext; + if (!crypto.EncryptByteString(public_key, params->data, &ciphertext)) { + *error = "EncryptError"; + return; + } + + if (!base::Base64Encode(ciphertext, base64_encoded_ciphertext)) { + *error = "EncodeError"; + return; + } + } +}; + +// Deletes WiFiService and CryptoVerify objects on worker thread. +void ShutdownServicesOnWorkerThread( + scoped_ptr<wifi::WiFiService> wifi_service, + scoped_ptr<NetworkingPrivateServiceClient::CryptoVerify> crypto_verify) { + DCHECK(wifi_service.get()); + DCHECK(crypto_verify.get()); +} + +} // namespace + +NetworkingPrivateServiceClient::NetworkingPrivateServiceClient( + wifi::WiFiService* wifi_service, + CryptoVerify* crypto_verify) + : crypto_verify_(crypto_verify), + wifi_service_(wifi_service), + weak_factory_(this) { + sequence_token_ = BrowserThread::GetBlockingPool()-> + GetNamedSequenceToken(kNetworkingPrivateSequenceTokenName); + task_runner_ = BrowserThread::GetBlockingPool()-> + GetSequencedTaskRunnerWithShutdownBehavior( + sequence_token_, + base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN); + task_runner_->PostTask( + FROM_HERE, + base::Bind( + &WiFiService::SetEventObservers, + base::Unretained(wifi_service_.get()), + base::MessageLoopProxy::current(), + base::Bind( + &NetworkingPrivateServiceClient::OnNetworksChangedEventOnUIThread, + weak_factory_.GetWeakPtr()), + base::Bind( + &NetworkingPrivateServiceClient:: + OnNetworkListChangedEventOnUIThread, + weak_factory_.GetWeakPtr()))); +} + +NetworkingPrivateServiceClient::~NetworkingPrivateServiceClient() { + // Verify that these objects were passed to ShutdownServicesOnWorkerThread to + // be deleted after completion of all posted tasks. + DCHECK(!wifi_service_.get()); + DCHECK(!crypto_verify_.get()); +} + +NetworkingPrivateServiceClient::CryptoVerify* + NetworkingPrivateServiceClient::CryptoVerify::Create() { + return new CryptoVerifyImpl(); +} + +NetworkingPrivateServiceClient::ServiceCallbacks::ServiceCallbacks() {} + +NetworkingPrivateServiceClient::ServiceCallbacks::~ServiceCallbacks() {} + +void NetworkingPrivateServiceClient::Shutdown() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + // Clear callbacks map to release callbacks from UI thread. + callbacks_map_.Clear(); + // Post ShutdownServicesOnWorkerThread task to delete services when all posted + // tasks are done. + task_runner_->PostTask( + FROM_HERE, + base::Bind(&ShutdownServicesOnWorkerThread, + base::Passed(&wifi_service_), + base::Passed(&crypto_verify_))); +} + +void NetworkingPrivateServiceClient::AddObserver(Observer* observer) { + network_events_observers_.AddObserver(observer); +} + +void NetworkingPrivateServiceClient::RemoveObserver(Observer* observer) { + network_events_observers_.RemoveObserver(observer); +} + +NetworkingPrivateServiceClient::ServiceCallbacks* +NetworkingPrivateServiceClient::AddServiceCallbacks() { + ServiceCallbacks* service_callbacks = new ServiceCallbacks(); + service_callbacks->id = callbacks_map_.Add(service_callbacks); + return service_callbacks; +} + +void NetworkingPrivateServiceClient::RemoveServiceCallbacks( + ServiceCallbacksID callback_id) { + callbacks_map_.Remove(callback_id); +} + +void NetworkingPrivateServiceClient::GetProperties( + const std::string& network_guid, + const DictionaryResultCallback& callback, + const ErrorCallback& error_callback) { + ServiceCallbacks* service_callbacks = AddServiceCallbacks(); + service_callbacks->error_callback = error_callback; + service_callbacks->get_properties_callback = callback; + + DictionaryValue* properties = new DictionaryValue(); + std::string* error = new std::string; + + task_runner_->PostTaskAndReply( + FROM_HERE, + base::Bind(&WiFiService::GetProperties, + base::Unretained(wifi_service_.get()), + network_guid, + properties, + error), + base::Bind(&NetworkingPrivateServiceClient::AfterGetProperties, + weak_factory_.GetWeakPtr(), + service_callbacks->id, + network_guid, + base::Owned(properties), + base::Owned(error))); +} + +void NetworkingPrivateServiceClient::GetVisibleNetworks( + const ListResultCallback& callback) { + ServiceCallbacks* service_callbacks = AddServiceCallbacks(); + service_callbacks->get_visible_networks_callback = callback; + + ListValue* networks = new ListValue(); + + task_runner_->PostTaskAndReply( + FROM_HERE, + base::Bind(&WiFiService::GetVisibleNetworks, + base::Unretained(wifi_service_.get()), + networks), + base::Bind(&NetworkingPrivateServiceClient::AfterGetVisibleNetworks, + weak_factory_.GetWeakPtr(), + service_callbacks->id, + base::Owned(networks))); +} + +void NetworkingPrivateServiceClient::RequestNetworkScan() { + task_runner_->PostTask( + FROM_HERE, + base::Bind(&WiFiService::RequestNetworkScan, + base::Unretained(wifi_service_.get()))); +} + +void NetworkingPrivateServiceClient::SetProperties( + const std::string& network_guid, + const base::DictionaryValue& properties, + const base::Closure& callback, + const ErrorCallback& error_callback) { + ServiceCallbacks* service_callbacks = AddServiceCallbacks(); + service_callbacks->error_callback = error_callback; + service_callbacks->set_properties_callback = callback; + + scoped_ptr<base::DictionaryValue> properties_ptr(properties.DeepCopy()); + std::string* error = new std::string; + + task_runner_->PostTaskAndReply( + FROM_HERE, + base::Bind(&WiFiService::SetProperties, + base::Unretained(wifi_service_.get()), + network_guid, + base::Passed(&properties_ptr), + error), + base::Bind(&NetworkingPrivateServiceClient::AfterSetProperties, + weak_factory_.GetWeakPtr(), + service_callbacks->id, + base::Owned(error))); +} + + +void NetworkingPrivateServiceClient::StartConnect( + const std::string& network_guid, + const base::Closure& callback, + const ErrorCallback& error_callback) { + ServiceCallbacks* service_callbacks = AddServiceCallbacks(); + service_callbacks->error_callback = error_callback; + service_callbacks->start_connect_callback = callback; + + std::string* error = new std::string; + + task_runner_->PostTaskAndReply( + FROM_HERE, + base::Bind(&WiFiService::StartConnect, + base::Unretained(wifi_service_.get()), + network_guid, + error), + base::Bind(&NetworkingPrivateServiceClient::AfterStartConnect, + weak_factory_.GetWeakPtr(), + service_callbacks->id, + base::Owned(error))); +} + +void NetworkingPrivateServiceClient::StartDisconnect( + const std::string& network_guid, + const base::Closure& callback, + const ErrorCallback& error_callback) { + ServiceCallbacks* service_callbacks = AddServiceCallbacks(); + service_callbacks->error_callback = error_callback; + service_callbacks->start_disconnect_callback = callback; + + std::string* error = new std::string; + + task_runner_->PostTaskAndReply( + FROM_HERE, + base::Bind(&WiFiService::StartDisconnect, + base::Unretained(wifi_service_.get()), + network_guid, + error), + base::Bind(&NetworkingPrivateServiceClient::AfterStartDisconnect, + weak_factory_.GetWeakPtr(), + service_callbacks->id, + base::Owned(error))); +} + +void NetworkingPrivateServiceClient::VerifyDestination( + scoped_ptr<base::ListValue> args, + const BoolResultCallback& callback, + const CryptoErrorCallback& error_callback) { + ServiceCallbacks* service_callbacks = AddServiceCallbacks(); + service_callbacks->crypto_error_callback = error_callback; + service_callbacks->verify_destination_callback = callback; + + bool* result = new bool; + std::string* error = new std::string; + + task_runner_->PostTaskAndReply( + FROM_HERE, + base::Bind(&CryptoVerify::VerifyDestination, + base::Unretained(crypto_verify_.get()), + base::Passed(&args), + result, + error), + base::Bind(&NetworkingPrivateServiceClient::AfterVerifyDestination, + weak_factory_.GetWeakPtr(), + service_callbacks->id, + base::Owned(result), + base::Owned(error))); +} + +void NetworkingPrivateServiceClient::VerifyAndEncryptData( + scoped_ptr<base::ListValue> args, + const StringResultCallback& callback, + const CryptoErrorCallback& error_callback) { + ServiceCallbacks* service_callbacks = AddServiceCallbacks(); + service_callbacks->crypto_error_callback = error_callback; + service_callbacks->verify_and_encrypt_data_callback = callback; + + std::string* result = new std::string; + std::string* error = new std::string; + + task_runner_->PostTaskAndReply( + FROM_HERE, + base::Bind(&CryptoVerify::VerifyAndEncryptData, + base::Unretained(crypto_verify_.get()), + base::Passed(&args), + result, + error), + base::Bind(&NetworkingPrivateServiceClient::AfterVerifyAndEncryptData, + weak_factory_.GetWeakPtr(), + service_callbacks->id, + base::Owned(result), + base::Owned(error))); +} + +void NetworkingPrivateServiceClient::AfterGetProperties( + ServiceCallbacksID callback_id, + const std::string& network_guid, + const DictionaryValue* properties, + const std::string* error) { + ServiceCallbacks* service_callbacks = callbacks_map_.Lookup(callback_id); + DCHECK(service_callbacks); + if (!error->empty()) { + DCHECK(!service_callbacks->error_callback.is_null()); + service_callbacks->error_callback.Run(*error, + scoped_ptr<base::DictionaryValue>()); + } else { + DCHECK(!service_callbacks->get_properties_callback.is_null()); + service_callbacks->get_properties_callback.Run(network_guid, *properties); + } + RemoveServiceCallbacks(callback_id); +} + +void NetworkingPrivateServiceClient::AfterGetVisibleNetworks( + ServiceCallbacksID callback_id, + const ListValue* networks) { + ServiceCallbacks* service_callbacks = callbacks_map_.Lookup(callback_id); + DCHECK(service_callbacks); + DCHECK(!service_callbacks->get_visible_networks_callback.is_null()); + service_callbacks->get_visible_networks_callback.Run(*networks); + RemoveServiceCallbacks(callback_id); +} + +void NetworkingPrivateServiceClient::AfterSetProperties( + ServiceCallbacksID callback_id, + const std::string* error) { + ServiceCallbacks* service_callbacks = callbacks_map_.Lookup(callback_id); + DCHECK(service_callbacks); + if (!error->empty()) { + DCHECK(!service_callbacks->error_callback.is_null()); + service_callbacks->error_callback.Run(*error, + scoped_ptr<base::DictionaryValue>()); + } else { + DCHECK(!service_callbacks->set_properties_callback.is_null()); + service_callbacks->set_properties_callback.Run(); + } + RemoveServiceCallbacks(callback_id); +} + +void NetworkingPrivateServiceClient::AfterStartConnect( + ServiceCallbacksID callback_id, + const std::string* error) { + ServiceCallbacks* service_callbacks = callbacks_map_.Lookup(callback_id); + DCHECK(service_callbacks); + if (!error->empty()) { + DCHECK(!service_callbacks->error_callback.is_null()); + service_callbacks->error_callback.Run(*error, + scoped_ptr<base::DictionaryValue>()); + } else { + DCHECK(!service_callbacks->start_connect_callback.is_null()); + service_callbacks->start_connect_callback.Run(); + } + RemoveServiceCallbacks(callback_id); +} + +void NetworkingPrivateServiceClient::AfterStartDisconnect( + ServiceCallbacksID callback_id, + const std::string* error) { + ServiceCallbacks* service_callbacks = callbacks_map_.Lookup(callback_id); + DCHECK(service_callbacks); + if (!error->empty()) { + DCHECK(!service_callbacks->error_callback.is_null()); + service_callbacks->error_callback.Run(*error, + scoped_ptr<base::DictionaryValue>()); + } else { + DCHECK(!service_callbacks->start_disconnect_callback.is_null()); + service_callbacks->start_disconnect_callback.Run(); + } + RemoveServiceCallbacks(callback_id); +} + +void NetworkingPrivateServiceClient::AfterVerifyDestination( + ServiceCallbacksID callback_id, + const bool* result, + const std::string* error) { + ServiceCallbacks* service_callbacks = callbacks_map_.Lookup(callback_id); + DCHECK(service_callbacks); + if (!error->empty()) { + DCHECK(!service_callbacks->crypto_error_callback.is_null()); + service_callbacks->crypto_error_callback.Run(*error, *error); + } else { + DCHECK(!service_callbacks->verify_destination_callback.is_null()); + service_callbacks->verify_destination_callback.Run(*result); + } + RemoveServiceCallbacks(callback_id); +} + +void NetworkingPrivateServiceClient::AfterVerifyAndEncryptData( + ServiceCallbacksID callback_id, + const std::string* result, + const std::string* error) { + ServiceCallbacks* service_callbacks = callbacks_map_.Lookup(callback_id); + DCHECK(service_callbacks); + if (!error->empty()) { + DCHECK(!service_callbacks->crypto_error_callback.is_null()); + service_callbacks->crypto_error_callback.Run(*error, *error); + } else { + DCHECK(!service_callbacks->verify_and_encrypt_data_callback.is_null()); + service_callbacks->verify_and_encrypt_data_callback.Run(*result); + } + RemoveServiceCallbacks(callback_id); +} + +void NetworkingPrivateServiceClient::OnNetworksChangedEventOnUIThread( + const std::vector<std::string>& network_guids) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + FOR_EACH_OBSERVER(Observer, + network_events_observers_, + OnNetworksChangedEvent(network_guids)); +} + +void NetworkingPrivateServiceClient::OnNetworkListChangedEventOnUIThread( + const std::vector<std::string>& network_guids) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + FOR_EACH_OBSERVER(Observer, + network_events_observers_, + OnNetworkListChangedEvent(network_guids)); +} + +} // namespace extensions diff --git a/chrome/browser/extensions/api/networking_private/networking_private_service_client.h b/chrome/browser/extensions/api/networking_private/networking_private_service_client.h new file mode 100644 index 0000000..3e0ced6 --- /dev/null +++ b/chrome/browser/extensions/api/networking_private/networking_private_service_client.h @@ -0,0 +1,239 @@ +// Copyright 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. + +#ifndef CHROME_BROWSER_EXTENSIONS_API_NETWORKING_PRIVATE_NETWORKING_PRIVATE_SERVICE_CLIENT_H_ +#define CHROME_BROWSER_EXTENSIONS_API_NETWORKING_PRIVATE_NETWORKING_PRIVATE_SERVICE_CLIENT_H_ + +#include <string> +#include <vector> + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "base/id_map.h" +#include "base/memory/weak_ptr.h" +#include "base/observer_list.h" +#include "base/strings/string16.h" +#include "base/supports_user_data.h" +#include "base/threading/sequenced_worker_pool.h" +#include "base/values.h" +#include "components/browser_context_keyed_service/browser_context_keyed_service.h" +#include "components/wifi/wifi_service.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/utility_process_host.h" +#include "content/public/browser/utility_process_host_client.h" + +namespace base { +class SequencedTaskRunner; +} + +namespace wifi { +class WiFiService; +} + +namespace extensions { + +using wifi::WiFiService; + +// The client wrapper for the WiFiService and CryptoVerify interfaces to invoke +// them on worker thread. Always used from UI thread only. +class NetworkingPrivateServiceClient : public BrowserContextKeyedService { + public: + // Interface for Verify* methods implementation. + class CryptoVerify { + public: + CryptoVerify() {} + virtual ~CryptoVerify() {} + + static CryptoVerify* Create(); + + virtual void VerifyDestination(scoped_ptr<base::ListValue> args, + bool* verified, + std::string* error) = 0; + + virtual void VerifyAndEncryptData(scoped_ptr<base::ListValue> args, + std::string* base64_encoded_ciphertext, + std::string* error) = 0; + private: + DISALLOW_COPY_AND_ASSIGN(CryptoVerify); + }; + + // Interface for observing Network Events. + class Observer { + public: + Observer() {} + virtual ~Observer() {} + + virtual void OnNetworksChangedEvent( + const std::vector<std::string>& network_guids) = 0; + virtual void OnNetworkListChangedEvent( + const std::vector<std::string>& network_guids) = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(Observer); + }; + + // An error callback used by most of API functions to receive error results + // from the NetworkingPrivateServiceClient. + typedef base::Callback< + void(const std::string& error_name, + scoped_ptr<base::DictionaryValue> error_data)> ErrorCallback; + + // An error callback used by most of Crypto Verify* API functions to receive + // error results from the NetworkingPrivateServiceClient. + // TODO(mef): Cleanup networking_private_api.* to make consistent + // NetworkingPrivateXXXFunction naming and error callbacks. + typedef base::Callback< + void(const std::string& error_name, + const std::string& error)> CryptoErrorCallback; + + // Callback used to return bool result from VerifyDestination function. + typedef base::Callback<void(bool result)> BoolResultCallback; + + // Callback used to return string result from VerifyAndEncryptData function. + typedef base::Callback<void(const std::string& result)> StringResultCallback; + + // Callback used to return Dictionary of network properties. + typedef base::Callback< + void(const std::string& network_guid, + const base::DictionaryValue& dictionary)> DictionaryResultCallback; + + // Callback used to return List of visibile networks. + typedef base::Callback< + void(const base::ListValue& network_list)> ListResultCallback; + + // Takes ownership of |wifi_service| and |crypto_verify|. They are accessed + // and deleted on the worker thread. The deletion task is posted during the + // NetworkingPrivateServiceClient shutdown. + NetworkingPrivateServiceClient(wifi::WiFiService* wifi_service, + CryptoVerify* crypto_verify); + + // BrowserContextKeyedServices method override. + virtual void Shutdown() OVERRIDE; + + // Gets the properties of the network with id |service_path|. See note on + // |callback| and |error_callback|, in class description above. + void GetProperties(const std::string& service_path, + const DictionaryResultCallback& callback, + const ErrorCallback& error_callback); + + // Start connect to the network with id |service_path|. See note on + // |callback| and |error_callback|, in class description above. + void StartConnect(const std::string& service_path, + const base::Closure& callback, + const ErrorCallback& error_callback); + + // Start disconnect from the network with id |service_path|. See note on + // |callback| and |error_callback|, in class description above. + void StartDisconnect(const std::string& service_path, + const base::Closure& callback, + const ErrorCallback& error_callback); + + // Sets the |properties| of the network with id |service_path|. See note on + // |callback| and |error_callback|, in class description above. + void SetProperties(const std::string& service_path, + const base::DictionaryValue& properties, + const base::Closure& callback, + const ErrorCallback& error_callback); + + // Requests network scan. Broadcasts NetworkListChangedEvent upon completion. + void RequestNetworkScan(); + + // Gets the list of visible networks and calls |callback|. + void GetVisibleNetworks(const ListResultCallback& callback); + + // Verify that Chromecast provides valid cryptographically signed properties. + void VerifyDestination(scoped_ptr<base::ListValue> args, + const BoolResultCallback& callback, + const CryptoErrorCallback& error_callback); + + // Verify that Chromecast provides valid cryptographically signed properties. + // If valid, then encrypt data using Chromecast's public key. + void VerifyAndEncryptData(scoped_ptr<base::ListValue> args, + const StringResultCallback& callback, + const CryptoErrorCallback& error_callback); + + // Adds observer to network events. + void AddObserver(Observer* network_events_observer); + + // Removes observer to network events. If there is no observers, + // then process can be shut down when there are no more calls pending return. + void RemoveObserver(Observer* network_events_observer); + + private: + // Callbacks to extension api function objects. Keep reference to API object + // and are released in ShutdownOnUIThread. Run when WiFiService calls back + // into NetworkingPrivateServiceClient's callback wrappers. + typedef int32 ServiceCallbacksID; + struct ServiceCallbacks { + ServiceCallbacks(); + ~ServiceCallbacks(); + + DictionaryResultCallback get_properties_callback; + base::Closure start_connect_callback; + base::Closure start_disconnect_callback; + base::Closure set_properties_callback; + ListResultCallback get_visible_networks_callback; + ErrorCallback error_callback; + + BoolResultCallback verify_destination_callback; + StringResultCallback verify_and_encrypt_data_callback; + CryptoErrorCallback crypto_error_callback; + + ServiceCallbacksID id; + }; + typedef IDMap<ServiceCallbacks, IDMapOwnPointer> ServiceCallbacksMap; + + virtual ~NetworkingPrivateServiceClient(); + + // Callback wrappers. + void AfterGetProperties(ServiceCallbacksID callback_id, + const std::string& network_guid, + const DictionaryValue* properties, + const std::string* error); + void AfterSetProperties(ServiceCallbacksID callback_id, + const std::string* error); + void AfterGetVisibleNetworks(ServiceCallbacksID callback_id, + const ListValue* network_list); + void AfterStartConnect(ServiceCallbacksID callback_id, + const std::string* error); + void AfterStartDisconnect(ServiceCallbacksID callback_id, + const std::string* error); + void AfterVerifyDestination(ServiceCallbacksID callback_id, + const bool* result, + const std::string* error); + void AfterVerifyAndEncryptData(ServiceCallbacksID callback_id, + const std::string* result, + const std::string* error); + + void OnNetworksChangedEventOnUIThread( + const WiFiService::NetworkGuidList& network_guid_list); + void OnNetworkListChangedEventOnUIThread( + const WiFiService::NetworkGuidList& network_guid_list); + + // Add new |ServiceCallbacks| to |callbacks_map_|. + ServiceCallbacks* AddServiceCallbacks(); + // Removes ServiceCallbacks for |callback_id| from |callbacks_map_|. + void RemoveServiceCallbacks(ServiceCallbacksID callback_id); + + // Callbacks to run when callback is called from WiFiService. + ServiceCallbacksMap callbacks_map_; + // Observers to Network Events. + ObserverList<Observer> network_events_observers_; + // Interface for Verify* methods. Used and deleted on the worker thread. + scoped_ptr<CryptoVerify> crypto_verify_; + // Interface to WiFiService. Used and deleted on the worker thread. + scoped_ptr<wifi::WiFiService> wifi_service_; + // Sequence token associated with wifi tasks. + base::SequencedWorkerPool::SequenceToken sequence_token_; + // Task runner for worker tasks. + scoped_refptr<base::SequencedTaskRunner> task_runner_; + // Use WeakPtrs for callbacks from |wifi_service_| and |crypto_verify_|. + base::WeakPtrFactory<NetworkingPrivateServiceClient> weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(NetworkingPrivateServiceClient); +}; + +} // namespace extensions + +#endif // CHROME_BROWSER_EXTENSIONS_API_NETWORKING_PRIVATE_NETWORKING_PRIVATE_SERVICE_CLIENT_H_ diff --git a/chrome/browser/extensions/api/networking_private/networking_private_service_client_factory.cc b/chrome/browser/extensions/api/networking_private/networking_private_service_client_factory.cc new file mode 100644 index 0000000..c9b7304 --- /dev/null +++ b/chrome/browser/extensions/api/networking_private/networking_private_service_client_factory.cc @@ -0,0 +1,57 @@ +// Copyright 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/extensions/api/networking_private/networking_private_service_client_factory.h" + +#include "chrome/browser/extensions/api/networking_private/networking_private_service_client.h" +#include "chrome/browser/extensions/extension_system_factory.h" +#include "chrome/browser/profiles/profile.h" +#include "components/browser_context_keyed_service/browser_context_dependency_manager.h" +#include "content/public/browser/browser_thread.h" + +namespace extensions { + +// static +NetworkingPrivateServiceClient* + NetworkingPrivateServiceClientFactory::GetForProfile(Profile* profile) { + return static_cast<NetworkingPrivateServiceClient*>( + GetInstance()->GetServiceForBrowserContext(profile, true)); +} + +// static +NetworkingPrivateServiceClientFactory* + NetworkingPrivateServiceClientFactory::GetInstance() { + return Singleton<NetworkingPrivateServiceClientFactory>::get(); +} + +NetworkingPrivateServiceClientFactory::NetworkingPrivateServiceClientFactory() + : BrowserContextKeyedServiceFactory( + "NetworkingPrivateServiceClient", + BrowserContextDependencyManager::GetInstance()) { + DependsOn(ExtensionSystemFactory::GetInstance()); +} + +NetworkingPrivateServiceClientFactory + ::~NetworkingPrivateServiceClientFactory() { +} + +BrowserContextKeyedService* + NetworkingPrivateServiceClientFactory::BuildServiceInstanceFor( + content::BrowserContext* profile) const { + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); + return new NetworkingPrivateServiceClient( + wifi::WiFiService::Create(), + NetworkingPrivateServiceClient::CryptoVerify::Create()); +} + +bool NetworkingPrivateServiceClientFactory::ServiceIsCreatedWithBrowserContext() + const { + return false; +} + +bool NetworkingPrivateServiceClientFactory::ServiceIsNULLWhileTesting() const { + return false; +} + +} // namespace extensions diff --git a/chrome/browser/extensions/api/networking_private/networking_private_service_client_factory.h b/chrome/browser/extensions/api/networking_private/networking_private_service_client_factory.h new file mode 100644 index 0000000..9cc75ed --- /dev/null +++ b/chrome/browser/extensions/api/networking_private/networking_private_service_client_factory.h @@ -0,0 +1,41 @@ +// Copyright 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. + +#ifndef CHROME_BROWSER_EXTENSIONS_API_NETWORKING_PRIVATE_NETWORKING_PRIVATE_SERVICE_CLIENT_FACTORY_H_ +#define CHROME_BROWSER_EXTENSIONS_API_NETWORKING_PRIVATE_NETWORKING_PRIVATE_SERVICE_CLIENT_FACTORY_H_ + +#include "base/memory/singleton.h" +#include "components/browser_context_keyed_service/browser_context_keyed_service_factory.h" + +class Profile; + +namespace extensions { + +class NetworkingPrivateServiceClient; + +class NetworkingPrivateServiceClientFactory + : public BrowserContextKeyedServiceFactory { + public: + static NetworkingPrivateServiceClient* GetForProfile(Profile* profile); + + static NetworkingPrivateServiceClientFactory* GetInstance(); + + private: + friend struct DefaultSingletonTraits<NetworkingPrivateServiceClientFactory>; + + NetworkingPrivateServiceClientFactory(); + virtual ~NetworkingPrivateServiceClientFactory(); + + // BrowserContextKeyedServiceFactory: + virtual BrowserContextKeyedService* + BuildServiceInstanceFor(content::BrowserContext* profile) const OVERRIDE; + virtual bool ServiceIsCreatedWithBrowserContext() const OVERRIDE; + virtual bool ServiceIsNULLWhileTesting() const OVERRIDE; + + DISALLOW_COPY_AND_ASSIGN(NetworkingPrivateServiceClientFactory); +}; + +} // namespace extensions + +#endif // CHROME_BROWSER_EXTENSIONS_API_NETWORKING_PRIVATE_NETWORKING_PRIVATE_SERVICE_CLIENT_FACTORY_H_ diff --git a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc index 5976de3..027b774 100644 --- a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc +++ b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc @@ -78,6 +78,7 @@ #include "chrome/browser/extensions/api/management/management_api.h" #include "chrome/browser/extensions/api/mdns/mdns_api.h" #include "chrome/browser/extensions/api/media_galleries_private/media_galleries_private_api.h" +#include "chrome/browser/extensions/api/networking_private/networking_private_event_router_factory.h" #include "chrome/browser/extensions/api/omnibox/omnibox_api.h" #include "chrome/browser/extensions/api/preference/chrome_direct_setting_api.h" #include "chrome/browser/extensions/api/preference/preference_api.h" @@ -141,7 +142,6 @@ #include "chrome/browser/chromeos/extensions/media_player_api.h" #include "chrome/browser/chromeos/extensions/screenlock_private_api.h" #include "chrome/browser/extensions/api/input_ime/input_ime_api.h" -#include "chrome/browser/extensions/api/networking_private/networking_private_event_router_factory.h" #if defined(FILE_MANAGER_EXTENSION) #include "chrome/browser/chromeos/extensions/file_manager/file_browser_private_api_factory.h" #endif @@ -211,9 +211,6 @@ EnsureBrowserContextKeyedServiceFactoriesBuilt() { #if defined(OS_ANDROID) ProtectedMediaIdentifierPermissionContextFactory::GetInstance(); #endif -#if defined(OS_CHROMEOS) - chromeos::NetworkingPrivateEventRouterFactory::GetInstance(); -#endif #if defined(ENABLE_FULL_PRINTING) CloudPrintProxyServiceFactory::GetInstance(); #endif @@ -280,6 +277,9 @@ EnsureBrowserContextKeyedServiceFactoriesBuilt() { extensions::MediaPlayerAPI::GetFactoryInstance(); #endif extensions::MenuManagerFactory::GetInstance(); +#if defined(OS_CHROMEOS) || defined(OS_WIN) + extensions::NetworkingPrivateEventRouterFactory::GetInstance(); +#endif // defined(OS_CHROMEOS) || defined(OS_WIN) extensions::OmniboxAPI::GetFactoryInstance(); #if defined(ENABLE_PLUGINS) extensions::PluginManager::GetFactoryInstance(); diff --git a/chrome/chrome_browser_extensions.gypi b/chrome/chrome_browser_extensions.gypi index 0077c4a..2078414a 100644 --- a/chrome/chrome_browser_extensions.gypi +++ b/chrome/chrome_browser_extensions.gypi @@ -28,6 +28,7 @@ 'installer_util', 'sync_file_system_proto', '../components/components.gyp:onc_component', + '../components/components.gyp:wifi_component', '../content/content.gyp:content_browser', '../crypto/crypto.gyp:crypto', '../device/bluetooth/bluetooth.gyp:device_bluetooth', @@ -388,15 +389,6 @@ 'browser/extensions/api/music_manager_private/device_id_win.cc', 'browser/extensions/api/music_manager_private/music_manager_private_api.cc', 'browser/extensions/api/music_manager_private/music_manager_private_api.h', - 'browser/extensions/api/networking_private/networking_private_api_chromeos.cc', - 'browser/extensions/api/networking_private/networking_private_api_nonchromeos.cc', - 'browser/extensions/api/networking_private/networking_private_api.h', - 'browser/extensions/api/networking_private/networking_private_crypto.cc', - 'browser/extensions/api/networking_private/networking_private_crypto.h', - 'browser/extensions/api/networking_private/networking_private_event_router_chromeos.cc', - 'browser/extensions/api/networking_private/networking_private_event_router.h', - 'browser/extensions/api/networking_private/networking_private_event_router_factory.cc', - 'browser/extensions/api/networking_private/networking_private_event_router_factory.h', 'browser/extensions/api/notifications/notifications_api.cc', 'browser/extensions/api/notifications/notifications_api.h', 'browser/extensions/api/omnibox/omnibox_api.cc', @@ -927,7 +919,6 @@ 'browser/extensions/api/audio/audio_service.cc', 'browser/extensions/api/feedback_private/feedback_service_nonchromeos.cc', 'browser/extensions/api/image_writer_private/operation_linux.cc', - 'browser/extensions/api/networking_private/networking_private_api_nonchromeos.cc', 'browser/extensions/api/system_display/display_info_provider_aura.cc', 'browser/extensions/default_apps.cc', 'browser/extensions/default_apps.h', @@ -950,6 +941,12 @@ 'browser/extensions/api/log_private/syslog_parser.h', 'browser/chromeos/extensions/screenlock_private_api.cc', 'browser/chromeos/extensions/screenlock_private_api.h', + 'browser/extensions/api/networking_private/networking_private_api_chromeos.cc', + 'browser/extensions/api/networking_private/networking_private_api.h', + 'browser/extensions/api/networking_private/networking_private_event_router_chromeos.cc', + 'browser/extensions/api/networking_private/networking_private_event_router.h', + 'browser/extensions/api/networking_private/networking_private_event_router_factory.cc', + 'browser/extensions/api/networking_private/networking_private_event_router_factory.h', 'browser/extensions/api/terminal/terminal_extension_helper.cc', 'browser/extensions/api/terminal/terminal_extension_helper.h', 'browser/extensions/api/terminal/terminal_private_api.cc', @@ -992,6 +989,7 @@ ['include', '^browser/extensions/api/messaging/message_property_provider.cc'], ['include', '^browser/extensions/api/messaging/message_service.cc'], ['include', '^browser/extensions/api/module/module.cc'], + ['include', '^browser/extensions/api/networking_private/.*\.cc'], ['include', '^browser/extensions/api/omnibox/omnibox_api.cc'], ['include', '^browser/extensions/api/preference/preference_api.cc'], ['include', '^browser/extensions/api/proxy/proxy_api.cc'], @@ -1067,6 +1065,22 @@ ], }], ['OS=="win"', { + 'sources': [ + 'browser/extensions/api/networking_private/networking_private_api.h', + 'browser/extensions/api/networking_private/networking_private_api_nonchromeos.cc', + 'browser/extensions/api/networking_private/networking_private_crypto.cc', + 'browser/extensions/api/networking_private/networking_private_crypto.h', + 'browser/extensions/api/networking_private/networking_private_event_router.h', + 'browser/extensions/api/networking_private/networking_private_event_router_factory.cc', + 'browser/extensions/api/networking_private/networking_private_event_router_factory.h', + 'browser/extensions/api/networking_private/networking_private_event_router_nonchromeos.cc', + 'browser/extensions/api/networking_private/networking_private_service_client.cc', + 'browser/extensions/api/networking_private/networking_private_service_client.h', + 'browser/extensions/api/networking_private/networking_private_service_client_factory.cc', + 'browser/extensions/api/networking_private/networking_private_service_client_factory.h', + ], + }], + ['OS=="win"', { 'dependencies': [ 'launcher_support', '../third_party/iaccessible2/iaccessible2.gyp:iaccessible2', diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index c0d108d..3bf8f10 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -1161,7 +1161,6 @@ 'browser/extensions/api/metrics_private/metrics_apitest.cc', 'browser/extensions/api/module/module_apitest.cc', 'browser/extensions/api/music_manager_private/music_manager_private_browsertest.cc', - 'browser/extensions/api/networking_private/networking_private_apitest.cc', 'browser/extensions/api/notifications/notifications_apitest.cc', 'browser/extensions/api/omnibox/omnibox_api_browsertest.cc', 'browser/extensions/api/page_capture/page_capture_apitest.cc', @@ -1959,6 +1958,11 @@ }], ], }], + ['chromeos == 1 or OS=="win"', { + 'sources': [ + 'browser/extensions/api/networking_private/networking_private_apitest.cc', + ], + }], ['toolkit_views==1', { 'dependencies': [ '../ui/views/views.gyp:views', diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi index 8bd155b2..c66eca5 100644 --- a/chrome/chrome_tests_unit.gypi +++ b/chrome/chrome_tests_unit.gypi @@ -841,7 +841,6 @@ 'browser/extensions/api/messaging/native_message_process_host_unittest.cc', 'browser/extensions/api/messaging/native_messaging_host_manifest_unittest.cc', 'browser/extensions/api/mdns/dns_sd_registry_unittest.cc', - 'browser/extensions/api/networking_private/networking_private_crypto_unittest.cc', 'browser/extensions/api/omnibox/omnibox_unittest.cc', 'browser/extensions/api/permissions/permissions_api_helpers_unittest.cc', 'browser/extensions/api/power/power_api_unittest.cc', @@ -2526,6 +2525,7 @@ '<(DEPTH)/third_party/wtl/include', ], 'sources': [ + 'browser/extensions/api/networking_private/networking_private_crypto_unittest.cc', # TODO: It would be nice to have these pulled in # automatically from direct_dependent_settings in # their various targets (net.gyp:net_resources, etc.), diff --git a/chrome/common/extensions/api/networking_private.json b/chrome/common/extensions/api/networking_private.json index 750860f..1cdf358 100644 --- a/chrome/common/extensions/api/networking_private.json +++ b/chrome/common/extensions/api/networking_private.json @@ -9,6 +9,7 @@ "compiler_options": { "implemented_in": "chrome/browser/extensions/api/networking_private/networking_private_api.h" }, + "platforms": ["chromeos", "win"], "types" : [ { "id": "NetworkProperties", diff --git a/components/OWNERS b/components/OWNERS index 356fe7b..63c9c4d 100644 --- a/components/OWNERS +++ b/components/OWNERS @@ -67,5 +67,7 @@ per-file variations.gypi=asvitkine@chromium.org per-file variations.gypi=jwd@chromium.org per-file variations.gypi=stevet@chromium.org +per-file wifi.gypi=mef@chromium.org + per-file *.isolate=csharp@chromium.org per-file *.isolate=maruel@chromium.org diff --git a/components/components.gyp b/components/components.gyp index d9b31c4..053852b 100644 --- a/components/components.gyp +++ b/components/components.gyp @@ -31,5 +31,6 @@ 'webdata.gypi', 'web_contents_delegate_android.gypi', 'web_modal.gypi', + 'wifi.gypi', ], } diff --git a/components/wifi.gypi b/components/wifi.gypi new file mode 100644 index 0000000..f65bdaa --- /dev/null +++ b/components/wifi.gypi @@ -0,0 +1,28 @@ +# Copyright 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. + +{ + 'targets': [ + { + 'target_name': 'wifi_component', + 'type': '<(component)', + 'dependencies': [ + '../base/base.gyp:base', + '../components/components.gyp:onc_component', + ], + 'include_dirs': [ + '..', + ], + 'defines': [ + 'WIFI_IMPLEMENTATION', + ], + 'sources': [ + 'wifi/wifi_export.h', + 'wifi/wifi_service.cc', + 'wifi/wifi_service.h', + 'wifi/fake_wifi_service.cc', + ], + }, + ], +} diff --git a/components/wifi/DEPS b/components/wifi/DEPS new file mode 100644 index 0000000..273d26b --- /dev/null +++ b/components/wifi/DEPS @@ -0,0 +1,3 @@ +include_rules = [ + "+components/onc", +] diff --git a/components/wifi/OWNERS b/components/wifi/OWNERS new file mode 100644 index 0000000..db8bbdc --- /dev/null +++ b/components/wifi/OWNERS @@ -0,0 +1 @@ +mef@chromium.org diff --git a/components/wifi/fake_wifi_service.cc b/components/wifi/fake_wifi_service.cc new file mode 100644 index 0000000..90902ed --- /dev/null +++ b/components/wifi/fake_wifi_service.cc @@ -0,0 +1,208 @@ +// Copyright 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 "components/wifi/wifi_service.h" + +#include "base/bind.h" +#include "base/message_loop/message_loop.h" +#include "components/onc/onc_constants.h" + +namespace wifi { + +// Fake implementation of WiFiService used to satisfy expectations of +// networkingPrivateApi browser test. +class FakeWiFiService : public WiFiService { + public: + FakeWiFiService() { + // Populate data expected by unit test. + { + WiFiService::NetworkProperties network_properties; + network_properties.connection_state = onc::connection_state::kConnected; + network_properties.guid = "stub_ethernet"; + network_properties.name = "eth0"; + network_properties.type = onc::network_type::kEthernet; + network_properties.json_extra = + " {" + " \"Authentication\": \"None\"" + " }"; + networks_.push_back(network_properties); + } + { + WiFiService::NetworkProperties network_properties; + network_properties.connection_state = onc::connection_state::kConnected; + network_properties.guid = "stub_wifi1"; + network_properties.name = "wifi1"; + network_properties.type = onc::network_type::kWiFi; + network_properties.frequency = 0; + network_properties.ssid = "stub_wifi1"; + network_properties.security = onc::wifi::kWEP_PSK; + network_properties.signal_strength = 0; + networks_.push_back(network_properties); + } + { + WiFiService::NetworkProperties network_properties; + network_properties.connection_state = onc::connection_state::kConnected; + network_properties.guid = "stub_vpn1"; + network_properties.name = "vpn1"; + network_properties.type = onc::network_type::kVPN; + networks_.push_back(network_properties); + } + { + WiFiService::NetworkProperties network_properties; + network_properties.connection_state = + onc::connection_state::kNotConnected; + network_properties.guid = "stub_wifi2"; + network_properties.name = "wifi2_PSK"; + network_properties.type = onc::network_type::kWiFi; + network_properties.frequency = 5000; + network_properties.frequency_list.push_back(2400); + network_properties.frequency_list.push_back(5000); + network_properties.ssid = "wifi2_PSK"; + network_properties.security = onc::wifi::kWPA_PSK; + network_properties.signal_strength = 80; + networks_.push_back(network_properties); + } + { + WiFiService::NetworkProperties network_properties; + network_properties.connection_state = + onc::connection_state::kNotConnected; + network_properties.guid = "stub_cellular1"; + network_properties.name = "cellular1"; + network_properties.type = onc::network_type::kCellular; + network_properties.json_extra = + " {" + " \"ActivateOverNonCellularNetwork\": false," + " \"ActivationState\": \"not-activated\"," + " \"NetworkTechnology\": \"GSM\"," + " \"RoamingState\": \"home\"" + " }"; + networks_.push_back(network_properties); + } + } + + virtual void GetProperties(const std::string& network_guid, + DictionaryValue* properties, + std::string* error) OVERRIDE { + NetworkList::iterator network_properties = FindNetwork(network_guid); + if (network_properties != networks_.end()) { + properties->Swap(network_properties->ToValue(false).get()); + } else { + *error = "Error.DBusFailed"; + } + } + + virtual void SetProperties(const std::string& network_guid, + scoped_ptr<base::DictionaryValue> properties, + std::string* error) OVERRIDE { + NetworkList::iterator network_properties = FindNetwork(network_guid); + if (network_properties == networks_.end() || + !network_properties->UpdateFromValue(*properties)) { + *error = "Error.DBusFailed"; + } + } + + virtual void GetVisibleNetworks(ListValue* network_list) OVERRIDE { + for (WiFiService::NetworkList::const_iterator it = networks_.begin(); + it != networks_.end(); + ++it) { + scoped_ptr<DictionaryValue> network(it->ToValue(true)); + network_list->Append(network.release()); + } + } + + virtual void RequestNetworkScan() OVERRIDE { + NotifyNetworkListChanged(networks_); + } + + virtual void StartConnect(const std::string& network_guid, + std::string* error) OVERRIDE { + NetworkList::iterator network_properties = FindNetwork(network_guid); + if (network_properties != networks_.end()) { + DisconnectAllNetworksOfType(network_properties->type); + network_properties->connection_state = onc::connection_state::kConnected; + SortNetworks(); + NotifyNetworkListChanged(networks_); + NotifyNetworkChanged(network_guid); + } else { + *error = "configure-failed"; + } + } + + virtual void StartDisconnect(const std::string& network_guid, + std::string* error) OVERRIDE { + NetworkList::iterator network_properties = FindNetwork(network_guid); + if (network_properties != networks_.end()) { + network_properties->connection_state = + onc::connection_state::kNotConnected; + SortNetworks(); + NotifyNetworkListChanged(networks_); + NotifyNetworkChanged(network_guid); + } else { + *error = "not-found"; + } + } + + virtual void SetEventObservers( + scoped_refptr<base::MessageLoopProxy> message_loop_proxy, + const NetworkGuidListCallback& networks_changed_observer, + const NetworkGuidListCallback& network_list_changed_observer) OVERRIDE { + message_loop_proxy_.swap(message_loop_proxy); + networks_changed_observer_ = networks_changed_observer; + network_list_changed_observer_ = network_list_changed_observer; + } + + private: + NetworkList::iterator FindNetwork(const std::string& network_guid) { + for (NetworkList::iterator it = networks_.begin(); it != networks_.end(); + ++it) { + if (it->guid == network_guid) + return it; + } + return networks_.end(); + } + + void DisconnectAllNetworksOfType(const std::string& type) { + for (NetworkList::iterator it = networks_.begin(); it != networks_.end(); + ++it) { + if (it->type == type) + it->connection_state = onc::connection_state::kNotConnected; + } + } + + void SortNetworks() { + // Sort networks, so connected/connecting is up front, then by type: + // Ethernet, WiFi, Cellular, VPN + networks_.sort(WiFiService::NetworkProperties::OrderByType); + } + + void NotifyNetworkListChanged(const NetworkList& networks) { + WiFiService::NetworkGuidList current_networks; + for (WiFiService::NetworkList::const_iterator it = networks.begin(); + it != networks.end(); + ++it) { + current_networks.push_back(it->guid); + } + + message_loop_proxy_->PostTask( + FROM_HERE, + base::Bind(network_list_changed_observer_, current_networks)); + } + + void NotifyNetworkChanged(const std::string& network_guid) { + WiFiService::NetworkGuidList changed_networks(1, network_guid); + message_loop_proxy_->PostTask( + FROM_HERE, + base::Bind(networks_changed_observer_, changed_networks)); + } + + NetworkList networks_; + scoped_refptr<base::MessageLoopProxy> message_loop_proxy_; + NetworkGuidListCallback networks_changed_observer_; + NetworkGuidListCallback network_list_changed_observer_; +}; + +WiFiService* WiFiService::CreateForTest() { return new FakeWiFiService(); } +WiFiService* WiFiService::Create() { return new FakeWiFiService(); } + +} // namespace wifi diff --git a/components/wifi/wifi_export.h b/components/wifi/wifi_export.h new file mode 100644 index 0000000..50c8676 --- /dev/null +++ b/components/wifi/wifi_export.h @@ -0,0 +1,29 @@ +// Copyright 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. + +#ifndef COMPONENTS_WIFI_WIFI_EXPORT_H_ +#define COMPONENTS_WIFI_WIFI_EXPORT_H_ + +#if defined(COMPONENT_BUILD) +#if defined(WIN32) + +#if defined(WIFI_IMPLEMENTATION) +#define WIFI_EXPORT __declspec(dllexport) +#else +#define WIFI_EXPORT __declspec(dllimport) +#endif // defined(WIFI_IMPLEMENTATION) + +#else // defined(WIN32) +#if defined(WIFI_IMPLEMENTATION) +#define WIFI_EXPORT __attribute__((visibility("default"))) +#else +#define WIFI_EXPORT +#endif +#endif + +#else // defined(COMPONENT_BUILD) +#define WIFI_EXPORT +#endif + +#endif // COMPONENTS_WIFI_WIFI_EXPORT_H_ diff --git a/components/wifi/wifi_service.cc b/components/wifi/wifi_service.cc new file mode 100644 index 0000000..2ca87c3 --- /dev/null +++ b/components/wifi/wifi_service.cc @@ -0,0 +1,105 @@ +// Copyright 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 "components/wifi/wifi_service.h" + +#include "base/json/json_reader.h" +#include "base/message_loop/message_loop.h" +#include "base/strings/stringprintf.h" +#include "components/onc/onc_constants.h" + +namespace wifi { + +WiFiService::NetworkProperties::NetworkProperties() + : connection_state(onc::connection_state::kNotConnected), + security(onc::wifi::kNone), + signal_strength(0), + auto_connect(false), + frequency(WiFiService::kFrequencyUnknown) {} + +WiFiService::NetworkProperties::~NetworkProperties() {} + +scoped_ptr<base::DictionaryValue> WiFiService::NetworkProperties::ToValue( + bool network_list) const { + scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue()); + + value->SetString(onc::network_config::kGUID, guid); + value->SetString(onc::network_config::kName, name); + value->SetString(onc::network_config::kConnectionState, connection_state); + value->SetString(onc::network_config::kType, type); + + if (type == onc::network_type::kWiFi) { + scoped_ptr<base::DictionaryValue> wifi(new base::DictionaryValue()); + wifi->SetString(onc::wifi::kSecurity, security); + wifi->SetInteger(onc::wifi::kSignalStrength, signal_strength); + + // Network list expects subset of data. + if (!network_list) { + if (frequency != WiFiService::kFrequencyUnknown) + wifi->SetInteger(onc::wifi::kFrequency, frequency); + scoped_ptr<base::ListValue> frequency_list(new base::ListValue()); + for (FrequencyList::const_iterator it = this->frequency_list.begin(); + it != this->frequency_list.end(); + ++it) { + frequency_list->AppendInteger(*it); + } + if (!frequency_list->empty()) + wifi->Set(onc::wifi::kFrequencyList, frequency_list.release()); + if (!bssid.empty()) + wifi->SetString(onc::wifi::kBSSID, bssid); + wifi->SetString(onc::wifi::kSSID, ssid); + } + value->Set(onc::network_type::kWiFi, wifi.release()); + } else { + // Add properites from json extra if present. + if (!json_extra.empty()) { + Value* value_extra = base::JSONReader::Read(json_extra); + value->Set(type, value_extra); + } + } + return value.Pass(); +} + +bool WiFiService::NetworkProperties::UpdateFromValue( + const base::DictionaryValue& value) { + const base::DictionaryValue* wifi = NULL; + std::string wifi_security; + if (value.GetDictionary(onc::network_type::kWiFi, &wifi) && + wifi->GetString(onc::wifi::kSecurity, &wifi_security)) { + security = wifi_security; + return true; + } + return false; +} + +std::string WiFiService::NetworkProperties::MacAddressAsString( + const uint8 mac_as_int[6]) { + // mac_as_int is big-endian. Write in byte chunks. + // Format is XX:XX:XX:XX:XX:XX. + static const char* const kMacFormatString = "%02x:%02x:%02x:%02x:%02x:%02x"; + return base::StringPrintf(kMacFormatString, + mac_as_int[0], + mac_as_int[1], + mac_as_int[2], + mac_as_int[3], + mac_as_int[4], + mac_as_int[5]); +} + +bool WiFiService::NetworkProperties::OrderByType(const NetworkProperties& l, + const NetworkProperties& r) { + if (l.connection_state != r.connection_state) + return l.connection_state < r.connection_state; + // This sorting order is needed only for browser_tests, which expect this + // network type sort order: ethernet < wifi < vpn < cellular. + if (l.type == r.type) + return l.guid < r.guid; + if (l.type == onc::network_type::kEthernet) + return true; + if (r.type == onc::network_type::kEthernet) + return false; + return l.type > r.type; +} + +} // namespace wifi diff --git a/components/wifi/wifi_service.h b/components/wifi/wifi_service.h new file mode 100644 index 0000000..e29d936 --- /dev/null +++ b/components/wifi/wifi_service.h @@ -0,0 +1,119 @@ +// Copyright 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. + +#ifndef CHROME_UTILITY_WIFI_WIFI_SERVICE_H_ +#define CHROME_UTILITY_WIFI_WIFI_SERVICE_H_ + +#include <list> +#include <string> +#include <vector> + +#include "base/callback.h" +#include "base/memory/ref_counted.h" +#include "base/message_loop/message_loop_proxy.h" +#include "base/values.h" +#include "components/wifi/wifi_export.h" + +namespace wifi { + +// WiFiService interface used by implementation of chrome.networkingPrivate +// JavaScript extension API. All methods should be called on worker thread. +// It could be created on any (including UI) thread, so nothing expensive should +// be done in the constructor. +class WIFI_EXPORT WiFiService { + public: + typedef std::vector<std::string> NetworkGuidList; + typedef base::Callback< + void(const NetworkGuidList& network_guid_list)> NetworkGuidListCallback; + + virtual ~WiFiService() {} + + // Create instance of |WiFiService| for normal use. + static WiFiService* Create(); + // Create instance of |WiFiService| for unit test use. + static WiFiService* CreateForTest(); + + // Get Properties of network identified by |network_guid|. Populates + // |properties| on success, |error| on failure. + virtual void GetProperties(const std::string& network_guid, + DictionaryValue* properties, + std::string* error) = 0; + + // Set Properties of network identified by |network_guid|. Populates |error| + // on failure. + virtual void SetProperties(const std::string& network_guid, + scoped_ptr<base::DictionaryValue> properties, + std::string* error) = 0; + + // Get list of visible networks. Populates |network_list| on success. + virtual void GetVisibleNetworks(ListValue* network_list) = 0; + + // Request network scan. Send |NetworkListChanged| event on completion. + virtual void RequestNetworkScan() = 0; + + // Start connect to network identified by |network_guid|. Populates |error| + // on failure. + virtual void StartConnect(const std::string& network_guid, + std::string* error) = 0; + + // Start disconnect from network identified by |network_guid|. Populates + // |error| on failure. + virtual void StartDisconnect(const std::string& network_guid, + std::string* error) = 0; + + // Set observers to run when |NetworksChanged| and |NetworksListChanged| + // events needs to be sent. Notifications are posted on |message_loop_proxy|. + virtual void SetEventObservers( + scoped_refptr<base::MessageLoopProxy> message_loop_proxy, + const NetworkGuidListCallback& networks_changed_observer, + const NetworkGuidListCallback& network_list_changed_observer) = 0; + + protected: + WiFiService() {} + + typedef int32 Frequency; + enum FrequencyEnum { + kFrequencyUnknown = 0, + kFrequency2400 = 2400, + kFrequency5000 = 5000 + }; + + typedef std::list<Frequency> FrequencyList; + // Network Properties, used as result of |GetProperties| and + // |GetVisibleNetworks|. + struct WIFI_EXPORT NetworkProperties { + NetworkProperties(); + ~NetworkProperties(); + + std::string connection_state; + std::string guid; + std::string name; + std::string ssid; + std::string bssid; + std::string type; + std::string security; + // WiFi Signal Strength. 0..100 + uint32 signal_strength; + bool auto_connect; + Frequency frequency; + FrequencyList frequency_list; + + std::string json_extra; // Extra JSON properties for unit tests + + scoped_ptr<base::DictionaryValue> ToValue(bool network_list) const; + bool UpdateFromValue(const base::DictionaryValue& value); + static std::string MacAddressAsString(const uint8 mac_as_int[6]); + static bool OrderByType(const NetworkProperties& l, + const NetworkProperties& r); + }; + + typedef std::list<NetworkProperties> NetworkList; + + private: + DISALLOW_COPY_AND_ASSIGN(WiFiService); +}; + +} // namespace wifi + +#endif // CHROME_UTILITY_WIFI_WIFI_SERVICE_H_ diff --git a/tools/json_schema_compiler/cpp_bundle_generator.py b/tools/json_schema_compiler/cpp_bundle_generator.py index d47f57f1..1cadff8 100644 --- a/tools/json_schema_compiler/cpp_bundle_generator.py +++ b/tools/json_schema_compiler/cpp_bundle_generator.py @@ -84,9 +84,15 @@ class CppBundleGenerator(object): for platform in model_object.platforms: if platform == Platforms.CHROMEOS: ifdefs.append('defined(OS_CHROMEOS)') + elif platform == Platforms.LINUX: + ifdefs.append('defined(OS_LINUX)') + elif platform == Platforms.MAC: + ifdefs.append('defined(OS_MACOSX)') + elif platform == Platforms.WIN: + ifdefs.append('defined(OS_WIN)') else: raise ValueError("Unsupported platform ifdef: %s" % platform.name) - return ' and '.join(ifdefs) + return ' || '.join(ifdefs) def _GenerateRegisterFunctions(self, namespace_name, function): c = code.Code() |