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
parent 741588f9
...@@ -37,6 +37,8 @@ const char kErrorPlatformNotSupported[] = ...@@ -37,6 +37,8 @@ const char kErrorPlatformNotSupported[] =
"This operation is not supported on the current platform"; "This operation is not supported on the current platform";
const char kErrorWriteCharacteristicValueFailedFormat[] = const char kErrorWriteCharacteristicValueFailedFormat[] =
"Failed to write value of characteristic with ID \"%s\"."; "Failed to write value of characteristic with ID \"%s\".";
const char kErrorWriteDescriptorValueFailedFormat[] =
"Failed to write value of descriptor with ID \"%s\".";
extensions::BluetoothLowEnergyEventRouter* GetEventRouter( extensions::BluetoothLowEnergyEventRouter* GetEventRouter(
BrowserContext* context) { BrowserContext* context) {
...@@ -550,10 +552,53 @@ void BluetoothLowEnergyReadDescriptorValueFunction::ErrorCallback() { ...@@ -550,10 +552,53 @@ void BluetoothLowEnergyReadDescriptorValueFunction::ErrorCallback() {
} }
bool BluetoothLowEnergyWriteDescriptorValueFunction::DoWork() { bool BluetoothLowEnergyWriteDescriptorValueFunction::DoWork() {
// TODO(armansito): Implement. DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
SetError("Call not supported.");
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); SendResponse(false);
return false;
} }
} // namespace api } // namespace api
......
...@@ -241,6 +241,15 @@ class BluetoothLowEnergyWriteDescriptorValueFunction ...@@ -241,6 +241,15 @@ class BluetoothLowEnergyWriteDescriptorValueFunction
// BluetoothLowEnergyExtensionFunction override. // BluetoothLowEnergyExtensionFunction override.
virtual bool DoWork() 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 } // namespace api
......
...@@ -903,4 +903,53 @@ IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, ReadDescriptorValue) { ...@@ -903,4 +903,53 @@ IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, ReadDescriptorValue) {
event_router()->DeviceRemoved(mock_adapter_, device_.get()); 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 } // namespace
...@@ -465,6 +465,27 @@ bool BluetoothLowEnergyEventRouter::ReadDescriptorValue( ...@@ -465,6 +465,27 @@ bool BluetoothLowEnergyEventRouter::ReadDescriptorValue(
return true; 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( void BluetoothLowEnergyEventRouter::SetAdapterForTesting(
device::BluetoothAdapter* adapter) { device::BluetoothAdapter* adapter) {
adapter_ = adapter; adapter_ = adapter;
......
...@@ -148,6 +148,15 @@ class BluetoothLowEnergyEventRouter ...@@ -148,6 +148,15 @@ class BluetoothLowEnergyEventRouter
const base::Closure& callback, const base::Closure& callback,
const base::Closure& error_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. // Initializes the adapter for testing. Used by unit tests only.
void SetAdapterForTesting(device::BluetoothAdapter* adapter); void SetAdapterForTesting(device::BluetoothAdapter* adapter);
......
...@@ -23,6 +23,7 @@ var charId = 'char_id0'; ...@@ -23,6 +23,7 @@ var charId = 'char_id0';
var badCharId = 'char_id1'; var badCharId = 'char_id1';
var characteristic = null; var characteristic = null;
var bytes = [0x43, 0x68, 0x72, 0x6F, 0x6D, 0x65]; var bytes = [0x43, 0x68, 0x72, 0x6F, 0x6D, 0x65];
var writeValue = new ArrayBuffer(bytes.length); var writeValue = new ArrayBuffer(bytes.length);
var valueBytes = new Uint8Array(writeValue); var valueBytes = new Uint8Array(writeValue);
...@@ -31,7 +32,7 @@ valueBytes.set(bytes); ...@@ -31,7 +32,7 @@ valueBytes.set(bytes);
// 1. Unknown characteristic instanceId. // 1. Unknown characteristic instanceId.
writeCharacteristicValue(badCharId, writeValue, function (result) { writeCharacteristicValue(badCharId, writeValue, function (result) {
if (result || !chrome.runtime.lastError) { 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. // 2. Known characteristic instanceId, but call failure.
......
{
"manifest_version": 2,
"name": "Test the Bluetooth Low Energy writeDescriptorValue API",
"version": "1.0",
"app": {
"background": {
"scripts": ["runtest.js"]
}
},
"bluetooth": {}
}
// 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]);
});
});
});
});
});
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment