diff options
author | armansito@chromium.org <armansito@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-23 21:49:47 +0000 |
---|---|---|
committer | armansito@chromium.org <armansito@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-23 21:49:47 +0000 |
commit | 911a934c82a000c6632d4ce5403e6e4e6911f0b8 (patch) | |
tree | a29bcdd7f9db4959fc6a91d22b9231ba09e5bc38 | |
parent | 741588f90638dd4ac004afa89f48a62d6aab975e (diff) | |
download | chromium_src-911a934c82a000c6632d4ce5403e6e4e6911f0b8.zip chromium_src-911a934c82a000c6632d4ce5403e6e4e6911f0b8.tar.gz chromium_src-911a934c82a000c6632d4ce5403e6e4e6911f0b8.tar.bz2 |
chrome.bluetoothLowEnergy: Implement writeDescriptorValue.
This CL implements the writeDescriptorValue function of the bluetoothLowEnergy
API.
BUG=265663
TEST=browser_tests --gtest_filter=BluetoothLowEnergyApiTest.*
Review URL: https://codereview.chromium.org/293153002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@272600 0039d316-1c4b-4281-b951-d872f2087c98
8 files changed, 206 insertions, 4 deletions
diff --git a/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_api.cc b/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_api.cc index fe71360..4c29506 100644 --- a/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_api.cc +++ b/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_api.cc @@ -37,6 +37,8 @@ const char kErrorPlatformNotSupported[] = "This operation is not supported on the current platform"; const char kErrorWriteCharacteristicValueFailedFormat[] = "Failed to write value of characteristic with ID \"%s\"."; +const char kErrorWriteDescriptorValueFailedFormat[] = + "Failed to write value of descriptor with ID \"%s\"."; extensions::BluetoothLowEnergyEventRouter* GetEventRouter( BrowserContext* context) { @@ -550,10 +552,53 @@ void BluetoothLowEnergyReadDescriptorValueFunction::ErrorCallback() { } bool BluetoothLowEnergyWriteDescriptorValueFunction::DoWork() { - // TODO(armansito): Implement. - SetError("Call not supported."); + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + + BluetoothLowEnergyEventRouter* event_router = + GetEventRouter(browser_context()); + + // The adapter must be initialized at this point, but return an error instead + // of asserting. + if (!event_router->HasAdapter()) { + SetError(kErrorAdapterNotInitialized); + SendResponse(false); + return false; + } + + scoped_ptr<apibtle::WriteDescriptorValue::Params> params( + apibtle::WriteDescriptorValue::Params::Create(*args_)); + EXTENSION_FUNCTION_VALIDATE(params.get() != NULL); + + instance_id_ = params->descriptor_id; + std::vector<uint8> value(params->value.begin(), params->value.end()); + + if (!event_router->WriteDescriptorValue( + instance_id_, + value, + base::Bind( + &BluetoothLowEnergyWriteDescriptorValueFunction::SuccessCallback, + this), + base::Bind( + &BluetoothLowEnergyWriteDescriptorValueFunction::ErrorCallback, + this))) { + SetError(base::StringPrintf(kErrorDescriptorNotFoundFormat, + instance_id_.c_str())); + SendResponse(false); + return false; + } + + return true; +} + +void BluetoothLowEnergyWriteDescriptorValueFunction::SuccessCallback() { + results_ = apibtle::WriteDescriptorValue::Results::Create(); + SendResponse(true); +} + +void BluetoothLowEnergyWriteDescriptorValueFunction::ErrorCallback() { + SetError(base::StringPrintf(kErrorWriteDescriptorValueFailedFormat, + instance_id_.c_str())); SendResponse(false); - return false; } } // namespace api diff --git a/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_api.h b/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_api.h index f817adb..f455b9a 100644 --- a/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_api.h +++ b/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_api.h @@ -241,6 +241,15 @@ class BluetoothLowEnergyWriteDescriptorValueFunction // BluetoothLowEnergyExtensionFunction override. virtual bool DoWork() OVERRIDE; + + private: + // Success and error callbacks, called by + // BluetoothLowEnergyEventRouter::WriteDescriptorValue. + void SuccessCallback(); + void ErrorCallback(); + + // The instance ID of the requested descriptor. + std::string instance_id_; }; } // namespace api diff --git a/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_apitest.cc b/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_apitest.cc index 4f838bd..2682f7df 100644 --- a/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_apitest.cc +++ b/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_apitest.cc @@ -903,4 +903,53 @@ IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, ReadDescriptorValue) { event_router()->DeviceRemoved(mock_adapter_, device_.get()); } +IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, WriteDescriptorValue) { + ResultCatcher catcher; + catcher.RestrictToProfile(browser()->profile()); + + event_router()->DeviceAdded(mock_adapter_, device_.get()); + event_router()->GattServiceAdded(device_.get(), service0_.get()); + event_router()->GattCharacteristicAdded(service0_.get(), chrc0_.get()); + event_router()->GattDescriptorAdded(chrc0_.get(), desc0_.get()); + + EXPECT_CALL(*mock_adapter_, GetDevice(_)) + .Times(3) + .WillRepeatedly(Return(device_.get())); + + EXPECT_CALL(*device_, GetGattService(kTestServiceId0)) + .Times(3) + .WillRepeatedly(Return(service0_.get())); + + EXPECT_CALL(*service0_, GetCharacteristic(kTestCharacteristicId0)) + .Times(3) + .WillRepeatedly(Return(chrc0_.get())); + + EXPECT_CALL(*chrc0_, GetDescriptor(kTestDescriptorId0)) + .Times(3) + .WillRepeatedly(Return(desc0_.get())); + + std::vector<uint8> write_value; + EXPECT_CALL(*desc0_, WriteRemoteDescriptor(_, _, _)) + .Times(2) + .WillOnce(Invoke(&WriteValueErrorCallback)) + .WillOnce( + DoAll(SaveArg<0>(&write_value), Invoke(&WriteValueSuccessCallback))); + + EXPECT_CALL(*desc0_, GetValue()).Times(1).WillOnce(ReturnRef(write_value)); + + ExtensionTestMessageListener listener("ready", true); + ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII( + "bluetooth_low_energy/write_descriptor_value"))); + EXPECT_TRUE(listener.WaitUntilSatisfied()); + + listener.Reply("go"); + + EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); + + event_router()->GattDescriptorRemoved(chrc0_.get(), desc0_.get()); + event_router()->GattCharacteristicRemoved(service0_.get(), chrc0_.get()); + event_router()->GattServiceRemoved(device_.get(), service0_.get()); + event_router()->DeviceRemoved(mock_adapter_, device_.get()); +} + } // namespace diff --git a/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_event_router.cc b/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_event_router.cc index 385e0db..947d84e 100644 --- a/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_event_router.cc +++ b/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_event_router.cc @@ -465,6 +465,27 @@ bool BluetoothLowEnergyEventRouter::ReadDescriptorValue( return true; } +bool BluetoothLowEnergyEventRouter::WriteDescriptorValue( + const std::string& instance_id, + const std::vector<uint8>& value, + const base::Closure& callback, + const base::Closure& error_callback) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + if (!adapter_) { + VLOG(1) << "BluetoothAdapter not ready."; + return false; + } + + BluetoothGattDescriptor* descriptor = FindDescriptorById(instance_id); + if (!descriptor) { + VLOG(1) << "Descriptor not found: " << instance_id; + return false; + } + + descriptor->WriteRemoteDescriptor(value, callback, error_callback); + return true; +} + void BluetoothLowEnergyEventRouter::SetAdapterForTesting( device::BluetoothAdapter* adapter) { adapter_ = adapter; diff --git a/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_event_router.h b/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_event_router.h index 86631aa..8b606be 100644 --- a/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_event_router.h +++ b/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_event_router.h @@ -148,6 +148,15 @@ class BluetoothLowEnergyEventRouter const base::Closure& callback, const base::Closure& error_callback); + // Sends a request to write the value of the descriptor with instance ID + // |instance_id|, with value |value|. Returns false, if no such descriptor + // is known. Otherwise, returns true and invokes |callback| on success and + // |error_callback| on failure. + bool WriteDescriptorValue(const std::string& instance_id, + const std::vector<uint8>& value, + const base::Closure& callback, + const base::Closure& error_callback); + // Initializes the adapter for testing. Used by unit tests only. void SetAdapterForTesting(device::BluetoothAdapter* adapter); diff --git a/chrome/test/data/extensions/api_test/bluetooth_low_energy/write_characteristic_value/runtest.js b/chrome/test/data/extensions/api_test/bluetooth_low_energy/write_characteristic_value/runtest.js index 017664c..51fd4e9 100644 --- a/chrome/test/data/extensions/api_test/bluetooth_low_energy/write_characteristic_value/runtest.js +++ b/chrome/test/data/extensions/api_test/bluetooth_low_energy/write_characteristic_value/runtest.js @@ -23,6 +23,7 @@ var charId = 'char_id0'; var badCharId = 'char_id1'; var characteristic = null; + var bytes = [0x43, 0x68, 0x72, 0x6F, 0x6D, 0x65]; var writeValue = new ArrayBuffer(bytes.length); var valueBytes = new Uint8Array(writeValue); @@ -31,7 +32,7 @@ valueBytes.set(bytes); // 1. Unknown characteristic instanceId. writeCharacteristicValue(badCharId, writeValue, function (result) { if (result || !chrome.runtime.lastError) { - chrome.test.fail('badCharId did not cause failure'); + chrome.test.fail('\'badCharId\' did not cause failure'); } // 2. Known characteristic instanceId, but call failure. diff --git a/chrome/test/data/extensions/api_test/bluetooth_low_energy/write_descriptor_value/manifest.json b/chrome/test/data/extensions/api_test/bluetooth_low_energy/write_descriptor_value/manifest.json new file mode 100644 index 0000000..e2f054f --- /dev/null +++ b/chrome/test/data/extensions/api_test/bluetooth_low_energy/write_descriptor_value/manifest.json @@ -0,0 +1,11 @@ +{ + "manifest_version": 2, + "name": "Test the Bluetooth Low Energy writeDescriptorValue API", + "version": "1.0", + "app": { + "background": { + "scripts": ["runtest.js"] + } + }, + "bluetooth": {} +} diff --git a/chrome/test/data/extensions/api_test/bluetooth_low_energy/write_descriptor_value/runtest.js b/chrome/test/data/extensions/api_test/bluetooth_low_energy/write_descriptor_value/runtest.js new file mode 100644 index 0000000..ca687b1 --- /dev/null +++ b/chrome/test/data/extensions/api_test/bluetooth_low_energy/write_descriptor_value/runtest.js @@ -0,0 +1,57 @@ +// 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. + +function testWriteDescriptorValue() { + chrome.test.assertTrue(descriptor != null, '\'descriptor\' is null'); + chrome.test.assertEq(descId, descriptor.instanceId); + + chrome.test.assertEq(writeValue.byteLength, descriptor.value.byteLength); + + var receivedValueBytes = new Uint8Array(descriptor.value); + for (var i = 0; i < writeValue.byteLength; i++) { + chrome.test.assertEq(valueBytes[i], receivedValueBytes[i]); + } + + chrome.test.succeed(); +} + +var writeDescriptorValue = chrome.bluetoothLowEnergy.writeDescriptorValue; +var descId = 'desc_id0'; +var badDescId = 'desc_id1'; + +var descriptor = null; + +var bytes = [0x43, 0x68, 0x72, 0x6F, 0x6D, 0x65]; +var writeValue = new ArrayBuffer(bytes.length); +var valueBytes = new Uint8Array(writeValue); +valueBytes.set(bytes); + +// 1. Unknown descriptor instanceId. +writeDescriptorValue(badDescId, writeValue, function (result) { + if (result || !chrome.runtime.lastError) { + chrome.test.fail('\'badDescId\' did not cause failure'); + } + + // 2. Known descriptor instanceId, but call failure. + writeDescriptorValue(descId, writeValue, function (result) { + if (result || !chrome.runtime.lastError) { + chrome.test.fail('writeDescriptorValue should have failed'); + } + + // 3. Call should succeed. + writeDescriptorValue(descId, writeValue, function (result) { + if (chrome.runtime.lastError) { + chrome.test.fail(chrome.runtime.lastError.message); + } + + chrome.bluetoothLowEnergy.getDescriptor(descId, function (result) { + descriptor = result; + + chrome.test.sendMessage('ready', function (message) { + chrome.test.runTests([testWriteDescriptorValue]); + }); + }); + }); + }); +}); |