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/memory/scoped_vector.h"
6 #include "base/message_loop/message_loop.h"
7 #include "base/run_loop.h"
8 #include "chromeos/dbus/dbus_thread_manager.h"
9 #include "chromeos/dbus/fake_bluetooth_adapter_client.h"
10 #include "chromeos/dbus/fake_bluetooth_agent_manager_client.h"
11 #include "chromeos/dbus/fake_bluetooth_device_client.h"
12 #include "chromeos/dbus/fake_bluetooth_gatt_characteristic_client.h"
13 #include "chromeos/dbus/fake_bluetooth_gatt_descriptor_client.h"
14 #include "chromeos/dbus/fake_bluetooth_gatt_service_client.h"
15 #include "chromeos/dbus/fake_bluetooth_input_client.h"
16 #include "dbus/object_path.h"
17 #include "device/bluetooth/bluetooth_adapter.h"
18 #include "device/bluetooth/bluetooth_adapter_factory.h"
19 #include "device/bluetooth/bluetooth_device.h"
20 #include "device/bluetooth/bluetooth_gatt_characteristic.h"
21 #include "device/bluetooth/bluetooth_gatt_connection.h"
22 #include "device/bluetooth/bluetooth_gatt_descriptor.h"
23 #include "device/bluetooth/bluetooth_gatt_notify_session.h"
24 #include "device/bluetooth/bluetooth_gatt_service.h"
25 #include "device/bluetooth/bluetooth_uuid.h"
26 #include "testing/gtest/include/gtest/gtest.h"
28 using device::BluetoothAdapter
;
29 using device::BluetoothDevice
;
30 using device::BluetoothGattCharacteristic
;
31 using device::BluetoothGattConnection
;
32 using device::BluetoothGattDescriptor
;
33 using device::BluetoothGattService
;
34 using device::BluetoothGattNotifySession
;
35 using device::BluetoothUUID
;
41 const BluetoothUUID
kHeartRateMeasurementUUID(
42 FakeBluetoothGattCharacteristicClient::kHeartRateMeasurementUUID
);
43 const BluetoothUUID
kBodySensorLocationUUID(
44 FakeBluetoothGattCharacteristicClient::kBodySensorLocationUUID
);
45 const BluetoothUUID
kHeartRateControlPointUUID(
46 FakeBluetoothGattCharacteristicClient::kHeartRateControlPointUUID
);
48 // Compares GATT characteristic/descriptor values. Returns true, if the values
50 bool ValuesEqual(const std::vector
<uint8
>& value0
,
51 const std::vector
<uint8
>& value1
) {
52 if (value0
.size() != value1
.size())
54 for (size_t i
= 0; i
< value0
.size(); ++i
)
55 if (value0
[i
] != value1
[i
])
60 class TestObserver
: public BluetoothAdapter::Observer
{
62 TestObserver(scoped_refptr
<BluetoothAdapter
> adapter
)
63 : gatt_service_added_count_(0),
64 gatt_service_removed_count_(0),
65 gatt_service_changed_count_(0),
66 gatt_discovery_complete_count_(0),
67 gatt_characteristic_added_count_(0),
68 gatt_characteristic_removed_count_(0),
69 gatt_characteristic_value_changed_count_(0),
70 gatt_descriptor_added_count_(0),
71 gatt_descriptor_removed_count_(0),
72 gatt_descriptor_value_changed_count_(0),
74 adapter_
->AddObserver(this);
77 ~TestObserver() override
{ adapter_
->RemoveObserver(this); }
79 // BluetoothAdapter::Observer overrides.
80 void GattServiceAdded(BluetoothAdapter
* adapter
,
81 BluetoothDevice
* device
,
82 BluetoothGattService
* service
) override
{
83 ASSERT_EQ(adapter_
.get(), adapter
);
84 ASSERT_EQ(service
->GetDevice(), device
);
86 ++gatt_service_added_count_
;
87 last_gatt_service_id_
= service
->GetIdentifier();
88 last_gatt_service_uuid_
= service
->GetUUID();
90 EXPECT_FALSE(service
->IsLocal());
91 EXPECT_TRUE(service
->IsPrimary());
93 EXPECT_EQ(device
->GetGattService(last_gatt_service_id_
), service
);
98 void GattServiceRemoved(BluetoothAdapter
* adapter
,
99 BluetoothDevice
* device
,
100 BluetoothGattService
* service
) override
{
101 ASSERT_EQ(adapter_
.get(), adapter
);
102 ASSERT_EQ(service
->GetDevice(), device
);
104 ++gatt_service_removed_count_
;
105 last_gatt_service_id_
= service
->GetIdentifier();
106 last_gatt_service_uuid_
= service
->GetUUID();
108 EXPECT_FALSE(service
->IsLocal());
109 EXPECT_TRUE(service
->IsPrimary());
111 // The device should return NULL for this service.
112 EXPECT_FALSE(device
->GetGattService(last_gatt_service_id_
));
117 void GattDiscoveryCompleteForService(BluetoothAdapter
* adapter
,
118 BluetoothGattService
* service
) override
{
119 ASSERT_EQ(adapter_
.get(), adapter
);
120 ++gatt_discovery_complete_count_
;
125 void GattServiceChanged(BluetoothAdapter
* adapter
,
126 BluetoothGattService
* service
) override
{
127 ASSERT_EQ(adapter_
.get(), adapter
);
128 ++gatt_service_changed_count_
;
133 void GattCharacteristicAdded(
134 BluetoothAdapter
* adapter
,
135 BluetoothGattCharacteristic
* characteristic
) override
{
136 ASSERT_EQ(adapter_
.get(), adapter
);
138 ++gatt_characteristic_added_count_
;
139 last_gatt_characteristic_id_
= characteristic
->GetIdentifier();
140 last_gatt_characteristic_uuid_
= characteristic
->GetUUID();
142 ASSERT_TRUE(characteristic
->GetService());
143 EXPECT_EQ(characteristic
->GetService()->GetCharacteristic(
144 last_gatt_characteristic_id_
),
150 void GattCharacteristicRemoved(
151 BluetoothAdapter
* adapter
,
152 BluetoothGattCharacteristic
* characteristic
) override
{
153 ASSERT_EQ(adapter_
.get(), adapter
);
155 ++gatt_characteristic_removed_count_
;
156 last_gatt_characteristic_id_
= characteristic
->GetIdentifier();
157 last_gatt_characteristic_uuid_
= characteristic
->GetUUID();
159 // The service should return NULL for this characteristic.
160 ASSERT_TRUE(characteristic
->GetService());
161 EXPECT_FALSE(characteristic
->GetService()->GetCharacteristic(
162 last_gatt_characteristic_id_
));
167 void GattCharacteristicValueChanged(
168 BluetoothAdapter
* adapter
,
169 BluetoothGattCharacteristic
* characteristic
,
170 const std::vector
<uint8
>& value
) override
{
171 ASSERT_EQ(adapter_
.get(), adapter
);
173 ++gatt_characteristic_value_changed_count_
;
174 last_gatt_characteristic_id_
= characteristic
->GetIdentifier();
175 last_gatt_characteristic_uuid_
= characteristic
->GetUUID();
176 last_changed_characteristic_value_
= value
;
178 ASSERT_TRUE(characteristic
->GetService());
179 EXPECT_EQ(characteristic
->GetService()->GetCharacteristic(
180 last_gatt_characteristic_id_
),
186 void GattDescriptorAdded(BluetoothAdapter
* adapter
,
187 BluetoothGattDescriptor
* descriptor
) override
{
188 ASSERT_EQ(adapter_
.get(), adapter
);
190 ++gatt_descriptor_added_count_
;
191 last_gatt_descriptor_id_
= descriptor
->GetIdentifier();
192 last_gatt_descriptor_uuid_
= descriptor
->GetUUID();
194 ASSERT_TRUE(descriptor
->GetCharacteristic());
195 EXPECT_EQ(descriptor
->GetCharacteristic()->GetDescriptor(
196 last_gatt_descriptor_id_
),
202 void GattDescriptorRemoved(BluetoothAdapter
* adapter
,
203 BluetoothGattDescriptor
* descriptor
) override
{
204 ASSERT_EQ(adapter_
.get(), adapter
);
206 ++gatt_descriptor_removed_count_
;
207 last_gatt_descriptor_id_
= descriptor
->GetIdentifier();
208 last_gatt_descriptor_uuid_
= descriptor
->GetUUID();
210 // The characteristic should return NULL for this descriptor..
211 ASSERT_TRUE(descriptor
->GetCharacteristic());
212 EXPECT_FALSE(descriptor
->GetCharacteristic()->GetDescriptor(
213 last_gatt_descriptor_id_
));
218 void GattDescriptorValueChanged(BluetoothAdapter
* adapter
,
219 BluetoothGattDescriptor
* descriptor
,
220 const std::vector
<uint8
>& value
) override
{
221 ASSERT_EQ(adapter_
.get(), adapter
);
223 ++gatt_descriptor_value_changed_count_
;
224 last_gatt_descriptor_id_
= descriptor
->GetIdentifier();
225 last_gatt_descriptor_uuid_
= descriptor
->GetUUID();
226 last_changed_descriptor_value_
= value
;
228 ASSERT_TRUE(descriptor
->GetCharacteristic());
229 EXPECT_EQ(descriptor
->GetCharacteristic()->GetDescriptor(
230 last_gatt_descriptor_id_
),
236 int gatt_service_added_count_
;
237 int gatt_service_removed_count_
;
238 int gatt_service_changed_count_
;
239 int gatt_discovery_complete_count_
;
240 int gatt_characteristic_added_count_
;
241 int gatt_characteristic_removed_count_
;
242 int gatt_characteristic_value_changed_count_
;
243 int gatt_descriptor_added_count_
;
244 int gatt_descriptor_removed_count_
;
245 int gatt_descriptor_value_changed_count_
;
246 std::string last_gatt_service_id_
;
247 BluetoothUUID last_gatt_service_uuid_
;
248 std::string last_gatt_characteristic_id_
;
249 BluetoothUUID last_gatt_characteristic_uuid_
;
250 std::vector
<uint8
> last_changed_characteristic_value_
;
251 std::string last_gatt_descriptor_id_
;
252 BluetoothUUID last_gatt_descriptor_uuid_
;
253 std::vector
<uint8
> last_changed_descriptor_value_
;
256 // Some tests use a message loop since background processing is simulated;
257 // break out of those loops.
258 void QuitMessageLoop() {
259 if (base::MessageLoop::current() &&
260 base::MessageLoop::current()->is_running())
261 base::MessageLoop::current()->Quit();
264 scoped_refptr
<BluetoothAdapter
> adapter_
;
269 class BluetoothGattChromeOSTest
: public testing::Test
{
271 BluetoothGattChromeOSTest()
272 : fake_bluetooth_gatt_service_client_(NULL
),
273 success_callback_count_(0),
274 error_callback_count_(0) {
277 void SetUp() override
{
278 scoped_ptr
<DBusThreadManagerSetter
> dbus_setter
=
279 chromeos::DBusThreadManager::GetSetterForTesting();
280 fake_bluetooth_device_client_
= new FakeBluetoothDeviceClient
;
281 fake_bluetooth_gatt_service_client_
=
282 new FakeBluetoothGattServiceClient
;
283 fake_bluetooth_gatt_characteristic_client_
=
284 new FakeBluetoothGattCharacteristicClient
;
285 fake_bluetooth_gatt_descriptor_client_
=
286 new FakeBluetoothGattDescriptorClient
;
287 dbus_setter
->SetBluetoothDeviceClient(
288 scoped_ptr
<BluetoothDeviceClient
>(
289 fake_bluetooth_device_client_
));
290 dbus_setter
->SetBluetoothGattServiceClient(
291 scoped_ptr
<BluetoothGattServiceClient
>(
292 fake_bluetooth_gatt_service_client_
));
293 dbus_setter
->SetBluetoothGattCharacteristicClient(
294 scoped_ptr
<BluetoothGattCharacteristicClient
>(
295 fake_bluetooth_gatt_characteristic_client_
));
296 dbus_setter
->SetBluetoothGattDescriptorClient(
297 scoped_ptr
<BluetoothGattDescriptorClient
>(
298 fake_bluetooth_gatt_descriptor_client_
));
299 dbus_setter
->SetBluetoothAdapterClient(
300 scoped_ptr
<BluetoothAdapterClient
>(new FakeBluetoothAdapterClient
));
301 dbus_setter
->SetBluetoothInputClient(
302 scoped_ptr
<BluetoothInputClient
>(new FakeBluetoothInputClient
));
303 dbus_setter
->SetBluetoothAgentManagerClient(
304 scoped_ptr
<BluetoothAgentManagerClient
>(
305 new FakeBluetoothAgentManagerClient
));
309 adapter_
->SetPowered(
311 base::Bind(&base::DoNothing
),
312 base::Bind(&base::DoNothing
));
313 ASSERT_TRUE(adapter_
->IsPowered());
316 void TearDown() override
{
318 update_sessions_
.clear();
320 DBusThreadManager::Shutdown();
324 device::BluetoothAdapterFactory::GetAdapter(
325 base::Bind(&BluetoothGattChromeOSTest::AdapterCallback
,
326 base::Unretained(this)));
327 ASSERT_TRUE(adapter_
.get() != NULL
);
328 ASSERT_TRUE(adapter_
->IsInitialized());
329 ASSERT_TRUE(adapter_
->IsPresent());
332 void AdapterCallback(scoped_refptr
<BluetoothAdapter
> adapter
) {
336 void SuccessCallback() {
337 ++success_callback_count_
;
340 void ValueCallback(const std::vector
<uint8
>& value
) {
341 ++success_callback_count_
;
342 last_read_value_
= value
;
345 void GattConnectionCallback(scoped_ptr
<BluetoothGattConnection
> conn
) {
346 ++success_callback_count_
;
347 gatt_conn_
= conn
.Pass();
350 void NotifySessionCallback(scoped_ptr
<BluetoothGattNotifySession
> session
) {
351 ++success_callback_count_
;
352 update_sessions_
.push_back(session
.release());
356 void ServiceErrorCallback(BluetoothGattService::GattErrorCode err
) {
357 ++error_callback_count_
;
358 last_service_error_
= err
;
361 void ErrorCallback() {
362 ++error_callback_count_
;
365 void DBusErrorCallback(const std::string
& error_name
,
366 const std::string
& error_message
) {
367 ++error_callback_count_
;
370 void ConnectErrorCallback(BluetoothDevice::ConnectErrorCode error
) {
371 ++error_callback_count_
;
375 void QuitMessageLoop() {
376 if (base::MessageLoop::current() &&
377 base::MessageLoop::current()->is_running())
378 base::MessageLoop::current()->Quit();
381 base::MessageLoop message_loop_
;
383 FakeBluetoothDeviceClient
* fake_bluetooth_device_client_
;
384 FakeBluetoothGattServiceClient
* fake_bluetooth_gatt_service_client_
;
385 FakeBluetoothGattCharacteristicClient
*
386 fake_bluetooth_gatt_characteristic_client_
;
387 FakeBluetoothGattDescriptorClient
* fake_bluetooth_gatt_descriptor_client_
;
388 scoped_ptr
<device::BluetoothGattConnection
> gatt_conn_
;
389 ScopedVector
<BluetoothGattNotifySession
> update_sessions_
;
390 scoped_refptr
<BluetoothAdapter
> adapter_
;
392 int success_callback_count_
;
393 int error_callback_count_
;
394 std::vector
<uint8
> last_read_value_
;
395 BluetoothGattService::GattErrorCode last_service_error_
;
398 TEST_F(BluetoothGattChromeOSTest
, GattConnection
) {
399 fake_bluetooth_device_client_
->CreateDevice(
400 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
401 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
402 BluetoothDevice
* device
= adapter_
->GetDevice(
403 FakeBluetoothDeviceClient::kLowEnergyAddress
);
405 ASSERT_FALSE(device
->IsConnected());
406 ASSERT_FALSE(gatt_conn_
.get());
407 ASSERT_EQ(0, success_callback_count_
);
408 ASSERT_EQ(0, error_callback_count_
);
410 device
->CreateGattConnection(
411 base::Bind(&BluetoothGattChromeOSTest::GattConnectionCallback
,
412 base::Unretained(this)),
413 base::Bind(&BluetoothGattChromeOSTest::ConnectErrorCallback
,
414 base::Unretained(this)));
416 EXPECT_EQ(1, success_callback_count_
);
417 EXPECT_EQ(0, error_callback_count_
);
418 EXPECT_TRUE(device
->IsConnected());
419 ASSERT_TRUE(gatt_conn_
.get());
420 EXPECT_TRUE(gatt_conn_
->IsConnected());
421 EXPECT_EQ(FakeBluetoothDeviceClient::kLowEnergyAddress
,
422 gatt_conn_
->GetDeviceAddress());
424 gatt_conn_
->Disconnect(
425 base::Bind(&BluetoothGattChromeOSTest::SuccessCallback
,
426 base::Unretained(this)));
427 EXPECT_EQ(2, success_callback_count_
);
428 EXPECT_EQ(0, error_callback_count_
);
429 EXPECT_TRUE(device
->IsConnected());
430 EXPECT_FALSE(gatt_conn_
->IsConnected());
432 device
->CreateGattConnection(
433 base::Bind(&BluetoothGattChromeOSTest::GattConnectionCallback
,
434 base::Unretained(this)),
435 base::Bind(&BluetoothGattChromeOSTest::ConnectErrorCallback
,
436 base::Unretained(this)));
438 EXPECT_EQ(3, success_callback_count_
);
439 EXPECT_EQ(0, error_callback_count_
);
440 EXPECT_TRUE(device
->IsConnected());
441 ASSERT_TRUE(gatt_conn_
.get());
442 EXPECT_TRUE(gatt_conn_
->IsConnected());
445 base::Bind(&BluetoothGattChromeOSTest::SuccessCallback
,
446 base::Unretained(this)),
447 base::Bind(&BluetoothGattChromeOSTest::ErrorCallback
,
448 base::Unretained(this)));
450 EXPECT_EQ(4, success_callback_count_
);
451 EXPECT_EQ(0, error_callback_count_
);
452 ASSERT_TRUE(gatt_conn_
.get());
453 EXPECT_FALSE(gatt_conn_
->IsConnected());
455 device
->CreateGattConnection(
456 base::Bind(&BluetoothGattChromeOSTest::GattConnectionCallback
,
457 base::Unretained(this)),
458 base::Bind(&BluetoothGattChromeOSTest::ConnectErrorCallback
,
459 base::Unretained(this)));
461 EXPECT_EQ(5, success_callback_count_
);
462 EXPECT_EQ(0, error_callback_count_
);
463 EXPECT_TRUE(device
->IsConnected());
464 EXPECT_TRUE(gatt_conn_
->IsConnected());
466 fake_bluetooth_device_client_
->RemoveDevice(
467 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
468 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
469 ASSERT_TRUE(gatt_conn_
.get());
470 EXPECT_FALSE(gatt_conn_
->IsConnected());
473 TEST_F(BluetoothGattChromeOSTest
, GattServiceAddedAndRemoved
) {
474 // Create a fake LE device. We store the device pointer here because this is a
475 // test. It's unsafe to do this in production as the device might get deleted.
476 fake_bluetooth_device_client_
->CreateDevice(
477 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
478 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
479 BluetoothDevice
* device
= adapter_
->GetDevice(
480 FakeBluetoothDeviceClient::kLowEnergyAddress
);
483 TestObserver
observer(adapter_
);
485 EXPECT_EQ(0, observer
.gatt_service_added_count_
);
486 EXPECT_EQ(0, observer
.gatt_service_removed_count_
);
487 EXPECT_TRUE(observer
.last_gatt_service_id_
.empty());
488 EXPECT_FALSE(observer
.last_gatt_service_uuid_
.IsValid());
489 EXPECT_TRUE(device
->GetGattServices().empty());
491 // Expose the fake Heart Rate Service.
492 fake_bluetooth_gatt_service_client_
->ExposeHeartRateService(
493 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
494 EXPECT_EQ(1, observer
.gatt_service_added_count_
);
495 EXPECT_EQ(0, observer
.gatt_service_removed_count_
);
496 EXPECT_FALSE(observer
.last_gatt_service_id_
.empty());
497 EXPECT_EQ(1U, device
->GetGattServices().size());
499 BluetoothUUID(FakeBluetoothGattServiceClient::kHeartRateServiceUUID
),
500 observer
.last_gatt_service_uuid_
);
502 BluetoothGattService
* service
=
503 device
->GetGattService(observer
.last_gatt_service_id_
);
504 EXPECT_FALSE(service
->IsLocal());
505 EXPECT_TRUE(service
->IsPrimary());
506 EXPECT_EQ(service
, device
->GetGattServices()[0]);
507 EXPECT_EQ(service
, device
->GetGattService(service
->GetIdentifier()));
509 EXPECT_EQ(observer
.last_gatt_service_uuid_
, service
->GetUUID());
512 observer
.last_gatt_service_uuid_
= BluetoothUUID();
513 observer
.last_gatt_service_id_
.clear();
514 fake_bluetooth_gatt_service_client_
->HideHeartRateService();
516 EXPECT_EQ(1, observer
.gatt_service_added_count_
);
517 EXPECT_EQ(1, observer
.gatt_service_removed_count_
);
518 EXPECT_FALSE(observer
.last_gatt_service_id_
.empty());
519 EXPECT_TRUE(device
->GetGattServices().empty());
521 BluetoothUUID(FakeBluetoothGattServiceClient::kHeartRateServiceUUID
),
522 observer
.last_gatt_service_uuid_
);
524 EXPECT_EQ(NULL
, device
->GetGattService(observer
.last_gatt_service_id_
));
526 // Expose the service again.
527 observer
.last_gatt_service_uuid_
= BluetoothUUID();
528 observer
.last_gatt_service_id_
.clear();
529 fake_bluetooth_gatt_service_client_
->ExposeHeartRateService(
530 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
531 EXPECT_EQ(2, observer
.gatt_service_added_count_
);
532 EXPECT_EQ(1, observer
.gatt_service_removed_count_
);
533 EXPECT_FALSE(observer
.last_gatt_service_id_
.empty());
534 EXPECT_EQ(1U, device
->GetGattServices().size());
536 BluetoothUUID(FakeBluetoothGattServiceClient::kHeartRateServiceUUID
),
537 observer
.last_gatt_service_uuid_
);
539 // The object |service| points to should have been deallocated. |device|
540 // should contain a brand new instance.
541 service
= device
->GetGattService(observer
.last_gatt_service_id_
);
542 EXPECT_EQ(service
, device
->GetGattServices()[0]);
543 EXPECT_FALSE(service
->IsLocal());
544 EXPECT_TRUE(service
->IsPrimary());
546 EXPECT_EQ(observer
.last_gatt_service_uuid_
, service
->GetUUID());
548 // Remove the device. The observer should be notified of the removed service.
549 // |device| becomes invalid after this.
550 observer
.last_gatt_service_uuid_
= BluetoothUUID();
551 observer
.last_gatt_service_id_
.clear();
552 fake_bluetooth_device_client_
->RemoveDevice(
553 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
554 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
556 EXPECT_EQ(2, observer
.gatt_service_added_count_
);
557 EXPECT_EQ(2, observer
.gatt_service_removed_count_
);
558 EXPECT_FALSE(observer
.last_gatt_service_id_
.empty());
560 BluetoothUUID(FakeBluetoothGattServiceClient::kHeartRateServiceUUID
),
561 observer
.last_gatt_service_uuid_
);
563 NULL
, adapter_
->GetDevice(FakeBluetoothDeviceClient::kLowEnergyAddress
));
566 TEST_F(BluetoothGattChromeOSTest
, GattCharacteristicAddedAndRemoved
) {
567 fake_bluetooth_device_client_
->CreateDevice(
568 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
569 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
570 BluetoothDevice
* device
= adapter_
->GetDevice(
571 FakeBluetoothDeviceClient::kLowEnergyAddress
);
574 TestObserver
observer(adapter_
);
576 // Expose the fake Heart Rate service. This will asynchronously expose
578 fake_bluetooth_gatt_service_client_
->ExposeHeartRateService(
579 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
580 ASSERT_EQ(1, observer
.gatt_service_added_count_
);
582 BluetoothGattService
* service
=
583 device
->GetGattService(observer
.last_gatt_service_id_
);
585 EXPECT_EQ(0, observer
.gatt_service_changed_count_
);
586 EXPECT_EQ(0, observer
.gatt_discovery_complete_count_
);
587 EXPECT_EQ(0, observer
.gatt_characteristic_added_count_
);
588 EXPECT_EQ(0, observer
.gatt_characteristic_removed_count_
);
589 EXPECT_EQ(0, observer
.gatt_characteristic_value_changed_count_
);
590 EXPECT_TRUE(service
->GetCharacteristics().empty());
592 // Run the message loop so that the characteristics appear.
593 base::MessageLoop::current()->Run();
595 // 3 characteristics should appear. Only 1 of the characteristics sends
596 // value changed signals. Service changed should be fired once for
598 EXPECT_EQ(0, observer
.gatt_service_changed_count_
);
599 EXPECT_EQ(1, observer
.gatt_discovery_complete_count_
);
600 EXPECT_EQ(3, observer
.gatt_characteristic_added_count_
);
601 EXPECT_EQ(0, observer
.gatt_characteristic_removed_count_
);
602 EXPECT_EQ(0, observer
.gatt_characteristic_value_changed_count_
);
603 EXPECT_EQ(3U, service
->GetCharacteristics().size());
605 // Hide the characteristics. 3 removed signals should be received.
606 fake_bluetooth_gatt_characteristic_client_
->HideHeartRateCharacteristics();
607 EXPECT_EQ(0, observer
.gatt_service_changed_count_
);
608 EXPECT_EQ(3, observer
.gatt_characteristic_added_count_
);
609 EXPECT_EQ(3, observer
.gatt_characteristic_removed_count_
);
610 EXPECT_EQ(0, observer
.gatt_characteristic_value_changed_count_
);
611 EXPECT_TRUE(service
->GetCharacteristics().empty());
613 // Re-expose the heart rate characteristics. We shouldn't get another
614 // GattDiscoveryCompleteForService call, since the service thinks that
615 // discovery is done. On the bluetoothd side, characteristics will be removed
616 // only if the service will also be subsequently removed.
617 fake_bluetooth_gatt_characteristic_client_
->ExposeHeartRateCharacteristics(
618 fake_bluetooth_gatt_service_client_
->GetHeartRateServicePath());
619 EXPECT_EQ(0, observer
.gatt_service_changed_count_
);
620 EXPECT_EQ(1, observer
.gatt_discovery_complete_count_
);
621 EXPECT_EQ(6, observer
.gatt_characteristic_added_count_
);
622 EXPECT_EQ(3, observer
.gatt_characteristic_removed_count_
);
623 EXPECT_EQ(0, observer
.gatt_characteristic_value_changed_count_
);
624 EXPECT_EQ(3U, service
->GetCharacteristics().size());
626 // Hide the service. All characteristics should disappear.
627 fake_bluetooth_gatt_service_client_
->HideHeartRateService();
628 EXPECT_EQ(0, observer
.gatt_service_changed_count_
);
629 EXPECT_EQ(6, observer
.gatt_characteristic_added_count_
);
630 EXPECT_EQ(6, observer
.gatt_characteristic_removed_count_
);
631 EXPECT_EQ(0, observer
.gatt_characteristic_value_changed_count_
);
634 TEST_F(BluetoothGattChromeOSTest
, GattDescriptorAddedAndRemoved
) {
635 fake_bluetooth_device_client_
->CreateDevice(
636 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
637 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
638 BluetoothDevice
* device
= adapter_
->GetDevice(
639 FakeBluetoothDeviceClient::kLowEnergyAddress
);
642 TestObserver
observer(adapter_
);
644 // Expose the fake Heart Rate service. This will asynchronously expose
646 fake_bluetooth_gatt_service_client_
->ExposeHeartRateService(
647 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
648 ASSERT_EQ(1, observer
.gatt_service_added_count_
);
650 BluetoothGattService
* service
=
651 device
->GetGattService(observer
.last_gatt_service_id_
);
653 EXPECT_EQ(0, observer
.gatt_service_changed_count_
);
654 EXPECT_EQ(0, observer
.gatt_descriptor_added_count_
);
655 EXPECT_EQ(0, observer
.gatt_descriptor_removed_count_
);
656 EXPECT_EQ(0, observer
.gatt_descriptor_value_changed_count_
);
658 EXPECT_TRUE(service
->GetCharacteristics().empty());
660 // Run the message loop so that the characteristics appear.
661 base::MessageLoop::current()->Run();
662 EXPECT_EQ(0, observer
.gatt_service_changed_count_
);
664 // Only the Heart Rate Measurement characteristic has a descriptor.
665 EXPECT_EQ(1, observer
.gatt_descriptor_added_count_
);
666 EXPECT_EQ(0, observer
.gatt_descriptor_removed_count_
);
667 EXPECT_EQ(0, observer
.gatt_descriptor_value_changed_count_
);
669 BluetoothGattCharacteristic
* characteristic
= service
->GetCharacteristic(
670 fake_bluetooth_gatt_characteristic_client_
->
671 GetBodySensorLocationPath().value());
672 ASSERT_TRUE(characteristic
);
673 EXPECT_TRUE(characteristic
->GetDescriptors().empty());
675 characteristic
= service
->GetCharacteristic(
676 fake_bluetooth_gatt_characteristic_client_
->
677 GetHeartRateControlPointPath().value());
678 ASSERT_TRUE(characteristic
);
679 EXPECT_TRUE(characteristic
->GetDescriptors().empty());
681 characteristic
= service
->GetCharacteristic(
682 fake_bluetooth_gatt_characteristic_client_
->
683 GetHeartRateMeasurementPath().value());
684 ASSERT_TRUE(characteristic
);
685 EXPECT_EQ(1U, characteristic
->GetDescriptors().size());
687 BluetoothGattDescriptor
* descriptor
= characteristic
->GetDescriptors()[0];
688 EXPECT_FALSE(descriptor
->IsLocal());
689 EXPECT_EQ(BluetoothGattDescriptor::ClientCharacteristicConfigurationUuid(),
690 descriptor
->GetUUID());
691 EXPECT_EQ(descriptor
->GetUUID(), observer
.last_gatt_descriptor_uuid_
);
692 EXPECT_EQ(descriptor
->GetIdentifier(), observer
.last_gatt_descriptor_id_
);
694 // Hide the descriptor.
695 fake_bluetooth_gatt_descriptor_client_
->HideDescriptor(
696 dbus::ObjectPath(descriptor
->GetIdentifier()));
697 EXPECT_TRUE(characteristic
->GetDescriptors().empty());
698 EXPECT_EQ(0, observer
.gatt_service_changed_count_
);
699 EXPECT_EQ(1, observer
.gatt_descriptor_added_count_
);
700 EXPECT_EQ(1, observer
.gatt_descriptor_removed_count_
);
701 EXPECT_EQ(0, observer
.gatt_descriptor_value_changed_count_
);
703 // Expose the descriptor again.
704 observer
.last_gatt_descriptor_id_
.clear();
705 observer
.last_gatt_descriptor_uuid_
= BluetoothUUID();
706 fake_bluetooth_gatt_descriptor_client_
->ExposeDescriptor(
707 dbus::ObjectPath(characteristic
->GetIdentifier()),
708 FakeBluetoothGattDescriptorClient::
709 kClientCharacteristicConfigurationUUID
);
710 EXPECT_EQ(0, observer
.gatt_service_changed_count_
);
711 EXPECT_EQ(1U, characteristic
->GetDescriptors().size());
712 EXPECT_EQ(2, observer
.gatt_descriptor_added_count_
);
713 EXPECT_EQ(1, observer
.gatt_descriptor_removed_count_
);
714 EXPECT_EQ(0, observer
.gatt_descriptor_value_changed_count_
);
716 descriptor
= characteristic
->GetDescriptors()[0];
717 EXPECT_FALSE(descriptor
->IsLocal());
718 EXPECT_EQ(BluetoothGattDescriptor::ClientCharacteristicConfigurationUuid(),
719 descriptor
->GetUUID());
720 EXPECT_EQ(descriptor
->GetUUID(), observer
.last_gatt_descriptor_uuid_
);
721 EXPECT_EQ(descriptor
->GetIdentifier(), observer
.last_gatt_descriptor_id_
);
724 TEST_F(BluetoothGattChromeOSTest
, AdapterAddedAfterGattService
) {
725 // This unit test tests that all remote GATT objects are created for D-Bus
726 // objects that were already exposed.
728 ASSERT_FALSE(device::BluetoothAdapterFactory::HasSharedInstanceForTesting());
730 // Create the fake D-Bus objects.
731 fake_bluetooth_device_client_
->CreateDevice(
732 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
733 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
734 fake_bluetooth_gatt_service_client_
->ExposeHeartRateService(
735 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
736 while (!fake_bluetooth_gatt_characteristic_client_
->IsHeartRateVisible())
737 base::RunLoop().RunUntilIdle();
738 ASSERT_TRUE(fake_bluetooth_gatt_service_client_
->IsHeartRateVisible());
739 ASSERT_TRUE(fake_bluetooth_gatt_characteristic_client_
->IsHeartRateVisible());
741 // Create the adapter. This should create all the GATT objects.
743 BluetoothDevice
* device
= adapter_
->GetDevice(
744 FakeBluetoothDeviceClient::kLowEnergyAddress
);
746 EXPECT_EQ(1U, device
->GetGattServices().size());
748 BluetoothGattService
* service
= device
->GetGattServices()[0];
749 ASSERT_TRUE(service
);
750 EXPECT_FALSE(service
->IsLocal());
751 EXPECT_TRUE(service
->IsPrimary());
753 BluetoothUUID(FakeBluetoothGattServiceClient::kHeartRateServiceUUID
),
755 EXPECT_EQ(service
, device
->GetGattServices()[0]);
756 EXPECT_EQ(service
, device
->GetGattService(service
->GetIdentifier()));
757 EXPECT_FALSE(service
->IsLocal());
758 EXPECT_EQ(3U, service
->GetCharacteristics().size());
760 BluetoothGattCharacteristic
* characteristic
= service
->GetCharacteristic(
761 fake_bluetooth_gatt_characteristic_client_
->
762 GetBodySensorLocationPath().value());
763 ASSERT_TRUE(characteristic
);
765 BluetoothUUID(FakeBluetoothGattCharacteristicClient::
766 kBodySensorLocationUUID
),
767 characteristic
->GetUUID());
768 EXPECT_FALSE(characteristic
->IsLocal());
769 EXPECT_TRUE(characteristic
->GetDescriptors().empty());
771 characteristic
= service
->GetCharacteristic(
772 fake_bluetooth_gatt_characteristic_client_
->
773 GetHeartRateControlPointPath().value());
774 ASSERT_TRUE(characteristic
);
776 BluetoothUUID(FakeBluetoothGattCharacteristicClient::
777 kHeartRateControlPointUUID
),
778 characteristic
->GetUUID());
779 EXPECT_FALSE(characteristic
->IsLocal());
780 EXPECT_TRUE(characteristic
->GetDescriptors().empty());
782 characteristic
= service
->GetCharacteristic(
783 fake_bluetooth_gatt_characteristic_client_
->
784 GetHeartRateMeasurementPath().value());
785 ASSERT_TRUE(characteristic
);
787 BluetoothUUID(FakeBluetoothGattCharacteristicClient::
788 kHeartRateMeasurementUUID
),
789 characteristic
->GetUUID());
790 EXPECT_FALSE(characteristic
->IsLocal());
791 EXPECT_EQ(1U, characteristic
->GetDescriptors().size());
793 BluetoothGattDescriptor
* descriptor
= characteristic
->GetDescriptors()[0];
794 ASSERT_TRUE(descriptor
);
795 EXPECT_EQ(BluetoothGattDescriptor::ClientCharacteristicConfigurationUuid(),
796 descriptor
->GetUUID());
797 EXPECT_FALSE(descriptor
->IsLocal());
800 TEST_F(BluetoothGattChromeOSTest
, GattCharacteristicValue
) {
801 fake_bluetooth_device_client_
->CreateDevice(
802 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
803 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
804 BluetoothDevice
* device
= adapter_
->GetDevice(
805 FakeBluetoothDeviceClient::kLowEnergyAddress
);
808 TestObserver
observer(adapter_
);
810 // Expose the fake Heart Rate service. This will asynchronously expose
812 fake_bluetooth_gatt_service_client_
->ExposeHeartRateService(
813 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
814 ASSERT_EQ(1, observer
.gatt_service_added_count_
);
816 BluetoothGattService
* service
=
817 device
->GetGattService(observer
.last_gatt_service_id_
);
819 EXPECT_EQ(0, observer
.gatt_characteristic_value_changed_count_
);
821 // Run the message loop so that the characteristics appear.
822 base::MessageLoop::current()->Run();
824 // Issue write request to non-writable characteristics.
825 observer
.last_gatt_characteristic_id_
.clear();
826 observer
.last_gatt_characteristic_uuid_
= BluetoothUUID();
828 std::vector
<uint8
> write_value
;
829 write_value
.push_back(0x01);
830 BluetoothGattCharacteristic
* characteristic
=
831 service
->GetCharacteristic(fake_bluetooth_gatt_characteristic_client_
->
832 GetHeartRateMeasurementPath().value());
833 ASSERT_TRUE(characteristic
);
834 EXPECT_FALSE(characteristic
->IsNotifying());
835 EXPECT_EQ(fake_bluetooth_gatt_characteristic_client_
->
836 GetHeartRateMeasurementPath().value(),
837 characteristic
->GetIdentifier());
838 EXPECT_EQ(kHeartRateMeasurementUUID
, characteristic
->GetUUID());
839 characteristic
->WriteRemoteCharacteristic(
841 base::Bind(&BluetoothGattChromeOSTest::SuccessCallback
,
842 base::Unretained(this)),
843 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback
,
844 base::Unretained(this)));
845 EXPECT_TRUE(observer
.last_gatt_characteristic_id_
.empty());
846 EXPECT_FALSE(observer
.last_gatt_characteristic_uuid_
.IsValid());
847 EXPECT_EQ(0, success_callback_count_
);
848 EXPECT_EQ(1, error_callback_count_
);
849 EXPECT_EQ(BluetoothGattService::GATT_ERROR_NOT_SUPPORTED
,
850 last_service_error_
);
851 EXPECT_EQ(0, observer
.gatt_characteristic_value_changed_count_
);
853 characteristic
= service
->GetCharacteristic(
854 fake_bluetooth_gatt_characteristic_client_
->
855 GetBodySensorLocationPath().value());
856 ASSERT_TRUE(characteristic
);
857 EXPECT_EQ(fake_bluetooth_gatt_characteristic_client_
->
858 GetBodySensorLocationPath().value(),
859 characteristic
->GetIdentifier());
860 EXPECT_EQ(kBodySensorLocationUUID
, characteristic
->GetUUID());
861 characteristic
->WriteRemoteCharacteristic(
863 base::Bind(&BluetoothGattChromeOSTest::SuccessCallback
,
864 base::Unretained(this)),
865 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback
,
866 base::Unretained(this)));
867 EXPECT_TRUE(observer
.last_gatt_characteristic_id_
.empty());
868 EXPECT_FALSE(observer
.last_gatt_characteristic_uuid_
.IsValid());
869 EXPECT_EQ(0, success_callback_count_
);
870 EXPECT_EQ(2, error_callback_count_
);
871 EXPECT_EQ(BluetoothGattService::GATT_ERROR_NOT_PERMITTED
,
872 last_service_error_
);
873 EXPECT_EQ(0, observer
.gatt_characteristic_value_changed_count_
);
875 // Issue write request to writable characteristic. The "Body Sensor Location"
876 // characteristic does not send notifications and WriteValue does not result
877 // in a CharacteristicValueChanged event, thus no such event should be
879 characteristic
= service
->GetCharacteristic(
880 fake_bluetooth_gatt_characteristic_client_
->
881 GetHeartRateControlPointPath().value());
882 ASSERT_TRUE(characteristic
);
883 EXPECT_EQ(fake_bluetooth_gatt_characteristic_client_
->
884 GetHeartRateControlPointPath().value(),
885 characteristic
->GetIdentifier());
886 EXPECT_EQ(kHeartRateControlPointUUID
, characteristic
->GetUUID());
887 characteristic
->WriteRemoteCharacteristic(
889 base::Bind(&BluetoothGattChromeOSTest::SuccessCallback
,
890 base::Unretained(this)),
891 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback
,
892 base::Unretained(this)));
893 EXPECT_TRUE(observer
.last_gatt_characteristic_id_
.empty());
894 EXPECT_FALSE(observer
.last_gatt_characteristic_uuid_
.IsValid());
895 EXPECT_EQ(1, success_callback_count_
);
896 EXPECT_EQ(2, error_callback_count_
);
897 EXPECT_EQ(0, observer
.gatt_characteristic_value_changed_count_
);
899 // Issue some invalid write requests to the characteristic.
900 // The value should still not change.
902 std::vector
<uint8
> invalid_write_length
;
903 invalid_write_length
.push_back(0x01);
904 invalid_write_length
.push_back(0x00);
905 characteristic
->WriteRemoteCharacteristic(
906 invalid_write_length
,
907 base::Bind(&BluetoothGattChromeOSTest::SuccessCallback
,
908 base::Unretained(this)),
909 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback
,
910 base::Unretained(this)));
911 EXPECT_EQ(1, success_callback_count_
);
912 EXPECT_EQ(3, error_callback_count_
);
913 EXPECT_EQ(BluetoothGattService::GATT_ERROR_INVALID_LENGTH
,
914 last_service_error_
);
915 EXPECT_EQ(0, observer
.gatt_characteristic_value_changed_count_
);
917 std::vector
<uint8
> invalid_write_value
;
918 invalid_write_value
.push_back(0x02);
919 characteristic
->WriteRemoteCharacteristic(
921 base::Bind(&BluetoothGattChromeOSTest::SuccessCallback
,
922 base::Unretained(this)),
923 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback
,
924 base::Unretained(this)));
925 EXPECT_EQ(1, success_callback_count_
);
926 EXPECT_EQ(4, error_callback_count_
);
927 EXPECT_EQ(BluetoothGattService::GATT_ERROR_FAILED
, last_service_error_
);
928 EXPECT_EQ(0, observer
.gatt_characteristic_value_changed_count_
);
930 // Issue a read request. A successful read results in a
931 // CharacteristicValueChanged notification.
932 characteristic
= service
->GetCharacteristic(
933 fake_bluetooth_gatt_characteristic_client_
->
934 GetBodySensorLocationPath().value());
935 ASSERT_TRUE(characteristic
);
936 EXPECT_EQ(fake_bluetooth_gatt_characteristic_client_
->
937 GetBodySensorLocationPath().value(),
938 characteristic
->GetIdentifier());
939 EXPECT_EQ(kBodySensorLocationUUID
, characteristic
->GetUUID());
940 characteristic
->ReadRemoteCharacteristic(
941 base::Bind(&BluetoothGattChromeOSTest::ValueCallback
,
942 base::Unretained(this)),
943 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback
,
944 base::Unretained(this)));
945 EXPECT_EQ(2, success_callback_count_
);
946 EXPECT_EQ(4, error_callback_count_
);
947 EXPECT_EQ(1, observer
.gatt_characteristic_value_changed_count_
);
948 EXPECT_TRUE(ValuesEqual(characteristic
->GetValue(), last_read_value_
));
950 // Test long-running actions.
951 fake_bluetooth_gatt_characteristic_client_
->SetExtraProcessing(1);
952 characteristic
= service
->GetCharacteristic(
953 fake_bluetooth_gatt_characteristic_client_
->GetBodySensorLocationPath()
955 ASSERT_TRUE(characteristic
);
957 fake_bluetooth_gatt_characteristic_client_
->GetBodySensorLocationPath()
959 characteristic
->GetIdentifier());
960 EXPECT_EQ(kBodySensorLocationUUID
, characteristic
->GetUUID());
961 characteristic
->ReadRemoteCharacteristic(
962 base::Bind(&BluetoothGattChromeOSTest::ValueCallback
,
963 base::Unretained(this)),
964 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback
,
965 base::Unretained(this)));
967 // Callback counts shouldn't change, this one will be delayed until after
969 EXPECT_EQ(2, success_callback_count_
);
970 EXPECT_EQ(4, error_callback_count_
);
971 EXPECT_EQ(1, observer
.gatt_characteristic_value_changed_count_
);
973 // Next read should error because IN_PROGRESS
974 characteristic
->ReadRemoteCharacteristic(
975 base::Bind(&BluetoothGattChromeOSTest::ValueCallback
,
976 base::Unretained(this)),
977 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback
,
978 base::Unretained(this)));
979 EXPECT_EQ(5, error_callback_count_
);
980 EXPECT_EQ(BluetoothGattService::GATT_ERROR_IN_PROGRESS
, last_service_error_
);
982 // But previous call finished.
983 EXPECT_EQ(3, success_callback_count_
);
984 EXPECT_EQ(2, observer
.gatt_characteristic_value_changed_count_
);
985 EXPECT_TRUE(ValuesEqual(characteristic
->GetValue(), last_read_value_
));
986 fake_bluetooth_gatt_characteristic_client_
->SetExtraProcessing(0);
988 // Test unauthorized actions.
989 fake_bluetooth_gatt_characteristic_client_
->SetAuthorized(false);
990 characteristic
->ReadRemoteCharacteristic(
991 base::Bind(&BluetoothGattChromeOSTest::ValueCallback
,
992 base::Unretained(this)),
993 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback
,
994 base::Unretained(this)));
995 EXPECT_EQ(3, success_callback_count_
);
996 EXPECT_EQ(6, error_callback_count_
);
997 EXPECT_EQ(BluetoothGattService::GATT_ERROR_NOT_AUTHORIZED
,
998 last_service_error_
);
999 EXPECT_EQ(2, observer
.gatt_characteristic_value_changed_count_
);
1000 fake_bluetooth_gatt_characteristic_client_
->SetAuthorized(true);
1002 // Test unauthenticated / needs login.
1003 fake_bluetooth_gatt_characteristic_client_
->SetAuthenticated(false);
1004 characteristic
->ReadRemoteCharacteristic(
1005 base::Bind(&BluetoothGattChromeOSTest::ValueCallback
,
1006 base::Unretained(this)),
1007 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback
,
1008 base::Unretained(this)));
1009 EXPECT_EQ(3, success_callback_count_
);
1010 EXPECT_EQ(7, error_callback_count_
);
1011 EXPECT_EQ(BluetoothGattService::GATT_ERROR_NOT_PAIRED
, last_service_error_
);
1012 EXPECT_EQ(2, observer
.gatt_characteristic_value_changed_count_
);
1013 fake_bluetooth_gatt_characteristic_client_
->SetAuthenticated(true);
1016 TEST_F(BluetoothGattChromeOSTest
, GattCharacteristicProperties
) {
1017 fake_bluetooth_device_client_
->CreateDevice(
1018 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
1019 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
1020 BluetoothDevice
* device
= adapter_
->GetDevice(
1021 FakeBluetoothDeviceClient::kLowEnergyAddress
);
1022 ASSERT_TRUE(device
);
1024 TestObserver
observer(adapter_
);
1026 // Expose the fake Heart Rate service. This will asynchronously expose
1028 fake_bluetooth_gatt_service_client_
->ExposeHeartRateService(
1029 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
1031 BluetoothGattService
* service
=
1032 device
->GetGattService(observer
.last_gatt_service_id_
);
1034 EXPECT_TRUE(service
->GetCharacteristics().empty());
1036 // Run the message loop so that the characteristics appear.
1037 base::MessageLoop::current()->Run();
1039 BluetoothGattCharacteristic
*characteristic
= service
->GetCharacteristic(
1040 fake_bluetooth_gatt_characteristic_client_
->
1041 GetBodySensorLocationPath().value());
1042 EXPECT_EQ(BluetoothGattCharacteristic::PROPERTY_READ
,
1043 characteristic
->GetProperties());
1045 characteristic
= service
->GetCharacteristic(
1046 fake_bluetooth_gatt_characteristic_client_
->
1047 GetHeartRateControlPointPath().value());
1048 EXPECT_EQ(BluetoothGattCharacteristic::PROPERTY_WRITE
,
1049 characteristic
->GetProperties());
1051 characteristic
= service
->GetCharacteristic(
1052 fake_bluetooth_gatt_characteristic_client_
->
1053 GetHeartRateMeasurementPath().value());
1054 EXPECT_EQ(BluetoothGattCharacteristic::PROPERTY_NOTIFY
,
1055 characteristic
->GetProperties());
1058 TEST_F(BluetoothGattChromeOSTest
, GattDescriptorValue
) {
1059 fake_bluetooth_device_client_
->CreateDevice(
1060 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
1061 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
1062 BluetoothDevice
* device
= adapter_
->GetDevice(
1063 FakeBluetoothDeviceClient::kLowEnergyAddress
);
1064 ASSERT_TRUE(device
);
1066 TestObserver
observer(adapter_
);
1068 // Expose the fake Heart Rate service. This will asynchronously expose
1070 fake_bluetooth_gatt_service_client_
->ExposeHeartRateService(
1071 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
1072 ASSERT_EQ(1, observer
.gatt_service_added_count_
);
1074 BluetoothGattService
* service
=
1075 device
->GetGattService(observer
.last_gatt_service_id_
);
1077 EXPECT_EQ(0, observer
.gatt_service_changed_count_
);
1078 EXPECT_EQ(0, observer
.gatt_discovery_complete_count_
);
1079 EXPECT_EQ(0, observer
.gatt_descriptor_value_changed_count_
);
1080 EXPECT_TRUE(service
->GetCharacteristics().empty());
1082 // Run the message loop so that the characteristics appear.
1083 base::MessageLoop::current()->Run();
1084 EXPECT_EQ(0, observer
.gatt_service_changed_count_
);
1085 EXPECT_EQ(1, observer
.gatt_discovery_complete_count_
);
1087 // Only the Heart Rate Measurement characteristic has a descriptor.
1088 BluetoothGattCharacteristic
* characteristic
= service
->GetCharacteristic(
1089 fake_bluetooth_gatt_characteristic_client_
->
1090 GetHeartRateMeasurementPath().value());
1091 ASSERT_TRUE(characteristic
);
1092 EXPECT_EQ(1U, characteristic
->GetDescriptors().size());
1093 EXPECT_FALSE(characteristic
->IsNotifying());
1095 BluetoothGattDescriptor
* descriptor
= characteristic
->GetDescriptors()[0];
1096 EXPECT_FALSE(descriptor
->IsLocal());
1097 EXPECT_EQ(BluetoothGattDescriptor::ClientCharacteristicConfigurationUuid(),
1098 descriptor
->GetUUID());
1100 std::vector
<uint8_t> desc_value
= {0x00, 0x00};
1102 /* The cached value will be empty until the first read request */
1103 EXPECT_FALSE(ValuesEqual(desc_value
, descriptor
->GetValue()));
1104 EXPECT_TRUE(descriptor
->GetValue().empty());
1106 EXPECT_EQ(0, success_callback_count_
);
1107 EXPECT_EQ(0, error_callback_count_
);
1108 EXPECT_TRUE(last_read_value_
.empty());
1110 // Read value. GattDescriptorValueChanged event will be sent after a
1112 descriptor
->ReadRemoteDescriptor(
1113 base::Bind(&BluetoothGattChromeOSTest::ValueCallback
,
1114 base::Unretained(this)),
1115 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback
,
1116 base::Unretained(this)));
1117 EXPECT_EQ(1, success_callback_count_
);
1118 EXPECT_EQ(0, error_callback_count_
);
1119 EXPECT_TRUE(ValuesEqual(last_read_value_
, descriptor
->GetValue()));
1120 EXPECT_TRUE(ValuesEqual(desc_value
, descriptor
->GetValue()));
1121 EXPECT_EQ(0, observer
.gatt_service_changed_count_
);
1122 EXPECT_EQ(1, observer
.gatt_descriptor_value_changed_count_
);
1124 // Write value. Writes to this descriptor will fail.
1125 desc_value
[0] = 0x03;
1126 descriptor
->WriteRemoteDescriptor(
1128 base::Bind(&BluetoothGattChromeOSTest::SuccessCallback
,
1129 base::Unretained(this)),
1130 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback
,
1131 base::Unretained(this)));
1132 EXPECT_EQ(1, success_callback_count_
);
1133 EXPECT_EQ(1, error_callback_count_
);
1134 EXPECT_EQ(BluetoothGattService::GATT_ERROR_NOT_PERMITTED
,
1135 last_service_error_
);
1136 EXPECT_TRUE(ValuesEqual(last_read_value_
, descriptor
->GetValue()));
1137 EXPECT_FALSE(ValuesEqual(desc_value
, descriptor
->GetValue()));
1138 EXPECT_EQ(0, observer
.gatt_service_changed_count_
);
1139 EXPECT_EQ(1, observer
.gatt_descriptor_value_changed_count_
);
1141 // Read value. The value should remain unchanged.
1142 descriptor
->ReadRemoteDescriptor(
1143 base::Bind(&BluetoothGattChromeOSTest::ValueCallback
,
1144 base::Unretained(this)),
1145 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback
,
1146 base::Unretained(this)));
1147 EXPECT_EQ(2, success_callback_count_
);
1148 EXPECT_EQ(1, error_callback_count_
);
1149 EXPECT_TRUE(ValuesEqual(last_read_value_
, descriptor
->GetValue()));
1150 EXPECT_FALSE(ValuesEqual(desc_value
, descriptor
->GetValue()));
1151 EXPECT_EQ(0, observer
.gatt_service_changed_count_
);
1152 EXPECT_EQ(1, observer
.gatt_descriptor_value_changed_count_
);
1154 // Start notifications on the descriptor's characteristic. The descriptor
1155 // value should change.
1156 characteristic
->StartNotifySession(
1157 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback
,
1158 base::Unretained(this)),
1159 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback
,
1160 base::Unretained(this)));
1161 base::MessageLoop::current()->Run();
1162 EXPECT_EQ(3, success_callback_count_
);
1163 EXPECT_EQ(1, error_callback_count_
);
1164 EXPECT_EQ(1U, update_sessions_
.size());
1165 EXPECT_TRUE(characteristic
->IsNotifying());
1167 // Read the new descriptor value. We should receive a value updated event.
1168 descriptor
->ReadRemoteDescriptor(
1169 base::Bind(&BluetoothGattChromeOSTest::ValueCallback
,
1170 base::Unretained(this)),
1171 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback
,
1172 base::Unretained(this)));
1173 EXPECT_EQ(4, success_callback_count_
);
1174 EXPECT_EQ(1, error_callback_count_
);
1175 EXPECT_TRUE(ValuesEqual(last_read_value_
, descriptor
->GetValue()));
1176 EXPECT_FALSE(ValuesEqual(desc_value
, descriptor
->GetValue()));
1177 EXPECT_EQ(0, observer
.gatt_service_changed_count_
);
1178 EXPECT_EQ(2, observer
.gatt_descriptor_value_changed_count_
);
1181 TEST_F(BluetoothGattChromeOSTest
, NotifySessions
) {
1182 fake_bluetooth_device_client_
->CreateDevice(
1183 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
1184 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
1185 BluetoothDevice
* device
=
1186 adapter_
->GetDevice(FakeBluetoothDeviceClient::kLowEnergyAddress
);
1187 ASSERT_TRUE(device
);
1189 TestObserver
observer(adapter_
);
1191 // Expose the fake Heart Rate service. This will asynchronously expose
1193 fake_bluetooth_gatt_service_client_
->ExposeHeartRateService(
1194 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
1195 ASSERT_EQ(1, observer
.gatt_service_added_count_
);
1197 BluetoothGattService
* service
=
1198 device
->GetGattService(observer
.last_gatt_service_id_
);
1200 EXPECT_EQ(0, observer
.gatt_characteristic_value_changed_count_
);
1202 // Run the message loop so that the characteristics appear.
1203 base::MessageLoop::current()->Run();
1205 BluetoothGattCharacteristic
* characteristic
= service
->GetCharacteristic(
1206 fake_bluetooth_gatt_characteristic_client_
->GetHeartRateMeasurementPath()
1208 ASSERT_TRUE(characteristic
);
1209 EXPECT_FALSE(characteristic
->IsNotifying());
1210 EXPECT_TRUE(update_sessions_
.empty());
1212 // Request to start notifications.
1213 characteristic
->StartNotifySession(
1214 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback
,
1215 base::Unretained(this)),
1216 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback
,
1217 base::Unretained(this)));
1219 // The operation still hasn't completed but we should have received the first
1221 EXPECT_EQ(0, success_callback_count_
);
1222 EXPECT_EQ(0, error_callback_count_
);
1223 EXPECT_EQ(1, observer
.gatt_characteristic_value_changed_count_
);
1224 EXPECT_TRUE(update_sessions_
.empty());
1226 // Send a two more requests, which should get queued.
1227 characteristic
->StartNotifySession(
1228 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback
,
1229 base::Unretained(this)),
1230 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback
,
1231 base::Unretained(this)));
1232 characteristic
->StartNotifySession(
1233 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback
,
1234 base::Unretained(this)),
1235 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback
,
1236 base::Unretained(this)));
1237 EXPECT_EQ(0, success_callback_count_
);
1238 EXPECT_EQ(0, error_callback_count_
);
1239 EXPECT_EQ(1, observer
.gatt_characteristic_value_changed_count_
);
1240 EXPECT_TRUE(update_sessions_
.empty());
1241 EXPECT_TRUE(characteristic
->IsNotifying());
1243 // Run the main loop. The initial call should complete. The queued call should
1244 // succeed immediately.
1245 base::MessageLoop::current()->Run();
1247 EXPECT_EQ(3, success_callback_count_
);
1248 EXPECT_EQ(0, error_callback_count_
);
1249 EXPECT_EQ(1, observer
.gatt_characteristic_value_changed_count_
);
1250 EXPECT_EQ(3U, update_sessions_
.size());
1252 // Notifications should be getting sent regularly now.
1253 base::MessageLoop::current()->Run();
1254 EXPECT_GT(observer
.gatt_characteristic_value_changed_count_
, 1);
1256 // Stop one of the sessions. The session should become inactive but the
1257 // characteristic should still be notifying.
1258 BluetoothGattNotifySession
* session
= update_sessions_
[0];
1259 EXPECT_TRUE(session
->IsActive());
1260 session
->Stop(base::Bind(&BluetoothGattChromeOSTest::SuccessCallback
,
1261 base::Unretained(this)));
1262 EXPECT_EQ(4, success_callback_count_
);
1263 EXPECT_EQ(0, error_callback_count_
);
1264 EXPECT_FALSE(session
->IsActive());
1265 EXPECT_EQ(characteristic
->GetIdentifier(),
1266 session
->GetCharacteristicIdentifier());
1267 EXPECT_TRUE(characteristic
->IsNotifying());
1269 // Delete another session. Characteristic should still be notifying.
1270 update_sessions_
.pop_back();
1271 EXPECT_EQ(2U, update_sessions_
.size());
1272 EXPECT_TRUE(characteristic
->IsNotifying());
1273 EXPECT_FALSE(update_sessions_
[0]->IsActive());
1274 EXPECT_TRUE(update_sessions_
[1]->IsActive());
1276 // Clear the last session.
1277 update_sessions_
.clear();
1278 EXPECT_TRUE(update_sessions_
.empty());
1279 EXPECT_FALSE(characteristic
->IsNotifying());
1281 success_callback_count_
= 0;
1282 observer
.gatt_characteristic_value_changed_count_
= 0;
1284 // Enable notifications again.
1285 characteristic
->StartNotifySession(
1286 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback
,
1287 base::Unretained(this)),
1288 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback
,
1289 base::Unretained(this)));
1290 EXPECT_EQ(0, success_callback_count_
);
1291 EXPECT_EQ(0, error_callback_count_
);
1292 EXPECT_EQ(1, observer
.gatt_characteristic_value_changed_count_
);
1293 EXPECT_TRUE(update_sessions_
.empty());
1294 EXPECT_TRUE(characteristic
->IsNotifying());
1296 // Run the message loop. Notifications should begin.
1297 base::MessageLoop::current()->Run();
1299 EXPECT_EQ(1, success_callback_count_
);
1300 EXPECT_EQ(0, error_callback_count_
);
1301 EXPECT_EQ(1, observer
.gatt_characteristic_value_changed_count_
);
1302 EXPECT_EQ(1U, update_sessions_
.size());
1303 EXPECT_TRUE(update_sessions_
[0]->IsActive());
1304 EXPECT_TRUE(characteristic
->IsNotifying());
1306 // Check that notifications are happening.
1307 base::MessageLoop::current()->Run();
1308 EXPECT_GT(observer
.gatt_characteristic_value_changed_count_
, 1);
1310 // Request another session. This should return immediately.
1311 characteristic
->StartNotifySession(
1312 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback
,
1313 base::Unretained(this)),
1314 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback
,
1315 base::Unretained(this)));
1316 EXPECT_EQ(2, success_callback_count_
);
1317 EXPECT_EQ(0, error_callback_count_
);
1318 EXPECT_EQ(2U, update_sessions_
.size());
1319 EXPECT_TRUE(update_sessions_
[0]->IsActive());
1320 EXPECT_TRUE(update_sessions_
[1]->IsActive());
1321 EXPECT_TRUE(characteristic
->IsNotifying());
1323 // Hide the characteristic. The sessions should become inactive.
1324 fake_bluetooth_gatt_characteristic_client_
->HideHeartRateCharacteristics();
1325 EXPECT_EQ(2U, update_sessions_
.size());
1326 EXPECT_FALSE(update_sessions_
[0]->IsActive());
1327 EXPECT_FALSE(update_sessions_
[1]->IsActive());
1330 TEST_F(BluetoothGattChromeOSTest
, NotifySessionsMadeInactive
) {
1331 fake_bluetooth_device_client_
->CreateDevice(
1332 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
1333 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
1334 BluetoothDevice
* device
=
1335 adapter_
->GetDevice(FakeBluetoothDeviceClient::kLowEnergyAddress
);
1336 ASSERT_TRUE(device
);
1338 TestObserver
observer(adapter_
);
1340 // Expose the fake Heart Rate service. This will asynchronously expose
1342 fake_bluetooth_gatt_service_client_
->ExposeHeartRateService(
1343 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
1344 ASSERT_EQ(1, observer
.gatt_service_added_count_
);
1346 BluetoothGattService
* service
=
1347 device
->GetGattService(observer
.last_gatt_service_id_
);
1349 EXPECT_EQ(0, observer
.gatt_characteristic_value_changed_count_
);
1351 // Run the message loop so that the characteristics appear.
1352 base::MessageLoop::current()->Run();
1354 BluetoothGattCharacteristic
* characteristic
= service
->GetCharacteristic(
1355 fake_bluetooth_gatt_characteristic_client_
->GetHeartRateMeasurementPath()
1357 ASSERT_TRUE(characteristic
);
1358 EXPECT_FALSE(characteristic
->IsNotifying());
1359 EXPECT_TRUE(update_sessions_
.empty());
1361 // Send several requests to start notifications.
1362 characteristic
->StartNotifySession(
1363 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback
,
1364 base::Unretained(this)),
1365 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback
,
1366 base::Unretained(this)));
1367 characteristic
->StartNotifySession(
1368 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback
,
1369 base::Unretained(this)),
1370 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback
,
1371 base::Unretained(this)));
1372 characteristic
->StartNotifySession(
1373 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback
,
1374 base::Unretained(this)),
1375 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback
,
1376 base::Unretained(this)));
1377 characteristic
->StartNotifySession(
1378 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback
,
1379 base::Unretained(this)),
1380 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback
,
1381 base::Unretained(this)));
1383 // The operation still hasn't completed but we should have received the first
1385 EXPECT_EQ(0, success_callback_count_
);
1386 EXPECT_EQ(0, error_callback_count_
);
1387 EXPECT_EQ(1, observer
.gatt_characteristic_value_changed_count_
);
1388 EXPECT_TRUE(characteristic
->IsNotifying());
1389 EXPECT_TRUE(update_sessions_
.empty());
1391 // Run the main loop. The initial call should complete. The queued calls
1392 // should succeed immediately.
1393 base::MessageLoop::current()->Run();
1395 EXPECT_EQ(4, success_callback_count_
);
1396 EXPECT_EQ(0, error_callback_count_
);
1397 EXPECT_EQ(1, observer
.gatt_characteristic_value_changed_count_
);
1398 EXPECT_TRUE(characteristic
->IsNotifying());
1399 EXPECT_EQ(4U, update_sessions_
.size());
1401 for (int i
= 0; i
< 4; i
++)
1402 EXPECT_TRUE(update_sessions_
[0]->IsActive());
1404 // Stop notifications directly through the client. The sessions should get
1405 // marked as inactive.
1406 fake_bluetooth_gatt_characteristic_client_
->StopNotify(
1407 fake_bluetooth_gatt_characteristic_client_
->GetHeartRateMeasurementPath(),
1408 base::Bind(&BluetoothGattChromeOSTest::SuccessCallback
,
1409 base::Unretained(this)),
1410 base::Bind(&BluetoothGattChromeOSTest::DBusErrorCallback
,
1411 base::Unretained(this)));
1412 EXPECT_EQ(5, success_callback_count_
);
1413 EXPECT_EQ(0, error_callback_count_
);
1414 EXPECT_FALSE(characteristic
->IsNotifying());
1415 EXPECT_EQ(4U, update_sessions_
.size());
1417 for (int i
= 0; i
< 4; i
++)
1418 EXPECT_FALSE(update_sessions_
[0]->IsActive());
1420 // It should be possible to restart notifications and the call should reset
1421 // the session count and make a request through the client.
1422 update_sessions_
.clear();
1423 success_callback_count_
= 0;
1424 observer
.gatt_characteristic_value_changed_count_
= 0;
1425 characteristic
->StartNotifySession(
1426 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback
,
1427 base::Unretained(this)),
1428 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback
,
1429 base::Unretained(this)));
1431 EXPECT_EQ(0, success_callback_count_
);
1432 EXPECT_EQ(0, error_callback_count_
);
1433 EXPECT_EQ(1, observer
.gatt_characteristic_value_changed_count_
);
1434 EXPECT_TRUE(characteristic
->IsNotifying());
1435 EXPECT_TRUE(update_sessions_
.empty());
1437 base::MessageLoop::current()->Run();
1439 EXPECT_EQ(1, success_callback_count_
);
1440 EXPECT_EQ(0, error_callback_count_
);
1441 EXPECT_EQ(1, observer
.gatt_characteristic_value_changed_count_
);
1442 EXPECT_TRUE(characteristic
->IsNotifying());
1443 EXPECT_EQ(1U, update_sessions_
.size());
1444 EXPECT_TRUE(update_sessions_
[0]->IsActive());
1447 } // namespace chromeos