diff options
8 files changed, 162 insertions, 32 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 d5b6bbf..934013f 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 @@ -8,6 +8,7 @@ #include "base/lazy_instance.h" #include "base/strings/stringprintf.h" #include "chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_event_router.h" +#include "chrome/browser/extensions/api/bluetooth_low_energy/utils.h" #include "chrome/common/extensions/api/bluetooth_low_energy.h" #include "content/public/browser/browser_thread.h" #include "extensions/browser/event_router.h" @@ -40,35 +41,6 @@ void DoWorkCallback(const base::Callback<bool()>& callback) { callback.Run(); } -// TODO(armansito): Remove this function once the described bug is fixed. -// (See crbug.com/368368). -// -// Converts an apibtle::Characteristic to a base::Value. This function is -// necessary, as json_schema_compiler::util::AddItemToList has no template -// specialization for user defined enums, which get treated as integers. This is -// because Characteristic contains a list of enum CharacteristicProperty. -scoped_ptr<base::DictionaryValue> CharacteristicToValue( - apibtle::Characteristic* from) { - // Copy the properties. Use Characteristic::ToValue to generate the result - // dictionary without the properties, to prevent json_schema_compiler from - // failing. - std::vector<apibtle::CharacteristicProperty> properties = from->properties; - from->properties.clear(); - scoped_ptr<base::DictionaryValue> to = from->ToValue(); - - // Manually set each property. - scoped_ptr<base::ListValue> property_list(new base::ListValue()); - for (std::vector<apibtle::CharacteristicProperty>::iterator iter = - properties.begin(); - iter != properties.end(); - ++iter) - property_list->Append(new base::StringValue(apibtle::ToString(*iter))); - - to->Set("properties", property_list.release()); - - return to.Pass(); -} - } // namespace namespace extensions { @@ -229,7 +201,7 @@ bool BluetoothLowEnergyGetCharacteristicFunction::DoWork() { // Manually construct the result instead of using // apibtle::GetCharacteristic::Result::Create as it doesn't convert lists of // enums correctly. - SetResult(CharacteristicToValue(&characteristic).release()); + SetResult(apibtle::CharacteristicToValue(&characteristic).release()); SendResponse(true); return true; @@ -272,7 +244,7 @@ bool BluetoothLowEnergyGetCharacteristicsFunction::DoWork() { characteristic_list.begin(); iter != characteristic_list.end(); ++iter) - result->Append(CharacteristicToValue(iter->get()).release()); + result->Append(apibtle::CharacteristicToValue(iter->get()).release()); SetResult(result.release()); SendResponse(true); 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 1a35bb4..06466b3 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 @@ -465,4 +465,37 @@ IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, CharacteristicProperties) { event_router()->DeviceRemoved(mock_adapter_, device_.get()); } +IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, CharacteristicValueChanged) { + ResultCatcher catcher; + catcher.RestrictToProfile(browser()->profile()); + + // Load the extension and let it set up. + ExtensionTestMessageListener listener("ready", true); + ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII( + "bluetooth_low_energy/characteristic_value_changed"))); + + // Cause events to be sent to the extension. + event_router()->DeviceAdded(mock_adapter_, device_.get()); + event_router()->GattServiceAdded(device_.get(), service0_.get()); + event_router()->GattServiceAdded(device_.get(), service1_.get()); + event_router()->GattCharacteristicAdded(service0_.get(), chrc0_.get()); + event_router()->GattCharacteristicAdded(service1_.get(), chrc2_.get()); + + std::vector<uint8> value; + event_router()->GattCharacteristicValueChanged( + service0_.get(), chrc0_.get(), value); + event_router()->GattCharacteristicValueChanged( + service1_.get(), chrc2_.get(), value); + + EXPECT_TRUE(listener.WaitUntilSatisfied()); + listener.Reply("go"); + + EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); + event_router()->GattCharacteristicRemoved(service1_.get(), chrc2_.get()); + event_router()->GattCharacteristicRemoved(service0_.get(), chrc0_.get()); + event_router()->GattServiceRemoved(device_.get(), service1_.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 5dd4ec1..519c4c0 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 @@ -7,6 +7,7 @@ #include "base/bind.h" #include "base/logging.h" #include "base/values.h" +#include "chrome/browser/extensions/api/bluetooth_low_energy/utils.h" #include "content/public/browser/browser_thread.h" #include "device/bluetooth/bluetooth_adapter_factory.h" #include "device/bluetooth/bluetooth_gatt_characteristic.h" @@ -449,7 +450,30 @@ void BluetoothLowEnergyEventRouter::GattCharacteristicValueChanged( BluetoothGattService* service, BluetoothGattCharacteristic* characteristic, const std::vector<uint8>& value) { - // TODO(armansito): Implement. + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + VLOG(2) << "GATT characteristic value changed: " << service->GetIdentifier(); + + DCHECK(observed_gatt_services_.find(service->GetIdentifier()) != + observed_gatt_services_.end()); + DCHECK(service_id_to_device_address_.find(service->GetIdentifier()) != + service_id_to_device_address_.end()); + DCHECK(chrc_id_to_service_id_.find(characteristic->GetIdentifier()) != + chrc_id_to_service_id_.end()); + DCHECK(chrc_id_to_service_id_[characteristic->GetIdentifier()] == + service->GetIdentifier()); + + // Signal API event. + apibtle::Characteristic api_characteristic; + PopulateCharacteristic(characteristic, &api_characteristic); + + // Manually construct the arguments, instead of using + // apibtle::OnCharacteristicValueChanged::Create, as it doesn't convert lists + // of enums correctly. + scoped_ptr<base::ListValue> args(new base::ListValue()); + args->Append(apibtle::CharacteristicToValue(&api_characteristic).release()); + scoped_ptr<Event> event(new Event( + apibtle::OnCharacteristicValueChanged::kEventName, args.Pass())); + EventRouter::Get(browser_context_)->BroadcastEvent(event.Pass()); } void BluetoothLowEnergyEventRouter::OnGetAdapter( diff --git a/chrome/browser/extensions/api/bluetooth_low_energy/utils.cc b/chrome/browser/extensions/api/bluetooth_low_energy/utils.cc new file mode 100644 index 0000000..09e5819 --- /dev/null +++ b/chrome/browser/extensions/api/bluetooth_low_energy/utils.cc @@ -0,0 +1,33 @@ +// 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. + +#include "chrome/browser/extensions/api/bluetooth_low_energy/utils.h" + +namespace extensions { +namespace api { +namespace bluetooth_low_energy { + +scoped_ptr<base::DictionaryValue> CharacteristicToValue(Characteristic* from) { + // Copy the properties. Use Characteristic::ToValue to generate the result + // dictionary without the properties, to prevent json_schema_compiler from + // failing. + std::vector<CharacteristicProperty> properties = from->properties; + from->properties.clear(); + scoped_ptr<base::DictionaryValue> to = from->ToValue(); + + // Manually set each property. + scoped_ptr<base::ListValue> property_list(new base::ListValue()); + for (std::vector<CharacteristicProperty>::iterator iter = properties.begin(); + iter != properties.end(); + ++iter) + property_list->Append(new base::StringValue(ToString(*iter))); + + to->Set("properties", property_list.release()); + + return to.Pass(); +} + +} // namespace bluetooth_low_energy +} // namespace api +} // namespace extensions diff --git a/chrome/browser/extensions/api/bluetooth_low_energy/utils.h b/chrome/browser/extensions/api/bluetooth_low_energy/utils.h new file mode 100644 index 0000000..7d3da07 --- /dev/null +++ b/chrome/browser/extensions/api/bluetooth_low_energy/utils.h @@ -0,0 +1,29 @@ +// 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. + +#ifndef CHROME_BROWSER_EXTENSIONS_API_BLUETOOTH_LOW_ENERGY_UTILS_H_ +#define CHROME_BROWSER_EXTENSIONS_API_BLUETOOTH_LOW_ENERGY_UTILS_H_ + +#include "base/memory/scoped_ptr.h" +#include "base/values.h" +#include "chrome/common/extensions/api/bluetooth_low_energy.h" + +namespace extensions { +namespace api { +namespace bluetooth_low_energy { + +// TODO(armansito): Remove this function once the described bug is fixed. +// (See crbug.com/368368) +// +// Converts a Characteristic to a base::Value. This function is necessary as +// json_schema_compiler::util::AddItemToList has no template specialization for +// user defined enums, which get treated as integers. This is because +// Characteristic contains a list of enum CharacteristicProperty. +scoped_ptr<base::DictionaryValue> CharacteristicToValue(Characteristic* from); + +} // namespace bluetooth_low_energy +} // namespace api +} // namespace extensions + +#endif // CHROME_BROWSER_EXTENSIONS_API_BLUETOOTH_LOW_ENERGY_UTILS_H_ diff --git a/chrome/chrome_browser_extensions.gypi b/chrome/chrome_browser_extensions.gypi index fa3bb94..00c3842 100644 --- a/chrome/chrome_browser_extensions.gypi +++ b/chrome/chrome_browser_extensions.gypi @@ -163,6 +163,8 @@ 'browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_api.h', 'browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_event_router.cc', 'browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_event_router.h', + 'browser/extensions/api/bluetooth_low_energy/utils.cc', + 'browser/extensions/api/bluetooth_low_energy/utils.h', 'browser/extensions/api/bluetooth_socket/bluetooth_socket_api.cc', 'browser/extensions/api/bluetooth_socket/bluetooth_socket_api.h', 'browser/extensions/api/bluetooth_socket/bluetooth_socket_event_dispatcher.cc', diff --git a/chrome/test/data/extensions/api_test/bluetooth_low_energy/characteristic_value_changed/manifest.json b/chrome/test/data/extensions/api_test/bluetooth_low_energy/characteristic_value_changed/manifest.json new file mode 100644 index 0000000..26d272a --- /dev/null +++ b/chrome/test/data/extensions/api_test/bluetooth_low_energy/characteristic_value_changed/manifest.json @@ -0,0 +1,11 @@ +{ + "manifest_version": 2, + "name": "Test the Bluetooth LE API onCharacteristicValueChanged event", + "version": "1.0", + "app": { + "background": { + "scripts": ["runtest.js"] + } + }, + "bluetooth": {} +} diff --git a/chrome/test/data/extensions/api_test/bluetooth_low_energy/characteristic_value_changed/runtest.js b/chrome/test/data/extensions/api_test/bluetooth_low_energy/characteristic_value_changed/runtest.js new file mode 100644 index 0000000..86fdb22 --- /dev/null +++ b/chrome/test/data/extensions/api_test/bluetooth_low_energy/characteristic_value_changed/runtest.js @@ -0,0 +1,26 @@ +// 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 testCharacteristicValueChanged() { + chrome.test.assertEq(2, Object.keys(changedChrcs).length); + + chrome.test.assertEq(charId0, changedChrcs[charId0].instanceId); + chrome.test.assertEq(charId2, changedChrcs[charId2].instanceId); + + chrome.test.succeed(); +} + +var charId0 = 'char_id0'; +var charId2 = 'char_id2'; + +var changedChrcs = {} + +chrome.bluetoothLowEnergy.onCharacteristicValueChanged.addListener( + function (chrc) { + changedChrcs[chrc.instanceId] = chrc; +}); + +chrome.test.sendMessage('ready', function (message) { + chrome.test.runTests([testCharacteristicValueChanged]); +}); |