diff options
author | armansito@chromium.org <armansito@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-01 06:14:39 +0000 |
---|---|---|
committer | armansito@chromium.org <armansito@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-01 06:14:39 +0000 |
commit | 5c35c28f15bfb1291ddb7c34ce1252197d46ff94 (patch) | |
tree | d995cee9d050d75556ff3091d1374d0fdb89f04d | |
parent | 46448433ecacbb84e623c0310304c3c0d33bae7e (diff) | |
download | chromium_src-5c35c28f15bfb1291ddb7c34ce1252197d46ff94.zip chromium_src-5c35c28f15bfb1291ddb7c34ce1252197d46ff94.tar.gz chromium_src-5c35c28f15bfb1291ddb7c34ce1252197d46ff94.tar.bz2 |
chrome.bluetoothLowEnergy: Implement getIncludedServices.
This patch implements the getIncludedServices function of the bluetoothLowEnergy
API.
BUG=265663
TEST=browser_tests --gtest_filter=BluetoothLowEnergyApiTest.*
Review URL: https://codereview.chromium.org/257013004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@267460 0039d316-1c4b-4281-b951-d872f2087c98
6 files changed, 175 insertions, 6 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 4e424dd..972d395 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 @@ -161,7 +161,7 @@ bool BluetoothLowEnergyGetServicesFunction::DoWork() { return false; } - results_ = apibtle::GetServices::Results::Create(service_list).Pass(); + results_ = apibtle::GetServices::Results::Create(service_list); SendResponse(true); return true; @@ -182,10 +182,37 @@ bool BluetoothLowEnergyGetCharacteristicsFunction::DoWork() { } bool BluetoothLowEnergyGetIncludedServicesFunction::DoWork() { - // TODO(armansito): Implement. - SetError("Call not supported."); - SendResponse(false); - return false; + 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::GetIncludedServices::Params> params( + apibtle::GetIncludedServices::Params::Create(*args_)); + EXTENSION_FUNCTION_VALIDATE(params.get() != NULL); + + std::string service_id = params->service_id; + + BluetoothLowEnergyEventRouter::ServiceList service_list; + if (!event_router->GetIncludedServices(service_id, &service_list)) { + SetError( + base::StringPrintf(kErrorServiceNotFoundFormat, service_id.c_str())); + SendResponse(false); + return false; + } + + results_ = apibtle::GetIncludedServices::Results::Create(service_list); + SendResponse(true); + + return true; } bool BluetoothLowEnergyGetDescriptorFunction::DoWork() { 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 8e73dfd..fb1da70 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 @@ -224,4 +224,45 @@ IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, GetRemovedService) { event_router()->DeviceRemoved(mock_adapter_, device_.get()); } +IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, GetIncludedServices) { + ResultCatcher catcher; + catcher.RestrictToProfile(browser()->profile()); + + ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII( + "bluetooth_low_energy/get_included_services"))); + + // Wait for initial call to end with failure as there is no mapping. + ExtensionTestMessageListener listener("ready", true); + EXPECT_TRUE(listener.WaitUntilSatisfied()); + + // Set up for the rest of the calls before replying. Included services can be + // returned even if there is no instance ID mapping for them yet, so no need + // to call GattServiceAdded for |service1_| here. + event_router()->DeviceAdded(mock_adapter_, device_.get()); + event_router()->GattServiceAdded(device_.get(), service0_.get()); + + std::vector<BluetoothGattService*> includes; + includes.push_back(service1_.get()); + EXPECT_CALL(*mock_adapter_, GetDevice(kTestLeDeviceAddress)) + .Times(2) + .WillRepeatedly(Return(device_.get())); + EXPECT_CALL(*device_, GetGattService(kTestServiceId0)) + .Times(2) + .WillRepeatedly(Return(service0_.get())); + EXPECT_CALL(*service0_, GetIncludedServices()) + .Times(2) + .WillOnce(Return(std::vector<BluetoothGattService*>())) + .WillOnce(Return(includes)); + + listener.Reply("go"); + listener.Reset(); + EXPECT_TRUE(listener.WaitUntilSatisfied()); + + listener.Reply("go"); + + EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); + 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 bbb82a6..d9d96c4 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 @@ -182,6 +182,41 @@ bool BluetoothLowEnergyEventRouter::GetService( return true; } +bool BluetoothLowEnergyEventRouter::GetIncludedServices( + const std::string& instance_id, + ServiceList* out_services) const { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + DCHECK(out_services); + if (!adapter_) { + VLOG(1) << "BluetoothAdapter not ready."; + return false; + } + + BluetoothGattService* service = FindServiceById(instance_id); + if (!service) { + VLOG(1) << "Service not found: " << instance_id; + return false; + } + + out_services->clear(); + + const std::vector<BluetoothGattService*>& includes = + service->GetIncludedServices(); + for (std::vector<BluetoothGattService*>::const_iterator iter = + includes.begin(); + iter != includes.end(); + ++iter) { + // Populate an API service and add it to the return value. + const BluetoothGattService* included = *iter; + linked_ptr<apibtle::Service> api_service(new apibtle::Service()); + PopulateService(included, api_service.get()); + + out_services->push_back(api_service); + } + + return true; +} + void BluetoothLowEnergyEventRouter::SetAdapterForTesting( device::BluetoothAdapter* adapter) { adapter_ = adapter; @@ -313,7 +348,6 @@ void BluetoothLowEnergyEventRouter::OnGetAdapter( DCHECK(observed_devices_.empty()); DCHECK(observed_gatt_services_.empty()); - // TODO: Observe adapter and all devices. adapter_ = adapter; // Initialize instance ID mappings for all discovered GATT objects and add 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 82de21b..82e20ad 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 @@ -74,6 +74,15 @@ class BluetoothLowEnergyEventRouter bool GetService(const std::string& instance_id, api::bluetooth_low_energy::Service* out_service) const; + // Populates |out_services| with the list of GATT services that are included + // by the GATT service with instance ID |instance_id|. Returns false, if not + // GATT service with the given ID is known. Returns true, on success. If + // the given service has no included services, then |out_service| will be + // empty. |out_service| must not be NULL. If it is non-empty, then its + // contents will be cleared. + bool GetIncludedServices(const std::string& instance_id, + ServiceList* out_services) const; + // 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/get_included_services/manifest.json b/chrome/test/data/extensions/api_test/bluetooth_low_energy/get_included_services/manifest.json new file mode 100644 index 0000000..ebb7312 --- /dev/null +++ b/chrome/test/data/extensions/api_test/bluetooth_low_energy/get_included_services/manifest.json @@ -0,0 +1,11 @@ +{ + "manifest_version": 2, + "name": "Test the Bluetooth Low Energy getIncludedServices API", + "version": "1.0", + "app": { + "background": { + "scripts": ["runtest.js"] + } + }, + "bluetooth": {} +} diff --git a/chrome/test/data/extensions/api_test/bluetooth_low_energy/get_included_services/runtest.js b/chrome/test/data/extensions/api_test/bluetooth_low_energy/get_included_services/runtest.js new file mode 100644 index 0000000..d2cc488 --- /dev/null +++ b/chrome/test/data/extensions/api_test/bluetooth_low_energy/get_included_services/runtest.js @@ -0,0 +1,47 @@ +// 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 testGetIncludedServices() { + chrome.test.assertTrue(services != null, '\'services\' is null'); + chrome.test.assertEq(1, services.length); + chrome.test.assertEq(includedId, services[0].instanceId); + + chrome.test.succeed(); +} + +var serviceId = 'service_id0'; +var includedId = 'service_id1'; +var services = null; + +function failOnError() { + if (chrome.runtime.lastError) { + chrome.test.fail(chrome.runtime.lastError.message); + } +} + +chrome.bluetoothLowEnergy.getIncludedServices(serviceId, function (result) { + // No mapping for |serviceId|. + if (result || !chrome.runtime.lastError) { + chrome.test.fail('getIncludedServices should have failed'); + } + + chrome.test.sendMessage('ready', function (message) { + chrome.bluetoothLowEnergy.getIncludedServices(serviceId, function (result) { + failOnError(); + if (!result || result.length != 0) { + chrome.test.fail('Included services should be empty.'); + } + + chrome.bluetoothLowEnergy.getIncludedServices(serviceId, + function (result) { + failOnError(); + services = result; + + chrome.test.sendMessage('ready', function (message) { + chrome.test.runTests([testGetIncludedServices]); + }); + }); + }); + }); +}); |