Chromium Code Reviews| Index: chrome/browser/extensions/api/networking_private/networking_private_service_client.cc |
| 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 0000000000000000000000000000000000000000..24c156d44f1333339e0cb1ca086ad0932d72791f |
| --- /dev/null |
| +++ b/chrome/browser/extensions/api/networking_private/networking_private_service_client.cc |
| @@ -0,0 +1,479 @@ |
| +// 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/browser/profiles/profile.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 ShutdownWiFiServiceOnWorkerThread( |
| + wifi::WiFiService* wifi_service, |
| + NetworkingPrivateServiceClient::CryptoVerify* crypto_verify) { |
| + DCHECK(wifi_service); |
| + DCHECK(crypto_verify); |
| + delete wifi_service; |
| + delete crypto_verify; |
| +} |
| +} // namespace |
| + |
| +NetworkingPrivateServiceClient::NetworkingPrivateServiceClient( |
| + Profile* profile, |
| + wifi::WiFiService* wifi_service, |
| + CryptoVerify* crypto_verify) |
| + : profile_(profile), |
| + 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); |
| + wifi_service_->SetEventObservers( |
| + BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI), |
|
tbarzic
2013/11/15 22:56:30
you can use base::MessageLoopProxy::current()
But,
mef
2013/11/17 20:05:18
Wouldn't doing thread hoping here break agreement
tbarzic
2013/11/19 00:05:44
Not necessarily. You'd have to wrap the callback w
|
| + base::Bind( |
| + &NetworkingPrivateServiceClient::OnNetworksChangedEventOnUIThread, |
| + weak_factory_.GetWeakPtr()), |
| + base::Bind( |
| + &NetworkingPrivateServiceClient::OnNetworkListChangedEventOnUIThread, |
| + weak_factory_.GetWeakPtr())); |
| +} |
| + |
| +NetworkingPrivateServiceClient::~NetworkingPrivateServiceClient() { } |
| + |
| +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(); |
| + |
| + task_runner_->PostTask( |
| + FROM_HERE, |
| + base::Bind(&ShutdownWiFiServiceOnWorkerThread, |
| + base::Unretained(wifi_service_), |
| + base::Unretained(crypto_verify_))); |
| + wifi_service_ = NULL; |
| + crypto_verify_ = NULL; |
| +} |
| + |
| +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_), |
| + 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_), |
| + 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_))); |
| +} |
| + |
| +void NetworkingPrivateServiceClient::SetProperties( |
| + const std::string& network_guid, |
| + const base::DictionaryValue& properties, |
| + const VoidResultCallback& 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_), |
| + network_guid, |
| + 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 VoidResultCallback& 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_), |
| + 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 VoidResultCallback& 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_), |
| + 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_), |
| + 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_), |
| + Passed(&args), |
| + result, |
| + error), |
| + base::Bind(&NetworkingPrivateServiceClient::AfterVerifyAndEncryptData, |
| + weak_factory_.GetWeakPtr(), |
| + service_callbacks->id, |
| + base::Owned(result), |
| + base::Owned(error))); |
| +} |
| + |
| +bool NetworkingPrivateServiceClient::CheckServiceError( |
| + ServiceCallbacks* service_callbacks, |
|
tbarzic
2013/11/15 22:56:30
you can remove this now
mef
2013/11/17 20:05:18
Done.
|
| + const std::string& error) { |
| + if (!error.empty()) { |
| + DCHECK(service_callbacks); |
| + DCHECK(!service_callbacks->error_callback.is_null()); |
| + scoped_ptr<DictionaryValue> error_data_ptr(new DictionaryValue()); |
| + service_callbacks->error_callback.Run(error, |
| + error_data_ptr.Pass()); |
| + return true; |
| + } |
| + return false; |
| +} |
| + |
| +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 |