diff options
author | bryeung@chromium.org <bryeung@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-15 07:32:46 +0000 |
---|---|---|
committer | bryeung@chromium.org <bryeung@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-15 07:32:46 +0000 |
commit | 3d72c95ba7461b3eaaa0c839bff6347eeff3fb0d (patch) | |
tree | cfef19c74063cb24e8d8f6d6cec60e979b0f8a0c | |
parent | c6c1f12ca1b1e4a62e89e2852f95f7e52c095f5a (diff) | |
download | chromium_src-3d72c95ba7461b3eaaa0c839bff6347eeff3fb0d.zip chromium_src-3d72c95ba7461b3eaaa0c839bff6347eeff3fb0d.tar.gz chromium_src-3d72c95ba7461b3eaaa0c839bff6347eeff3fb0d.tar.bz2 |
Implement the OOB Pairing APIs.
This depends on https://chromiumcodereview.appspot.com/10546010
TEST=new apitests added
BUG=119473
Review URL: https://chromiumcodereview.appspot.com/10544013
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@142346 0039d316-1c4b-4281-b951-d872f2087c98
4 files changed, 318 insertions, 19 deletions
diff --git a/chrome/browser/extensions/api/bluetooth/bluetooth_api.cc b/chrome/browser/extensions/api/bluetooth/bluetooth_api.cc index 7b80b96..3b6e034 100644 --- a/chrome/browser/extensions/api/bluetooth/bluetooth_api.cc +++ b/chrome/browser/extensions/api/bluetooth/bluetooth_api.cc @@ -4,6 +4,12 @@ #include "chrome/browser/extensions/api/bluetooth/bluetooth_api.h" +#if defined(OS_CHROMEOS) +#include <errno.h> +#endif + +#include <string> + #include "base/utf_string_conversions.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/profiles/profile.h" @@ -18,8 +24,7 @@ #include "chrome/browser/chromeos/bluetooth/bluetooth_device.h" #include "chrome/browser/chromeos/bluetooth/bluetooth_socket.h" #include "chrome/browser/chromeos/extensions/bluetooth_event_router.h" - -#include <errno.h> +#include "chromeos/dbus/bluetooth_out_of_band_client.h" using chromeos::BluetoothAdapter; using chromeos::BluetoothDevice; @@ -43,6 +48,12 @@ chromeos::BluetoothAdapter* GetMutableAdapter(Profile* profile) { namespace { +const char kCouldNotClearOutOfBandPairingData[] = + "Could not clear Out Of Band Pairing Data"; +const char kCouldNotGetLocalOutOfBandPairingData[] = + "Could not get local Out Of Band Pairing Data"; +const char kCouldNotSetOutOfBandPairingData[] = + "Could not set Out Of Band Pairing Data"; const char kFailedToConnect[] = "Connection failed"; const char kInvalidDevice[] = "Invalid device"; const char kSocketNotFoundError[] = "Socket not found: invalid socket id"; @@ -57,6 +68,10 @@ namespace GetDevicesWithServiceUUID = extensions::api::experimental_bluetooth::GetDevicesWithServiceUUID; namespace Read = extensions::api::experimental_bluetooth::Read; namespace Write = extensions::api::experimental_bluetooth::Write; +namespace SetOutOfBandPairingData = + extensions::api::experimental_bluetooth::SetOutOfBandPairingData; +namespace ClearOutOfBandPairingData = + extensions::api::experimental_bluetooth::ClearOutOfBandPairingData; namespace extensions { namespace api { @@ -186,7 +201,7 @@ bool BluetoothConnectFunction::RunImpl() { return false; } - AddRef(); + AddRef(); // Released in ConnectToServiceCallback device->ConnectToService(params->service, base::Bind(&BluetoothConnectFunction::ConnectToServiceCallback, this, @@ -302,6 +317,131 @@ bool BluetoothWriteFunction::Respond() { return success_; } +void BluetoothSetOutOfBandPairingDataFunction::OnSuccessCallback() { + SendResponse(true); + Release(); // Added in RunImpl +} + +void BluetoothSetOutOfBandPairingDataFunction::OnErrorCallback() { + SetError(kCouldNotSetOutOfBandPairingData); + SendResponse(false); + Release(); // Added in RunImpl +} + +bool BluetoothSetOutOfBandPairingDataFunction::RunImpl() { + // TODO(bryeung): update to new-style parameter passing when ArrayBuffer + // support is added + std::string address; + EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &address)); + DictionaryValue* data_in; + EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(1, &data_in)); + + chromeos::BluetoothOutOfBandPairingData data_out; + + base::BinaryValue* tmp_data; + EXTENSION_FUNCTION_VALIDATE(data_in->GetBinary("hash", &tmp_data)); + EXTENSION_FUNCTION_VALIDATE( + tmp_data->GetSize() == chromeos::kBluetoothOutOfBandPairingDataSize); + memcpy(data_out.hash, + reinterpret_cast<uint8_t*>(tmp_data->GetBuffer()), + chromeos::kBluetoothOutOfBandPairingDataSize); + + EXTENSION_FUNCTION_VALIDATE(data_in->GetBinary("randomizer", &tmp_data)); + EXTENSION_FUNCTION_VALIDATE( + tmp_data->GetSize() == chromeos::kBluetoothOutOfBandPairingDataSize); + memcpy(data_out.randomizer, + reinterpret_cast<uint8_t*>(tmp_data->GetBuffer()), + chromeos::kBluetoothOutOfBandPairingDataSize); + + chromeos::BluetoothDevice* device = + GetMutableAdapter(profile())->GetDevice(address); + if (!device) { + SendResponse(false); + SetError(kInvalidDevice); + return false; + } + + AddRef(); + device->SetOutOfBandPairingData( + data_out, + base::Bind(&BluetoothSetOutOfBandPairingDataFunction::OnSuccessCallback, + this), + base::Bind(&BluetoothSetOutOfBandPairingDataFunction::OnErrorCallback, + this)); + + return true; +} + +void BluetoothGetLocalOutOfBandPairingDataFunction::ReadCallback( + const chromeos::BluetoothOutOfBandPairingData& data) { + base::BinaryValue* hash = base::BinaryValue::CreateWithCopiedBuffer( + reinterpret_cast<const char*>(data.hash), + chromeos::kBluetoothOutOfBandPairingDataSize); + base::BinaryValue* randomizer = base::BinaryValue::CreateWithCopiedBuffer( + reinterpret_cast<const char*>(data.randomizer), + chromeos::kBluetoothOutOfBandPairingDataSize); + + // TODO(bryeung): convert to experimental_bluetooth::OutOfBandPairingData + // when ArrayBuffer support within objects is completed. + DictionaryValue* result = new DictionaryValue(); + result->Set("hash", hash); + result->Set("randomizer", randomizer); + + result_.reset(result); + + SendResponse(true); + Release(); // Added in RunImpl +} + +void BluetoothGetLocalOutOfBandPairingDataFunction::ErrorCallback() { + SetError(kCouldNotGetLocalOutOfBandPairingData); + SendResponse(false); + Release(); // Added in RunImpl +} + +bool BluetoothGetLocalOutOfBandPairingDataFunction::RunImpl() { + AddRef(); // Released in one of the callbacks below + GetMutableAdapter(profile())->ReadLocalOutOfBandPairingData( + base::Bind(&BluetoothGetLocalOutOfBandPairingDataFunction::ReadCallback, + this), + base::Bind(&BluetoothGetLocalOutOfBandPairingDataFunction::ErrorCallback, + this)); + return true; +} + +void BluetoothClearOutOfBandPairingDataFunction::OnSuccessCallback() { + SendResponse(true); + Release(); // Added in RunImpl +} + +void BluetoothClearOutOfBandPairingDataFunction::OnErrorCallback() { + SetError(kCouldNotClearOutOfBandPairingData); + SendResponse(false); + Release(); // Added in RunImpl +} + +bool BluetoothClearOutOfBandPairingDataFunction::RunImpl() { + scoped_ptr<ClearOutOfBandPairingData::Params> params( + ClearOutOfBandPairingData::Params::Create(*args_)); + EXTENSION_FUNCTION_VALIDATE(params.get() != NULL); + + chromeos::BluetoothDevice* device = + GetMutableAdapter(profile())->GetDevice(params->address); + if (!device) { + SendResponse(false); + SetError(kInvalidDevice); + return false; + } + + AddRef(); // Released in one of the callbacks below + device->ClearOutOfBandPairingData( + base::Bind(&BluetoothClearOutOfBandPairingDataFunction::OnSuccessCallback, + this), + base::Bind(&BluetoothClearOutOfBandPairingDataFunction::OnErrorCallback, + this)); + return true; +} + #else // ----------------------------------------------------------------------------- @@ -366,23 +506,28 @@ bool BluetoothWriteFunction::Respond() { return false; } -#endif - -BluetoothReadFunction::BluetoothReadFunction() {} -BluetoothReadFunction::~BluetoothReadFunction() {} - -BluetoothWriteFunction::BluetoothWriteFunction() {} -BluetoothWriteFunction::~BluetoothWriteFunction() {} - bool BluetoothSetOutOfBandPairingDataFunction::RunImpl() { NOTREACHED() << "Not implemented yet"; return false; } -bool BluetoothGetOutOfBandPairingDataFunction::RunImpl() { +bool BluetoothGetLocalOutOfBandPairingDataFunction::RunImpl() { + NOTREACHED() << "Not implemented yet"; + return false; +} + +bool BluetoothClearOutOfBandPairingDataFunction::RunImpl() { NOTREACHED() << "Not implemented yet"; return false; } +#endif + +BluetoothReadFunction::BluetoothReadFunction() {} +BluetoothReadFunction::~BluetoothReadFunction() {} + +BluetoothWriteFunction::BluetoothWriteFunction() {} +BluetoothWriteFunction::~BluetoothWriteFunction() {} + } // namespace api } // namespace extensions diff --git a/chrome/browser/extensions/api/bluetooth/bluetooth_api.h b/chrome/browser/extensions/api/bluetooth/bluetooth_api.h index deac340..4096d96 100644 --- a/chrome/browser/extensions/api/bluetooth/bluetooth_api.h +++ b/chrome/browser/extensions/api/bluetooth/bluetooth_api.h @@ -6,6 +6,8 @@ #define CHROME_BROWSER_EXTENSIONS_API_BLUETOOTH_BLUETOOTH_API_H_ #pragma once +#include <string> + #include "chrome/browser/extensions/api/api_function.h" #include "chrome/browser/extensions/extension_function.h" @@ -17,6 +19,7 @@ namespace chromeos { class BluetoothDevice; class BluetoothSocket; +struct BluetoothOutOfBandPairingData; } // namespace chromeos #endif @@ -166,7 +169,7 @@ class BluetoothWriteFunction : public AsyncAPIFunction { }; class BluetoothSetOutOfBandPairingDataFunction - : public SyncExtensionFunction { + : public AsyncExtensionFunction { public: DECLARE_EXTENSION_FUNCTION_NAME( "experimental.bluetooth.setOutOfBandPairingData") @@ -174,18 +177,46 @@ class BluetoothSetOutOfBandPairingDataFunction protected: virtual ~BluetoothSetOutOfBandPairingDataFunction() {} +#if defined(OS_CHROMEOS) + void OnSuccessCallback(); + void OnErrorCallback(); +#endif + // ExtensionFunction: virtual bool RunImpl() OVERRIDE; }; -class BluetoothGetOutOfBandPairingDataFunction - : public SyncExtensionFunction { +class BluetoothGetLocalOutOfBandPairingDataFunction + : public AsyncExtensionFunction { + public: + DECLARE_EXTENSION_FUNCTION_NAME( + "experimental.bluetooth.getLocalOutOfBandPairingData") + + protected: + virtual ~BluetoothGetLocalOutOfBandPairingDataFunction() {} + +#if defined(OS_CHROMEOS) + void ReadCallback(const chromeos::BluetoothOutOfBandPairingData& data); + void ErrorCallback(); +#endif + + // ExtensionFunction: + virtual bool RunImpl() OVERRIDE; +}; + +class BluetoothClearOutOfBandPairingDataFunction + : public AsyncExtensionFunction { public: DECLARE_EXTENSION_FUNCTION_NAME( - "experimental.bluetooth.getOutOfBandPairingData") + "experimental.bluetooth.clearOutOfBandPairingData") protected: - virtual ~BluetoothGetOutOfBandPairingDataFunction() {} + virtual ~BluetoothClearOutOfBandPairingDataFunction() {} + +#if defined(OS_CHROMEOS) + void OnSuccessCallback(); + void OnErrorCallback(); +#endif // ExtensionFunction: virtual bool RunImpl() OVERRIDE; diff --git a/chrome/browser/extensions/api/bluetooth/bluetooth_apitest_chromeos.cc b/chrome/browser/extensions/api/bluetooth/bluetooth_apitest_chromeos.cc index 2d91e7e..4e0602f 100644 --- a/chrome/browser/extensions/api/bluetooth/bluetooth_apitest_chromeos.cc +++ b/chrome/browser/extensions/api/bluetooth/bluetooth_apitest_chromeos.cc @@ -2,6 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <string.h> + +#include "chrome/browser/chromeos/bluetooth/bluetooth_adapter.h" #include "chrome/browser/chromeos/bluetooth/test/mock_bluetooth_adapter.h" #include "chrome/browser/chromeos/bluetooth/test/mock_bluetooth_device.h" #include "chrome/browser/chromeos/extensions/bluetooth_event_router.h" @@ -11,6 +14,7 @@ #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/extension_test_message_listener.h" #include "chrome/browser/ui/browser.h" +#include "chromeos/dbus/bluetooth_out_of_band_client.h" #include "testing/gmock/include/gmock/gmock.h" using extensions::Extension; @@ -42,6 +46,7 @@ class BluetoothApiTest : public PlatformAppApiTest { const std::string& args) { scoped_ptr<base::Value> result( utils::RunFunctionAndReturnResult(function, args, browser())); + ASSERT_TRUE(result.get() != NULL); ASSERT_EQ(base::Value::TYPE_BOOLEAN, result->GetType()); bool boolean_value; result->GetAsBoolean(&boolean_value); @@ -68,6 +73,30 @@ class BluetoothApiTest : public PlatformAppApiTest { scoped_refptr<Extension> empty_extension_; }; +static const char kOutOfBandPairingDataHash[] = "0123456789ABCDEh"; +static const char kOutOfBandPairingDataRandomizer[] = "0123456789ABCDEr"; + +static chromeos::BluetoothOutOfBandPairingData GetOutOfBandPairingData() { + chromeos::BluetoothOutOfBandPairingData data; + memcpy(&(data.hash), kOutOfBandPairingDataHash, + chromeos::kBluetoothOutOfBandPairingDataSize); + memcpy(&(data.randomizer), kOutOfBandPairingDataRandomizer, + chromeos::kBluetoothOutOfBandPairingDataSize); + return data; +} + +static bool CallClosure(const base::Closure& callback) { + callback.Run(); + return true; +} + +static bool CallOutOfBandPairingDataCallback( + const chromeos::BluetoothAdapter::BluetoothOutOfBandPairingDataCallback& + callback) { + callback.Run(GetOutOfBandPairingData()); + return true; +} + } // namespace IN_PROC_BROWSER_TEST_F(BluetoothApiTest, IsAvailable) { @@ -143,3 +172,88 @@ IN_PROC_BROWSER_TEST_F(BluetoothApiTest, GetDevicesWithServiceUUID) { ASSERT_TRUE(device->GetString("name", &name)); EXPECT_EQ("d2", name); } + +IN_PROC_BROWSER_TEST_F(BluetoothApiTest, GetLocalOutOfBandPairingData) { + EXPECT_CALL(*mock_adapter_, + ReadLocalOutOfBandPairingData( + testing::Truly(CallOutOfBandPairingDataCallback), + testing::_)); + + scoped_refptr<api::BluetoothGetLocalOutOfBandPairingDataFunction> + get_oob_function(setupFunction( + new api::BluetoothGetLocalOutOfBandPairingDataFunction)); + + scoped_ptr<base::Value> result( + utils::RunFunctionAndReturnResult(get_oob_function, "[]", browser())); + + base::DictionaryValue* dict; + EXPECT_TRUE(result->GetAsDictionary(&dict)); + + base::BinaryValue* binary_value; + EXPECT_TRUE(dict->GetBinary("hash", &binary_value)); + EXPECT_STREQ(kOutOfBandPairingDataHash, + std::string(binary_value->GetBuffer(), binary_value->GetSize()).c_str()); + EXPECT_TRUE(dict->GetBinary("randomizer", &binary_value)); + EXPECT_STREQ(kOutOfBandPairingDataRandomizer, + std::string(binary_value->GetBuffer(), binary_value->GetSize()).c_str()); + + // Try again with an error + testing::Mock::VerifyAndClearExpectations(mock_adapter_); + EXPECT_CALL(*mock_adapter_, + ReadLocalOutOfBandPairingData( + testing::_, + testing::Truly(CallClosure))); + + get_oob_function = + setupFunction(new api::BluetoothGetLocalOutOfBandPairingDataFunction); + + std::string error( + utils::RunFunctionAndReturnError(get_oob_function, "[]", browser())); + EXPECT_FALSE(error.empty()); +} + +IN_PROC_BROWSER_TEST_F(BluetoothApiTest, DISABLED_SetOutOfBandPairingData) { + // TODO(bryeung): Fill in this test once it is possible to include an + // ArrayBuffer in the arguments to the RunFunctionAnd* methods. + // crbug.com/132796 +} + +IN_PROC_BROWSER_TEST_F(BluetoothApiTest, ClearOutOfBandPairingData) { + std::string device_address("11:12:13:14:15:16"); + testing::NiceMock<chromeos::MockBluetoothDevice> device( + mock_adapter_, "d1", device_address); + EXPECT_CALL(*mock_adapter_, GetDevice(device_address)) + .WillOnce(testing::Return(&device)); + EXPECT_CALL(device, + ClearOutOfBandPairingData( + testing::Truly(CallClosure), + testing::_)); + + char buf[32]; + snprintf(buf, sizeof(buf), "[\"%s\"]", device_address.c_str()); + std::string params(buf); + + scoped_refptr<api::BluetoothClearOutOfBandPairingDataFunction> + clear_oob_function; + clear_oob_function = setupFunction( + new api::BluetoothClearOutOfBandPairingDataFunction); + // There isn't actually a result. + (void)utils::RunFunctionAndReturnResult( + clear_oob_function, params, browser()); + + // Try again with an error + testing::Mock::VerifyAndClearExpectations(mock_adapter_); + testing::Mock::VerifyAndClearExpectations(&device); + EXPECT_CALL(*mock_adapter_, GetDevice(device_address)) + .WillOnce(testing::Return(&device)); + EXPECT_CALL(device, + ClearOutOfBandPairingData( + testing::_, + testing::Truly(CallClosure))); + + clear_oob_function = setupFunction( + new api::BluetoothClearOutOfBandPairingDataFunction); + std::string error( + utils::RunFunctionAndReturnError(clear_oob_function, params, browser())); + EXPECT_FALSE(error.empty()); +} diff --git a/chrome/common/extensions/api/experimental_bluetooth.idl b/chrome/common/extensions/api/experimental_bluetooth.idl index f7408eb..d38a3c0 100644 --- a/chrome/common/extensions/api/experimental_bluetooth.idl +++ b/chrome/common/extensions/api/experimental_bluetooth.idl @@ -91,9 +91,11 @@ // Get the local Out of Band Pairing data. // |callback| : Called with the data. - static void getOutOfBandPairingData(OutOfBandPairingDataCallback callback); + static void getLocalOutOfBandPairingData( + OutOfBandPairingDataCallback callback); - // Set the Out of Band Pairing data for the bluetooth device at |address|. + // Set the Out Of Band Pairing Data for the bluetooth device at |address|. + // Any previous Out Of Band Pairing Data for this device is overwritten. // |address| : The bluetooth address of the device sending the data. // |data| : The data. // |callback| : Called to indicate success or failure. @@ -101,6 +103,13 @@ DOMString address, OutOfBandPairingData data, optional ResultCallback callback); + + // Clear any Out Of Band Pairing Data for the bluetooth device at |address|. + // |address| : The bluetooth address for which data should be cleared. + // |callback| : Called to indicate success or failure. + static void clearOutOfBandPairingData( + DOMString address, + optional ResultCallback callback); }; interface Events { |