1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/message_loop/message_loop.h"
6 #include "base/run_loop.h"
7 #include "chromeos/dbus/fake_bluetooth_adapter_client.h"
8 #include "chromeos/dbus/fake_bluetooth_agent_manager_client.h"
9 #include "chromeos/dbus/fake_bluetooth_device_client.h"
10 #include "chromeos/dbus/fake_bluetooth_gatt_characteristic_client.h"
11 #include "chromeos/dbus/fake_bluetooth_gatt_descriptor_client.h"
12 #include "chromeos/dbus/fake_bluetooth_gatt_service_client.h"
13 #include "chromeos/dbus/fake_bluetooth_input_client.h"
14 #include "chromeos/dbus/fake_dbus_thread_manager.h"
15 #include "dbus/object_path.h"
16 #include "device/bluetooth/bluetooth_adapter.h"
17 #include "device/bluetooth/bluetooth_adapter_factory.h"
18 #include "device/bluetooth/bluetooth_device.h"
19 #include "device/bluetooth/bluetooth_gatt_characteristic.h"
20 #include "device/bluetooth/bluetooth_gatt_descriptor.h"
21 #include "device/bluetooth/bluetooth_gatt_service.h"
22 #include "device/bluetooth/bluetooth_uuid.h"
23 #include "testing/gtest/include/gtest/gtest.h"
25 using device::BluetoothAdapter
;
26 using device::BluetoothDevice
;
27 using device::BluetoothGattCharacteristic
;
28 using device::BluetoothGattDescriptor
;
29 using device::BluetoothGattService
;
30 using device::BluetoothUUID
;
36 const BluetoothUUID
kHeartRateMeasurementUUID(
37 FakeBluetoothGattCharacteristicClient::kHeartRateMeasurementUUID
);
38 const BluetoothUUID
kBodySensorLocationUUID(
39 FakeBluetoothGattCharacteristicClient::kBodySensorLocationUUID
);
40 const BluetoothUUID
kHeartRateControlPointUUID(
41 FakeBluetoothGattCharacteristicClient::kHeartRateControlPointUUID
);
43 // Compares GATT characteristic/descriptor values. Returns true, if the values
45 bool ValuesEqual(const std::vector
<uint8
>& value0
,
46 const std::vector
<uint8
>& value1
) {
47 if (value0
.size() != value1
.size())
49 for (size_t i
= 0; i
< value0
.size(); ++i
)
50 if (value0
[i
] != value1
[i
])
55 class TestDeviceObserver
: public BluetoothDevice::Observer
{
57 TestDeviceObserver(scoped_refptr
<BluetoothAdapter
> adapter
,
58 BluetoothDevice
* device
)
59 : gatt_service_added_count_(0),
60 gatt_service_removed_count_(0),
61 device_address_(device
->GetAddress()),
63 device
->AddObserver(this);
66 virtual ~TestDeviceObserver() {
67 BluetoothDevice
* device
= adapter_
->GetDevice(device_address_
);
69 device
->RemoveObserver(this);
72 // BluetoothDevice::Observer overrides.
73 virtual void GattServiceAdded(
74 BluetoothDevice
* device
,
75 BluetoothGattService
* service
) OVERRIDE
{
76 ASSERT_EQ(device_address_
, device
->GetAddress());
78 ++gatt_service_added_count_
;
79 last_gatt_service_id_
= service
->GetIdentifier();
80 last_gatt_service_uuid_
= service
->GetUUID();
82 EXPECT_FALSE(service
->IsLocal());
83 EXPECT_TRUE(service
->IsPrimary());
85 EXPECT_EQ(device
->GetGattService(last_gatt_service_id_
), service
);
90 virtual void GattServiceRemoved(
91 BluetoothDevice
* device
,
92 BluetoothGattService
* service
) OVERRIDE
{
93 ASSERT_EQ(device_address_
, device
->GetAddress());
95 ++gatt_service_removed_count_
;
96 last_gatt_service_id_
= service
->GetIdentifier();
97 last_gatt_service_uuid_
= service
->GetUUID();
99 EXPECT_FALSE(service
->IsLocal());
100 EXPECT_TRUE(service
->IsPrimary());
102 // The device should return NULL for this service.
103 EXPECT_FALSE(device
->GetGattService(last_gatt_service_id_
));
108 int gatt_service_added_count_
;
109 int gatt_service_removed_count_
;
110 std::string last_gatt_service_id_
;
111 BluetoothUUID last_gatt_service_uuid_
;
114 // Some tests use a message loop since background processing is simulated;
115 // break out of those loops.
116 void QuitMessageLoop() {
117 if (base::MessageLoop::current() &&
118 base::MessageLoop::current()->is_running())
119 base::MessageLoop::current()->Quit();
122 std::string device_address_
;
123 scoped_refptr
<BluetoothAdapter
> adapter_
;
126 class TestGattServiceObserver
: public BluetoothGattService::Observer
{
128 TestGattServiceObserver(scoped_refptr
<BluetoothAdapter
> adapter
,
129 BluetoothDevice
* device
,
130 BluetoothGattService
* service
)
131 : gatt_service_changed_count_(0),
132 gatt_characteristic_added_count_(0),
133 gatt_characteristic_removed_count_(0),
134 gatt_characteristic_value_changed_count_(0),
135 device_address_(device
->GetAddress()),
136 gatt_service_id_(service
->GetIdentifier()),
138 service
->AddObserver(this);
141 virtual ~TestGattServiceObserver() {
142 // See if either the device or the service even exist.
143 BluetoothDevice
* device
= adapter_
->GetDevice(device_address_
);
147 BluetoothGattService
* service
= device
->GetGattService(gatt_service_id_
);
151 service
->RemoveObserver(this);
154 // BluetoothGattService::Observer overrides.
155 virtual void GattServiceChanged(BluetoothGattService
* service
) OVERRIDE
{
156 ASSERT_EQ(gatt_service_id_
, service
->GetIdentifier());
157 ++gatt_service_changed_count_
;
162 virtual void GattCharacteristicAdded(
163 BluetoothGattService
* service
,
164 BluetoothGattCharacteristic
* characteristic
) OVERRIDE
{
165 ASSERT_EQ(gatt_service_id_
, service
->GetIdentifier());
167 ++gatt_characteristic_added_count_
;
168 last_gatt_characteristic_id_
= characteristic
->GetIdentifier();
169 last_gatt_characteristic_uuid_
= characteristic
->GetUUID();
171 EXPECT_EQ(service
->GetCharacteristic(last_gatt_characteristic_id_
),
173 EXPECT_EQ(service
, characteristic
->GetService());
178 virtual void GattCharacteristicRemoved(
179 BluetoothGattService
* service
,
180 BluetoothGattCharacteristic
* characteristic
) OVERRIDE
{
181 ASSERT_EQ(gatt_service_id_
, service
->GetIdentifier());
183 ++gatt_characteristic_removed_count_
;
184 last_gatt_characteristic_id_
= characteristic
->GetIdentifier();
185 last_gatt_characteristic_uuid_
= characteristic
->GetUUID();
187 // The service should return NULL for this characteristic.
188 EXPECT_FALSE(service
->GetCharacteristic(last_gatt_characteristic_id_
));
189 EXPECT_EQ(service
, characteristic
->GetService());
194 virtual void GattCharacteristicValueChanged(
195 BluetoothGattService
* service
,
196 BluetoothGattCharacteristic
* characteristic
,
197 const std::vector
<uint8
>& value
) OVERRIDE
{
198 ASSERT_EQ(gatt_service_id_
, service
->GetIdentifier());
200 ++gatt_characteristic_value_changed_count_
;
201 last_gatt_characteristic_id_
= characteristic
->GetIdentifier();
202 last_gatt_characteristic_uuid_
= characteristic
->GetUUID();
203 last_changed_characteristic_value_
= characteristic
->GetValue();
205 EXPECT_EQ(service
->GetCharacteristic(last_gatt_characteristic_id_
),
211 int gatt_service_changed_count_
;
212 int gatt_characteristic_added_count_
;
213 int gatt_characteristic_removed_count_
;
214 int gatt_characteristic_value_changed_count_
;
215 std::string last_gatt_characteristic_id_
;
216 BluetoothUUID last_gatt_characteristic_uuid_
;
217 std::vector
<uint8
> last_changed_characteristic_value_
;
220 // Some tests use a message loop since background processing is simulated;
221 // break out of those loops.
222 void QuitMessageLoop() {
223 if (base::MessageLoop::current() &&
224 base::MessageLoop::current()->is_running())
225 base::MessageLoop::current()->Quit();
228 std::string device_address_
;
229 std::string gatt_service_id_
;
230 scoped_refptr
<BluetoothAdapter
> adapter_
;
235 class BluetoothGattChromeOSTest
: public testing::Test
{
237 BluetoothGattChromeOSTest()
238 : fake_bluetooth_gatt_service_client_(NULL
),
239 success_callback_count_(0),
240 error_callback_count_(0) {
243 virtual void SetUp() {
244 FakeDBusThreadManager
* fake_dbus_thread_manager
= new FakeDBusThreadManager
;
245 fake_bluetooth_device_client_
= new FakeBluetoothDeviceClient
;
246 fake_bluetooth_gatt_service_client_
=
247 new FakeBluetoothGattServiceClient
;
248 fake_bluetooth_gatt_characteristic_client_
=
249 new FakeBluetoothGattCharacteristicClient
;
250 fake_bluetooth_gatt_descriptor_client_
=
251 new FakeBluetoothGattDescriptorClient
;
252 fake_dbus_thread_manager
->SetBluetoothDeviceClient(
253 scoped_ptr
<BluetoothDeviceClient
>(
254 fake_bluetooth_device_client_
));
255 fake_dbus_thread_manager
->SetBluetoothGattServiceClient(
256 scoped_ptr
<BluetoothGattServiceClient
>(
257 fake_bluetooth_gatt_service_client_
));
258 fake_dbus_thread_manager
->SetBluetoothGattCharacteristicClient(
259 scoped_ptr
<BluetoothGattCharacteristicClient
>(
260 fake_bluetooth_gatt_characteristic_client_
));
261 fake_dbus_thread_manager
->SetBluetoothGattDescriptorClient(
262 scoped_ptr
<BluetoothGattDescriptorClient
>(
263 fake_bluetooth_gatt_descriptor_client_
));
264 fake_dbus_thread_manager
->SetBluetoothAdapterClient(
265 scoped_ptr
<BluetoothAdapterClient
>(new FakeBluetoothAdapterClient
));
266 fake_dbus_thread_manager
->SetBluetoothInputClient(
267 scoped_ptr
<BluetoothInputClient
>(new FakeBluetoothInputClient
));
268 fake_dbus_thread_manager
->SetBluetoothAgentManagerClient(
269 scoped_ptr
<BluetoothAgentManagerClient
>(
270 new FakeBluetoothAgentManagerClient
));
271 DBusThreadManager::InitializeForTesting(fake_dbus_thread_manager
);
275 adapter_
->SetPowered(
277 base::Bind(&base::DoNothing
),
278 base::Bind(&base::DoNothing
));
279 ASSERT_TRUE(adapter_
->IsPowered());
282 virtual void TearDown() {
284 DBusThreadManager::Shutdown();
288 device::BluetoothAdapterFactory::GetAdapter(
289 base::Bind(&BluetoothGattChromeOSTest::AdapterCallback
,
290 base::Unretained(this)));
291 ASSERT_TRUE(adapter_
.get() != NULL
);
292 ASSERT_TRUE(adapter_
->IsInitialized());
293 ASSERT_TRUE(adapter_
->IsPresent());
296 void AdapterCallback(scoped_refptr
<BluetoothAdapter
> adapter
) {
300 void SuccessCallback() {
301 ++success_callback_count_
;
304 void ValueCallback(const std::vector
<uint8
>& value
) {
305 ++success_callback_count_
;
306 last_read_value_
= value
;
309 void ErrorCallback() {
310 ++error_callback_count_
;
314 base::MessageLoop message_loop_
;
316 FakeBluetoothDeviceClient
* fake_bluetooth_device_client_
;
317 FakeBluetoothGattServiceClient
* fake_bluetooth_gatt_service_client_
;
318 FakeBluetoothGattCharacteristicClient
*
319 fake_bluetooth_gatt_characteristic_client_
;
320 FakeBluetoothGattDescriptorClient
* fake_bluetooth_gatt_descriptor_client_
;
321 scoped_refptr
<BluetoothAdapter
> adapter_
;
323 int success_callback_count_
;
324 int error_callback_count_
;
325 std::vector
<uint8
> last_read_value_
;
328 TEST_F(BluetoothGattChromeOSTest
, GattServiceAddedAndRemoved
) {
329 // Create a fake LE device. We store the device pointer here because this is a
330 // test. It's unsafe to do this in production as the device might get deleted.
331 fake_bluetooth_device_client_
->CreateDevice(
332 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
333 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
334 BluetoothDevice
* device
= adapter_
->GetDevice(
335 FakeBluetoothDeviceClient::kLowEnergyAddress
);
338 TestDeviceObserver
observer(adapter_
, device
);
339 EXPECT_EQ(0, observer
.gatt_service_added_count_
);
340 EXPECT_EQ(0, observer
.gatt_service_removed_count_
);
341 EXPECT_TRUE(observer
.last_gatt_service_id_
.empty());
342 EXPECT_FALSE(observer
.last_gatt_service_uuid_
.IsValid());
343 EXPECT_TRUE(device
->GetGattServices().empty());
345 // Expose the fake Heart Rate Service.
346 fake_bluetooth_gatt_service_client_
->ExposeHeartRateService(
347 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
348 EXPECT_EQ(1, observer
.gatt_service_added_count_
);
349 EXPECT_EQ(0, observer
.gatt_service_removed_count_
);
350 EXPECT_FALSE(observer
.last_gatt_service_id_
.empty());
351 EXPECT_EQ(1U, device
->GetGattServices().size());
353 BluetoothUUID(FakeBluetoothGattServiceClient::kHeartRateServiceUUID
),
354 observer
.last_gatt_service_uuid_
);
356 BluetoothGattService
* service
=
357 device
->GetGattService(observer
.last_gatt_service_id_
);
358 EXPECT_FALSE(service
->IsLocal());
359 EXPECT_TRUE(service
->IsPrimary());
360 EXPECT_EQ(service
, device
->GetGattServices()[0]);
361 EXPECT_EQ(service
, device
->GetGattService(service
->GetIdentifier()));
363 EXPECT_EQ(observer
.last_gatt_service_uuid_
, service
->GetUUID());
366 observer
.last_gatt_service_uuid_
= BluetoothUUID();
367 observer
.last_gatt_service_id_
.clear();
368 fake_bluetooth_gatt_service_client_
->HideHeartRateService();
370 EXPECT_EQ(1, observer
.gatt_service_added_count_
);
371 EXPECT_EQ(1, observer
.gatt_service_removed_count_
);
372 EXPECT_FALSE(observer
.last_gatt_service_id_
.empty());
373 EXPECT_TRUE(device
->GetGattServices().empty());
375 BluetoothUUID(FakeBluetoothGattServiceClient::kHeartRateServiceUUID
),
376 observer
.last_gatt_service_uuid_
);
378 EXPECT_EQ(NULL
, device
->GetGattService(observer
.last_gatt_service_id_
));
380 // Expose the service again.
381 observer
.last_gatt_service_uuid_
= BluetoothUUID();
382 observer
.last_gatt_service_id_
.clear();
383 fake_bluetooth_gatt_service_client_
->ExposeHeartRateService(
384 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
385 EXPECT_EQ(2, observer
.gatt_service_added_count_
);
386 EXPECT_EQ(1, observer
.gatt_service_removed_count_
);
387 EXPECT_FALSE(observer
.last_gatt_service_id_
.empty());
388 EXPECT_EQ(1U, device
->GetGattServices().size());
390 BluetoothUUID(FakeBluetoothGattServiceClient::kHeartRateServiceUUID
),
391 observer
.last_gatt_service_uuid_
);
393 // The object |service| points to should have been deallocated. |device|
394 // should contain a brand new instance.
395 service
= device
->GetGattService(observer
.last_gatt_service_id_
);
396 EXPECT_EQ(service
, device
->GetGattServices()[0]);
397 EXPECT_FALSE(service
->IsLocal());
398 EXPECT_TRUE(service
->IsPrimary());
400 EXPECT_EQ(observer
.last_gatt_service_uuid_
, service
->GetUUID());
402 // Remove the device. The observer should be notified of the removed service.
403 // |device| becomes invalid after this.
404 observer
.last_gatt_service_uuid_
= BluetoothUUID();
405 observer
.last_gatt_service_id_
.clear();
406 fake_bluetooth_device_client_
->RemoveDevice(
407 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
408 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
410 EXPECT_EQ(2, observer
.gatt_service_added_count_
);
411 EXPECT_EQ(2, observer
.gatt_service_removed_count_
);
412 EXPECT_FALSE(observer
.last_gatt_service_id_
.empty());
414 BluetoothUUID(FakeBluetoothGattServiceClient::kHeartRateServiceUUID
),
415 observer
.last_gatt_service_uuid_
);
417 NULL
, adapter_
->GetDevice(FakeBluetoothDeviceClient::kLowEnergyAddress
));
420 TEST_F(BluetoothGattChromeOSTest
, GattCharacteristicAddedAndRemoved
) {
421 fake_bluetooth_device_client_
->CreateDevice(
422 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
423 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
424 BluetoothDevice
* device
= adapter_
->GetDevice(
425 FakeBluetoothDeviceClient::kLowEnergyAddress
);
428 TestDeviceObserver
observer(adapter_
, device
);
430 // Expose the fake Heart Rate service. This will asynchronously expose
432 fake_bluetooth_gatt_service_client_
->ExposeHeartRateService(
433 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
434 ASSERT_EQ(1, observer
.gatt_service_added_count_
);
436 BluetoothGattService
* service
=
437 device
->GetGattService(observer
.last_gatt_service_id_
);
439 TestGattServiceObserver
service_observer(adapter_
, device
, service
);
440 EXPECT_EQ(0, service_observer
.gatt_service_changed_count_
);
441 EXPECT_EQ(0, service_observer
.gatt_characteristic_added_count_
);
442 EXPECT_EQ(0, service_observer
.gatt_characteristic_removed_count_
);
443 EXPECT_EQ(0, service_observer
.gatt_characteristic_value_changed_count_
);
444 EXPECT_TRUE(service
->GetCharacteristics().empty());
446 // Run the message loop so that the characteristics appear.
447 base::MessageLoop::current()->Run();
449 // 3 characteristics should appear. Only 1 of the characteristics sends
450 // value changed signals. Service changed should be fired once for
452 EXPECT_EQ(4, service_observer
.gatt_service_changed_count_
);
453 EXPECT_EQ(3, service_observer
.gatt_characteristic_added_count_
);
454 EXPECT_EQ(0, service_observer
.gatt_characteristic_removed_count_
);
455 EXPECT_EQ(1, service_observer
.gatt_characteristic_value_changed_count_
);
456 EXPECT_EQ(3U, service
->GetCharacteristics().size());
458 // Hide the characteristics. 3 removed signals should be received.
459 fake_bluetooth_gatt_characteristic_client_
->HideHeartRateCharacteristics();
460 EXPECT_EQ(8, service_observer
.gatt_service_changed_count_
);
461 EXPECT_EQ(3, service_observer
.gatt_characteristic_added_count_
);
462 EXPECT_EQ(3, service_observer
.gatt_characteristic_removed_count_
);
463 EXPECT_EQ(1, service_observer
.gatt_characteristic_value_changed_count_
);
464 EXPECT_TRUE(service
->GetCharacteristics().empty());
466 // Re-expose the heart rate characteristics.
467 fake_bluetooth_gatt_characteristic_client_
->ExposeHeartRateCharacteristics(
468 fake_bluetooth_gatt_service_client_
->GetHeartRateServicePath());
469 EXPECT_EQ(12, service_observer
.gatt_service_changed_count_
);
470 EXPECT_EQ(6, service_observer
.gatt_characteristic_added_count_
);
471 EXPECT_EQ(3, service_observer
.gatt_characteristic_removed_count_
);
472 EXPECT_EQ(2, service_observer
.gatt_characteristic_value_changed_count_
);
473 EXPECT_EQ(3U, service
->GetCharacteristics().size());
475 // Hide the service. All characteristics should disappear.
476 fake_bluetooth_gatt_service_client_
->HideHeartRateService();
477 EXPECT_EQ(16, service_observer
.gatt_service_changed_count_
);
478 EXPECT_EQ(6, service_observer
.gatt_characteristic_added_count_
);
479 EXPECT_EQ(6, service_observer
.gatt_characteristic_removed_count_
);
480 EXPECT_EQ(2, service_observer
.gatt_characteristic_value_changed_count_
);
483 TEST_F(BluetoothGattChromeOSTest
, GattDescriptorAddedAndRemoved
) {
484 fake_bluetooth_device_client_
->CreateDevice(
485 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
486 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
487 BluetoothDevice
* device
= adapter_
->GetDevice(
488 FakeBluetoothDeviceClient::kLowEnergyAddress
);
491 TestDeviceObserver
observer(adapter_
, device
);
493 // Expose the fake Heart Rate service. This will asynchronously expose
495 fake_bluetooth_gatt_service_client_
->ExposeHeartRateService(
496 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
497 ASSERT_EQ(1, observer
.gatt_service_added_count_
);
499 BluetoothGattService
* service
=
500 device
->GetGattService(observer
.last_gatt_service_id_
);
502 TestGattServiceObserver
service_observer(adapter_
, device
, service
);
503 EXPECT_EQ(0, service_observer
.gatt_service_changed_count_
);
504 EXPECT_TRUE(service
->GetCharacteristics().empty());
506 // Run the message loop so that the characteristics appear.
507 base::MessageLoop::current()->Run();
508 EXPECT_EQ(4, service_observer
.gatt_service_changed_count_
);
510 // Only the Heart Rate Measurement characteristic has a descriptor.
511 BluetoothGattCharacteristic
* characteristic
= service
->GetCharacteristic(
512 fake_bluetooth_gatt_characteristic_client_
->
513 GetBodySensorLocationPath().value());
514 ASSERT_TRUE(characteristic
);
515 EXPECT_TRUE(characteristic
->GetDescriptors().empty());
517 characteristic
= service
->GetCharacteristic(
518 fake_bluetooth_gatt_characteristic_client_
->
519 GetHeartRateControlPointPath().value());
520 ASSERT_TRUE(characteristic
);
521 EXPECT_TRUE(characteristic
->GetDescriptors().empty());
523 characteristic
= service
->GetCharacteristic(
524 fake_bluetooth_gatt_characteristic_client_
->
525 GetHeartRateMeasurementPath().value());
526 ASSERT_TRUE(characteristic
);
527 EXPECT_EQ(1U, characteristic
->GetDescriptors().size());
529 BluetoothGattDescriptor
* descriptor
= characteristic
->GetDescriptors()[0];
530 EXPECT_FALSE(descriptor
->IsLocal());
531 EXPECT_EQ(BluetoothGattDescriptor::kClientCharacteristicConfigurationUuid
,
532 descriptor
->GetUUID());
534 // Hide the descriptor.
535 fake_bluetooth_gatt_descriptor_client_
->HideDescriptor(
536 dbus::ObjectPath(descriptor
->GetIdentifier()));
537 EXPECT_TRUE(characteristic
->GetDescriptors().empty());
538 EXPECT_EQ(5, service_observer
.gatt_service_changed_count_
);
540 // Expose the descriptor again.
541 fake_bluetooth_gatt_descriptor_client_
->ExposeDescriptor(
542 dbus::ObjectPath(characteristic
->GetIdentifier()),
543 FakeBluetoothGattDescriptorClient::
544 kClientCharacteristicConfigurationUUID
);
545 EXPECT_EQ(6, service_observer
.gatt_service_changed_count_
);
546 EXPECT_EQ(1U, characteristic
->GetDescriptors().size());
548 descriptor
= characteristic
->GetDescriptors()[0];
549 EXPECT_FALSE(descriptor
->IsLocal());
550 EXPECT_EQ(BluetoothGattDescriptor::kClientCharacteristicConfigurationUuid
,
551 descriptor
->GetUUID());
554 TEST_F(BluetoothGattChromeOSTest
, AdapterAddedAfterGattService
) {
555 // This unit test tests that all remote GATT objects are created for D-Bus
556 // objects that were already exposed.
558 EXPECT_EQ(NULL
, device::BluetoothAdapterFactory::MaybeGetAdapter().get());
560 // Create the fake D-Bus objects.
561 fake_bluetooth_device_client_
->CreateDevice(
562 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
563 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
564 fake_bluetooth_gatt_service_client_
->ExposeHeartRateService(
565 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
566 while (!fake_bluetooth_gatt_characteristic_client_
->IsHeartRateVisible())
567 base::RunLoop().RunUntilIdle();
568 ASSERT_TRUE(fake_bluetooth_gatt_service_client_
->IsHeartRateVisible());
569 ASSERT_TRUE(fake_bluetooth_gatt_characteristic_client_
->IsHeartRateVisible());
571 // Create the adapter. This should create all the GATT objects.
573 BluetoothDevice
* device
= adapter_
->GetDevice(
574 FakeBluetoothDeviceClient::kLowEnergyAddress
);
576 EXPECT_EQ(1U, device
->GetGattServices().size());
578 BluetoothGattService
* service
= device
->GetGattServices()[0];
579 ASSERT_TRUE(service
);
580 EXPECT_FALSE(service
->IsLocal());
581 EXPECT_TRUE(service
->IsPrimary());
583 BluetoothUUID(FakeBluetoothGattServiceClient::kHeartRateServiceUUID
),
585 EXPECT_EQ(service
, device
->GetGattServices()[0]);
586 EXPECT_EQ(service
, device
->GetGattService(service
->GetIdentifier()));
587 EXPECT_FALSE(service
->IsLocal());
588 EXPECT_EQ(3U, service
->GetCharacteristics().size());
590 BluetoothGattCharacteristic
* characteristic
= service
->GetCharacteristic(
591 fake_bluetooth_gatt_characteristic_client_
->
592 GetBodySensorLocationPath().value());
593 ASSERT_TRUE(characteristic
);
595 BluetoothUUID(FakeBluetoothGattCharacteristicClient::
596 kBodySensorLocationUUID
),
597 characteristic
->GetUUID());
598 EXPECT_FALSE(characteristic
->IsLocal());
599 EXPECT_TRUE(characteristic
->GetDescriptors().empty());
601 characteristic
= service
->GetCharacteristic(
602 fake_bluetooth_gatt_characteristic_client_
->
603 GetHeartRateControlPointPath().value());
604 ASSERT_TRUE(characteristic
);
606 BluetoothUUID(FakeBluetoothGattCharacteristicClient::
607 kHeartRateControlPointUUID
),
608 characteristic
->GetUUID());
609 EXPECT_FALSE(characteristic
->IsLocal());
610 EXPECT_TRUE(characteristic
->GetDescriptors().empty());
612 characteristic
= service
->GetCharacteristic(
613 fake_bluetooth_gatt_characteristic_client_
->
614 GetHeartRateMeasurementPath().value());
615 ASSERT_TRUE(characteristic
);
617 BluetoothUUID(FakeBluetoothGattCharacteristicClient::
618 kHeartRateMeasurementUUID
),
619 characteristic
->GetUUID());
620 EXPECT_FALSE(characteristic
->IsLocal());
621 EXPECT_EQ(1U, characteristic
->GetDescriptors().size());
623 BluetoothGattDescriptor
* descriptor
= characteristic
->GetDescriptors()[0];
624 ASSERT_TRUE(descriptor
);
625 EXPECT_EQ(BluetoothGattDescriptor::kClientCharacteristicConfigurationUuid
,
626 descriptor
->GetUUID());
627 EXPECT_FALSE(descriptor
->IsLocal());
630 TEST_F(BluetoothGattChromeOSTest
, GattCharacteristicValue
) {
631 fake_bluetooth_device_client_
->CreateDevice(
632 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
633 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
634 BluetoothDevice
* device
= adapter_
->GetDevice(
635 FakeBluetoothDeviceClient::kLowEnergyAddress
);
638 TestDeviceObserver
observer(adapter_
, device
);
640 // Expose the fake Heart Rate service. This will asynchronously expose
642 fake_bluetooth_gatt_service_client_
->ExposeHeartRateService(
643 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
644 ASSERT_EQ(1, observer
.gatt_service_added_count_
);
646 BluetoothGattService
* service
=
647 device
->GetGattService(observer
.last_gatt_service_id_
);
649 TestGattServiceObserver
service_observer(adapter_
, device
, service
);
650 EXPECT_EQ(0, service_observer
.gatt_characteristic_value_changed_count_
);
652 // Run the message loop so that the characteristics appear.
653 base::MessageLoop::current()->Run();
655 // We should get an initial value changed signal from the Heart Rate
656 // Measurement characteristic when it getsadded.
657 EXPECT_EQ(1, service_observer
.gatt_characteristic_value_changed_count_
);
659 // The Heart Rate Measurement characteristic should send regular
661 base::MessageLoop::current()->Run();
662 EXPECT_EQ(2, service_observer
.gatt_characteristic_value_changed_count_
);
663 EXPECT_EQ(kHeartRateMeasurementUUID
,
664 service_observer
.last_gatt_characteristic_uuid_
);
665 EXPECT_EQ(fake_bluetooth_gatt_characteristic_client_
->
666 GetHeartRateMeasurementPath().value(),
667 service_observer
.last_gatt_characteristic_id_
);
669 // Receive another notification.
670 service_observer
.last_gatt_characteristic_id_
.clear();
671 service_observer
.last_gatt_characteristic_uuid_
= BluetoothUUID();
672 base::MessageLoop::current()->Run();
673 EXPECT_EQ(3, service_observer
.gatt_characteristic_value_changed_count_
);
674 EXPECT_EQ(kHeartRateMeasurementUUID
,
675 service_observer
.last_gatt_characteristic_uuid_
);
676 EXPECT_EQ(fake_bluetooth_gatt_characteristic_client_
->
677 GetHeartRateMeasurementPath().value(),
678 service_observer
.last_gatt_characteristic_id_
);
680 // Issue write request to non-writeable characteristics.
681 service_observer
.last_gatt_characteristic_id_
.clear();
682 service_observer
.last_gatt_characteristic_uuid_
= BluetoothUUID();
684 std::vector
<uint8
> write_value
;
685 write_value
.push_back(0x01);
686 BluetoothGattCharacteristic
* characteristic
=
687 service
->GetCharacteristic(fake_bluetooth_gatt_characteristic_client_
->
688 GetHeartRateMeasurementPath().value());
689 ASSERT_TRUE(characteristic
);
690 EXPECT_EQ(fake_bluetooth_gatt_characteristic_client_
->
691 GetHeartRateMeasurementPath().value(),
692 characteristic
->GetIdentifier());
693 EXPECT_EQ(kHeartRateMeasurementUUID
, characteristic
->GetUUID());
694 characteristic
->WriteRemoteCharacteristic(
696 base::Bind(&BluetoothGattChromeOSTest::SuccessCallback
,
697 base::Unretained(this)),
698 base::Bind(&BluetoothGattChromeOSTest::ErrorCallback
,
699 base::Unretained(this)));
700 EXPECT_TRUE(service_observer
.last_gatt_characteristic_id_
.empty());
701 EXPECT_FALSE(service_observer
.last_gatt_characteristic_uuid_
.IsValid());
702 EXPECT_EQ(0, success_callback_count_
);
703 EXPECT_EQ(1, error_callback_count_
);
704 EXPECT_EQ(3, service_observer
.gatt_characteristic_value_changed_count_
);
706 characteristic
= service
->GetCharacteristic(
707 fake_bluetooth_gatt_characteristic_client_
->
708 GetBodySensorLocationPath().value());
709 ASSERT_TRUE(characteristic
);
710 EXPECT_EQ(fake_bluetooth_gatt_characteristic_client_
->
711 GetBodySensorLocationPath().value(),
712 characteristic
->GetIdentifier());
713 EXPECT_EQ(kBodySensorLocationUUID
, characteristic
->GetUUID());
714 characteristic
->WriteRemoteCharacteristic(
716 base::Bind(&BluetoothGattChromeOSTest::SuccessCallback
,
717 base::Unretained(this)),
718 base::Bind(&BluetoothGattChromeOSTest::ErrorCallback
,
719 base::Unretained(this)));
720 EXPECT_TRUE(service_observer
.last_gatt_characteristic_id_
.empty());
721 EXPECT_FALSE(service_observer
.last_gatt_characteristic_uuid_
.IsValid());
722 EXPECT_EQ(0, success_callback_count_
);
723 EXPECT_EQ(2, error_callback_count_
);
724 EXPECT_EQ(3, service_observer
.gatt_characteristic_value_changed_count_
);
726 // Issue write request to writeable characteristic. Writing "1" to the control
727 // point characteristic will immediately change its value back to "0", hence
728 // sending "ValueChanged" events twice.
729 characteristic
= service
->GetCharacteristic(
730 fake_bluetooth_gatt_characteristic_client_
->
731 GetHeartRateControlPointPath().value());
732 ASSERT_TRUE(characteristic
);
733 EXPECT_EQ(fake_bluetooth_gatt_characteristic_client_
->
734 GetHeartRateControlPointPath().value(),
735 characteristic
->GetIdentifier());
736 EXPECT_EQ(kHeartRateControlPointUUID
, characteristic
->GetUUID());
737 characteristic
->WriteRemoteCharacteristic(
739 base::Bind(&BluetoothGattChromeOSTest::SuccessCallback
,
740 base::Unretained(this)),
741 base::Bind(&BluetoothGattChromeOSTest::ErrorCallback
,
742 base::Unretained(this)));
743 EXPECT_EQ(characteristic
->GetIdentifier(),
744 service_observer
.last_gatt_characteristic_id_
);
745 EXPECT_EQ(characteristic
->GetUUID(),
746 service_observer
.last_gatt_characteristic_uuid_
);
747 EXPECT_EQ(1, success_callback_count_
);
748 EXPECT_EQ(2, error_callback_count_
);
749 EXPECT_EQ(5, service_observer
.gatt_characteristic_value_changed_count_
);
751 // Issue a read request.
752 characteristic
= service
->GetCharacteristic(
753 fake_bluetooth_gatt_characteristic_client_
->
754 GetBodySensorLocationPath().value());
755 ASSERT_TRUE(characteristic
);
756 EXPECT_EQ(fake_bluetooth_gatt_characteristic_client_
->
757 GetBodySensorLocationPath().value(),
758 characteristic
->GetIdentifier());
759 EXPECT_EQ(kBodySensorLocationUUID
, characteristic
->GetUUID());
760 characteristic
->ReadRemoteCharacteristic(
761 base::Bind(&BluetoothGattChromeOSTest::ValueCallback
,
762 base::Unretained(this)),
763 base::Bind(&BluetoothGattChromeOSTest::ErrorCallback
,
764 base::Unretained(this)));
765 EXPECT_EQ(2, success_callback_count_
);
766 EXPECT_EQ(2, error_callback_count_
);
767 EXPECT_EQ(5, service_observer
.gatt_characteristic_value_changed_count_
);
768 EXPECT_TRUE(ValuesEqual(characteristic
->GetValue(), last_read_value_
));
770 // One last value changed notification.
771 base::MessageLoop::current()->Run();
772 EXPECT_EQ(6, service_observer
.gatt_characteristic_value_changed_count_
);
773 EXPECT_EQ(kHeartRateMeasurementUUID
,
774 service_observer
.last_gatt_characteristic_uuid_
);
775 EXPECT_EQ(fake_bluetooth_gatt_characteristic_client_
->
776 GetHeartRateMeasurementPath().value(),
777 service_observer
.last_gatt_characteristic_id_
);
780 TEST_F(BluetoothGattChromeOSTest
, GattDescriptorValue
) {
781 fake_bluetooth_device_client_
->CreateDevice(
782 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
783 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
784 BluetoothDevice
* device
= adapter_
->GetDevice(
785 FakeBluetoothDeviceClient::kLowEnergyAddress
);
788 TestDeviceObserver
observer(adapter_
, device
);
790 // Expose the fake Heart Rate service. This will asynchronously expose
792 fake_bluetooth_gatt_service_client_
->ExposeHeartRateService(
793 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
794 ASSERT_EQ(1, observer
.gatt_service_added_count_
);
796 BluetoothGattService
* service
=
797 device
->GetGattService(observer
.last_gatt_service_id_
);
799 TestGattServiceObserver
service_observer(adapter_
, device
, service
);
800 EXPECT_EQ(0, service_observer
.gatt_service_changed_count_
);
801 EXPECT_TRUE(service
->GetCharacteristics().empty());
803 // Run the message loop so that the characteristics appear.
804 base::MessageLoop::current()->Run();
805 EXPECT_EQ(4, service_observer
.gatt_service_changed_count_
);
807 // Only the Heart Rate Measurement characteristic has a descriptor.
808 BluetoothGattCharacteristic
* characteristic
= service
->GetCharacteristic(
809 fake_bluetooth_gatt_characteristic_client_
->
810 GetHeartRateMeasurementPath().value());
811 ASSERT_TRUE(characteristic
);
812 EXPECT_EQ(1U, characteristic
->GetDescriptors().size());
814 BluetoothGattDescriptor
* descriptor
= characteristic
->GetDescriptors()[0];
815 EXPECT_FALSE(descriptor
->IsLocal());
816 EXPECT_EQ(BluetoothGattDescriptor::kClientCharacteristicConfigurationUuid
,
817 descriptor
->GetUUID());
819 std::vector
<uint8
> desc_value
;
820 desc_value
.push_back(0);
821 desc_value
.push_back(0);
822 EXPECT_TRUE(ValuesEqual(desc_value
, descriptor
->GetValue()));
824 EXPECT_EQ(0, success_callback_count_
);
825 EXPECT_EQ(0, error_callback_count_
);
826 EXPECT_TRUE(last_read_value_
.empty());
829 descriptor
->ReadRemoteDescriptor(
830 base::Bind(&BluetoothGattChromeOSTest::ValueCallback
,
831 base::Unretained(this)),
832 base::Bind(&BluetoothGattChromeOSTest::ErrorCallback
,
833 base::Unretained(this)));
834 EXPECT_EQ(1, success_callback_count_
);
835 EXPECT_EQ(0, error_callback_count_
);
836 EXPECT_TRUE(ValuesEqual(last_read_value_
, descriptor
->GetValue()));
839 desc_value
[0] = 0x03;
840 descriptor
->WriteRemoteDescriptor(
842 base::Bind(&BluetoothGattChromeOSTest::SuccessCallback
,
843 base::Unretained(this)),
844 base::Bind(&BluetoothGattChromeOSTest::ErrorCallback
,
845 base::Unretained(this)));
846 EXPECT_EQ(2, success_callback_count_
);
847 EXPECT_EQ(0, error_callback_count_
);
848 EXPECT_FALSE(ValuesEqual(last_read_value_
, descriptor
->GetValue()));
849 EXPECT_TRUE(ValuesEqual(desc_value
, descriptor
->GetValue()));
852 descriptor
->ReadRemoteDescriptor(
853 base::Bind(&BluetoothGattChromeOSTest::ValueCallback
,
854 base::Unretained(this)),
855 base::Bind(&BluetoothGattChromeOSTest::ErrorCallback
,
856 base::Unretained(this)));
857 EXPECT_EQ(3, success_callback_count_
);
858 EXPECT_EQ(0, error_callback_count_
);
859 EXPECT_TRUE(ValuesEqual(last_read_value_
, descriptor
->GetValue()));
860 EXPECT_TRUE(ValuesEqual(desc_value
, descriptor
->GetValue()));
863 } // namespace chromeos