diff options
author | noamsml@chromium.org <noamsml@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-08-07 07:44:08 +0000 |
---|---|---|
committer | noamsml@chromium.org <noamsml@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-08-07 07:44:08 +0000 |
commit | 1c524240de1634bf5db452a2f9f92453719bf6ff (patch) | |
tree | 0acfef7a39b5131ae798cb1c6b946b017407f801 | |
parent | f7209be650f0c2ce2a7454122cad77456c5b2e06 (diff) | |
download | chromium_src-1c524240de1634bf5db452a2f9f92453719bf6ff.zip chromium_src-1c524240de1634bf5db452a2f9f92453719bf6ff.tar.gz chromium_src-1c524240de1634bf5db452a2f9f92453719bf6ff.tar.bz2 |
Added function to get list of networks with prefetched passwords.
Added function that allows javascript apps using gcdPrivate to get a list of networks with prefetched passwords.
Fixed reland of https://codereview.chromium.org/434733003/ which was reverted due to test failure.
BUG=383167
TBR=asargent@chromium.org,vitalybuka@chromium.org
Review URL: https://codereview.chromium.org/450533003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@287995 0039d316-1c4b-4281-b951-d872f2087c98
10 files changed, 217 insertions, 30 deletions
diff --git a/chrome/browser/extensions/api/gcd_private/gcd_private_api.cc b/chrome/browser/extensions/api/gcd_private/gcd_private_api.cc index e68c5f8..b01e6f4 100644 --- a/chrome/browser/extensions/api/gcd_private/gcd_private_api.cc +++ b/chrome/browser/extensions/api/gcd_private/gcd_private_api.cc @@ -136,6 +136,8 @@ class GcdPrivateAPIImpl : public EventRouter::Observer, void RemoveSession(int session_id); + scoped_ptr<base::ListValue> GetPrefetchedSSIDList(); + private: typedef std::map<std::string /* id_string */, linked_ptr<api::gcd_private::GCDDevice> > GCDDeviceMap; @@ -391,10 +393,7 @@ void GcdPrivateAPIImpl::SendMessage(int session_id, if (api == kPrivatAPISetup) { const base::DictionaryValue* wifi = NULL; - if (input.GetDictionary(kPrivetKeyWifi, &wifi) && - !wifi->HasKey(kPrivetKeyPassphrase)) { - // If the message is a setup message, has a wifi section, try sending the - // passphrase. + if (input.GetDictionary(kPrivetKeyWifi, &wifi)) { std::string ssid; if (!wifi->GetString(kPrivetKeySSID, &ssid)) { @@ -403,16 +402,21 @@ void GcdPrivateAPIImpl::SendMessage(int session_id, return; } - PasswordMap::iterator found = wifi_passwords_.find(ssid); - if (found == wifi_passwords_.end()) { - callback.Run(gcd_private::STATUS_WIFIPASSWORDERROR, - base::DictionaryValue()); - return; - } + if (!wifi->HasKey(kPrivetKeyPassphrase)) { + // If the message is a setup message, has a wifi section, try sending + // the passphrase. + + PasswordMap::iterator found = wifi_passwords_.find(ssid); + if (found == wifi_passwords_.end()) { + callback.Run(gcd_private::STATUS_WIFIPASSWORDERROR, + base::DictionaryValue()); + return; + } - input_cloned.reset(input.DeepCopy()); - input_cloned->SetString(kPrivetKeyPassphraseDotted, found->second); - input_actual = input_cloned.get(); + input_cloned.reset(input.DeepCopy()); + input_cloned->SetString(kPrivetKeyPassphraseDotted, found->second); + input_actual = input_cloned.get(); + } } } #endif @@ -467,6 +471,20 @@ void GcdPrivateAPIImpl::RemoveSession(int session_id) { sessions_.erase(session_id); } +scoped_ptr<base::ListValue> GcdPrivateAPIImpl::GetPrefetchedSSIDList() { + scoped_ptr<base::ListValue> retval(new base::ListValue); + +#if defined(ENABLE_WIFI_BOOTSTRAPPING) + for (PasswordMap::iterator i = wifi_passwords_.begin(); + i != wifi_passwords_.end(); + i++) { + retval->AppendString(i->first); + } +#endif + + return retval.Pass(); +} + GcdPrivateRequest::GcdPrivateRequest( const std::string& api, const base::DictionaryValue& input, @@ -686,9 +704,6 @@ GcdPrivateQueryForNewLocalDevicesFunction:: bool GcdPrivateQueryForNewLocalDevicesFunction::RunSync() { GcdPrivateAPIImpl* gcd_api = GcdPrivateAPIImpl::Get(GetProfile()); - if (!gcd_api) - return false; - if (!gcd_api->QueryForDevices()) { error_ = "You must first subscribe to onDeviceStateChanged or onDeviceRemoved " @@ -716,9 +731,6 @@ bool GcdPrivatePrefetchWifiPasswordFunction::RunAsync() { GcdPrivateAPIImpl* gcd_api = GcdPrivateAPIImpl::Get(GetProfile()); - if (!gcd_api) - return false; - gcd_api->RequestWifiPassword( params->ssid, base::Bind(&GcdPrivatePrefetchWifiPasswordFunction::OnResponse, this)); @@ -748,9 +760,6 @@ bool GcdPrivateEstablishSessionFunction::RunAsync() { GcdPrivateAPIImpl* gcd_api = GcdPrivateAPIImpl::Get(GetProfile()); - if (!gcd_api) - return false; - gcd_api->EstablishSession( params->ip_address, params->port, @@ -785,9 +794,6 @@ bool GcdPrivateConfirmCodeFunction::RunAsync() { GcdPrivateAPIImpl* gcd_api = GcdPrivateAPIImpl::Get(GetProfile()); - if (!gcd_api) - return false; - gcd_api->ConfirmCode( params->session_id, base::Bind(&GcdPrivateConfirmCodeFunction::OnSessionEstablishedCallback, @@ -817,8 +823,6 @@ bool GcdPrivateSendMessageFunction::RunAsync() { GcdPrivateAPIImpl* gcd_api = GcdPrivateAPIImpl::Get(GetProfile()); - if (!gcd_api) - return false; gcd_api->SendMessage( params->session_id, @@ -854,9 +858,6 @@ bool GcdPrivateTerminateSessionFunction::RunAsync() { GcdPrivateAPIImpl* gcd_api = GcdPrivateAPIImpl::Get(GetProfile()); - if (!gcd_api) - return false; - gcd_api->RemoveSession(params->session_id); SendResponse(true); @@ -871,6 +872,24 @@ GcdPrivateGetCommandDefinitionsFunction:: ~GcdPrivateGetCommandDefinitionsFunction() { } +GcdPrivateGetPrefetchedWifiNameListFunction:: + GcdPrivateGetPrefetchedWifiNameListFunction() { +} + +GcdPrivateGetPrefetchedWifiNameListFunction:: + ~GcdPrivateGetPrefetchedWifiNameListFunction() { +} + +bool GcdPrivateGetPrefetchedWifiNameListFunction::RunSync() { + GcdPrivateAPIImpl* gcd_api = GcdPrivateAPIImpl::Get(GetProfile()); + + scoped_ptr<base::ListValue> ssid_list = gcd_api->GetPrefetchedSSIDList(); + + SetResult(ssid_list.release()); + + return true; +} + bool GcdPrivateGetCommandDefinitionsFunction::RunAsync() { return false; } diff --git a/chrome/browser/extensions/api/gcd_private/gcd_private_api.h b/chrome/browser/extensions/api/gcd_private/gcd_private_api.h index 968da26..7e701c9 100644 --- a/chrome/browser/extensions/api/gcd_private/gcd_private_api.h +++ b/chrome/browser/extensions/api/gcd_private/gcd_private_api.h @@ -108,6 +108,21 @@ class GcdPrivatePrefetchWifiPasswordFunction void OnResponse(bool response); }; +class GcdPrivateGetPrefetchedWifiNameListFunction + : public ChromeSyncExtensionFunction { + public: + DECLARE_EXTENSION_FUNCTION("gcdPrivate.getPrefetchedWifiNameList", + GCDPRIVATE_GETPREFETCHEDWIFINAMELIST); + + GcdPrivateGetPrefetchedWifiNameListFunction(); + + protected: + virtual ~GcdPrivateGetPrefetchedWifiNameListFunction(); + + // SyncExtensionFunction overrides. + virtual bool RunSync() OVERRIDE; +}; + class GcdPrivateEstablishSessionFunction : public ChromeAsyncExtensionFunction { public: DECLARE_EXTENSION_FUNCTION("gcdPrivate.establishSession", diff --git a/chrome/browser/extensions/api/gcd_private/gcd_private_apitest.cc b/chrome/browser/extensions/api/gcd_private/gcd_private_apitest.cc index f6dfaac..328e068 100644 --- a/chrome/browser/extensions/api/gcd_private/gcd_private_apitest.cc +++ b/chrome/browser/extensions/api/gcd_private/gcd_private_apitest.cc @@ -10,6 +10,7 @@ #include "chrome/browser/extensions/extension_apitest.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/local_discovery/gcd_api_flow.h" +#include "chrome/browser/local_discovery/wifi/mock_wifi_manager.h" #include "chrome/common/extensions/api/mdns.h" #include "extensions/common/switches.h" #include "net/url_request/test_url_fetcher_factory.h" @@ -21,6 +22,8 @@ namespace api = extensions::api; +using testing::Invoke; + namespace { const char kCloudPrintResponse[] = @@ -232,6 +235,29 @@ class GcdPrivateAPITest : public ExtensionApiTest { "ddchlicdkolnonkihahngkmmmjnjlkkf"); } +#if defined(ENABLE_WIFI_BOOTSTRAPPING) + virtual void OnCreateWifiManager() { + wifi_manager_ = wifi_manager_factory_.GetLastCreatedWifiManager(); + + EXPECT_CALL(*wifi_manager_, Start()); + + EXPECT_CALL(*wifi_manager_, + RequestNetworkCredentialsInternal("SuccessNetwork")) + .WillOnce(Invoke(this, &GcdPrivateAPITest::RespondToNetwork)); + + EXPECT_CALL(*wifi_manager_, + RequestNetworkCredentialsInternal("FailureNetwork")) + .WillOnce(Invoke(this, &GcdPrivateAPITest::RespondToNetwork)); + } + + void RespondToNetwork(const std::string& network) { + bool success = (network == "SuccessNetwork"); + + wifi_manager_->CallRequestNetworkCredentialsCallback( + success, network, success ? "SuccessPass" : ""); + } +#endif + protected: FakeGCDApiFlowFactory api_flow_factory_; net::URLFetcherImplFactory url_fetcher_impl_factory_; @@ -241,6 +267,11 @@ class GcdPrivateAPITest : public ExtensionApiTest { scoped_refptr<local_discovery::TestServiceDiscoveryClient> test_service_discovery_client_; #endif // ENABLE_MDNS + +#if defined(ENABLE_WIFI_BOOTSTRAPPING) + local_discovery::wifi::MockWifiManagerFactory wifi_manager_factory_; + local_discovery::wifi::MockWifiManager* wifi_manager_; +#endif }; IN_PROC_BROWSER_TEST_F(GcdPrivateAPITest, GetCloudList) { @@ -319,4 +350,24 @@ IN_PROC_BROWSER_TEST_F(GcdPrivateAPITest, SendQuery) { #endif // ENABLE_MDNS +#if defined(ENABLE_WIFI_BOOTSTRAPPING) + +IN_PROC_BROWSER_TEST_F(GcdPrivateAPITest, WifiMessage) { + EXPECT_TRUE(RunExtensionSubtest("gcd_private/api", "wifi_message.html")); +} + +IN_PROC_BROWSER_TEST_F(GcdPrivateAPITest, WifiPasswords) { +// TODO(noamsml): Win Dbg has a workaround that makes RunExtensionSubtest +// always return true without actually running the test. Remove when fixed. +// See http://crbug.com/177163 for details. +#if !defined(OS_WIN) || defined(NDEBUG) + EXPECT_CALL(wifi_manager_factory_, WifiManagerCreated()) + .WillOnce(Invoke(this, &GcdPrivateAPITest::OnCreateWifiManager)); +#endif + + EXPECT_TRUE(RunExtensionSubtest("gcd_private/api", "wifi_password.html")); +} + +#endif // ENABLE_WIFI_BOOTSTRAPPING + } // namespace diff --git a/chrome/browser/local_discovery/wifi/mock_wifi_manager.cc b/chrome/browser/local_discovery/wifi/mock_wifi_manager.cc index e8540dcf..56aace6 100644 --- a/chrome/browser/local_discovery/wifi/mock_wifi_manager.cc +++ b/chrome/browser/local_discovery/wifi/mock_wifi_manager.cc @@ -85,9 +85,15 @@ MockWifiManagerFactory::~MockWifiManagerFactory() { scoped_ptr<WifiManager> MockWifiManagerFactory::CreateWifiManager() { last_created_manager_ = new MockWifiManager(); + WifiManagerCreated(); + return scoped_ptr<WifiManager>(last_created_manager_); } +MockWifiManager* MockWifiManagerFactory::GetLastCreatedWifiManager() { + return last_created_manager_; +} + } // namespace wifi } // namespace local_discovery diff --git a/chrome/browser/local_discovery/wifi/mock_wifi_manager.h b/chrome/browser/local_discovery/wifi/mock_wifi_manager.h index 270f16c..589abe7 100644 --- a/chrome/browser/local_discovery/wifi/mock_wifi_manager.h +++ b/chrome/browser/local_discovery/wifi/mock_wifi_manager.h @@ -82,6 +82,8 @@ class MockWifiManagerFactory : public WifiManagerFactory { MockWifiManager* GetLastCreatedWifiManager(); + MOCK_METHOD0(WifiManagerCreated, void()); + private: MockWifiManager* last_created_manager_; }; diff --git a/chrome/common/extensions/api/gcd_private.idl b/chrome/common/extensions/api/gcd_private.idl index c0fb64b..918a80d 100644 --- a/chrome/common/extensions/api/gcd_private.idl +++ b/chrome/common/extensions/api/gcd_private.idl @@ -96,6 +96,9 @@ namespace gcdPrivate { // |success| Denotes whether the password fetch has succeeded or failed. callback SuccessCallback = void(boolean success); + // Called as a response to |getPrefetchedWifiNameList| + // |list| the list of ssids for which wifi passwords were prefetched. + callback SSIDListCallback = void(DOMString[] networks); interface Functions { // Returns the list of cloud devices visible locally or available in the @@ -113,6 +116,9 @@ namespace gcdPrivate { // with true if wifi password was cached and false if it was unavailable. static void prefetchWifiPassword(DOMString ssid, SuccessCallback callback); + // Get the list of ssids with prefetched callbacks. + static void getPrefetchedWifiNameList(SSIDListCallback callback); + // Establish the session. static void establishSession(DOMString ipAddress, long port, diff --git a/chrome/test/data/extensions/api_test/gcd_private/api/wifi_message.html b/chrome/test/data/extensions/api_test/gcd_private/api/wifi_message.html new file mode 100644 index 0000000..875d684 --- /dev/null +++ b/chrome/test/data/extensions/api_test/gcd_private/api/wifi_message.html @@ -0,0 +1 @@ +<script src="wifi_message.js"></script> diff --git a/chrome/test/data/extensions/api_test/gcd_private/api/wifi_message.js b/chrome/test/data/extensions/api_test/gcd_private/api/wifi_message.js new file mode 100644 index 0000000..bdec7dc --- /dev/null +++ b/chrome/test/data/extensions/api_test/gcd_private/api/wifi_message.js @@ -0,0 +1,51 @@ +// Copyright 2014 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. + +onload = function() { + chrome.test.runTests([ + function wifiMessage() { + var messages_needed = 3; + function onConfirmCode(sessionId, status, code, method) { + chrome.test.assertEq("success", status); + chrome.test.assertEq("01234", code); + chrome.gcdPrivate.confirmCode(sessionId, + onSessionEstablished.bind(null, + sessionId)); + } + + function onSessionEstablished(sessionId, status) { + chrome.test.assertEq("success", status); + + chrome.gcdPrivate.sendMessage(sessionId, "/privet/v3/setup/start", { + "wifi" : { + } + }, onMessageSent.bind(null, "setupParseError")); + + chrome.gcdPrivate.sendMessage(sessionId, "/privet/v3/setup/start", { + "wifi" : { + "passphrase": "Blah" + } + }, onMessageSent.bind(null, "setupParseError")); + + chrome.gcdPrivate.sendMessage(sessionId, "/privet/v3/setup/start", { + "wifi" : { + "ssid": "Blah" + } + }, onMessageSent.bind(null, "wifiPasswordError")); + } + + function onMessageSent(expected_status, status, output) { + chrome.test.assertEq(expected_status, status); + messages_needed--; + console.log("Messages needed " + messages_needed); + + if (messages_needed == 0) { + chrome.test.notifyPass(); + } + } + + chrome.gcdPrivate.establishSession("1.2.3.4", 9090, onConfirmCode); + } + ]); +}; diff --git a/chrome/test/data/extensions/api_test/gcd_private/api/wifi_password.html b/chrome/test/data/extensions/api_test/gcd_private/api/wifi_password.html new file mode 100644 index 0000000..80d0173 --- /dev/null +++ b/chrome/test/data/extensions/api_test/gcd_private/api/wifi_password.html @@ -0,0 +1 @@ +<script src="wifi_password.js"></script> diff --git a/chrome/test/data/extensions/api_test/gcd_private/api/wifi_password.js b/chrome/test/data/extensions/api_test/gcd_private/api/wifi_password.js new file mode 100644 index 0000000..ad12257 --- /dev/null +++ b/chrome/test/data/extensions/api_test/gcd_private/api/wifi_password.js @@ -0,0 +1,35 @@ +// Copyright 2014 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. + +onload = function() { + chrome.test.runTests([ + function wifiPassword() { + var succeeded = false; + var failed = false; + + function expectResult(expectedResult, result) { + chrome.test.assertEq(expectedResult, result); + + if (expectedResult) succeeded = true; + else failed = true; + + if (succeeded && failed) { + chrome.gcdPrivate.getPrefetchedWifiNameList(onWifiList); + } + } + + function onWifiList(list) { + chrome.test.assertEq(["SuccessNetwork"], list); + + chrome.test.notifyPass(); + } + + chrome.gcdPrivate.prefetchWifiPassword("SuccessNetwork", + expectResult.bind(null, true)); + + chrome.gcdPrivate.prefetchWifiPassword("FailureNetwork", + expectResult.bind(null, false)); + } + ]); +}; |