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 virtual ~TestObserver() {
78 adapter_
->RemoveObserver(this);
81 // BluetoothAdapter::Observer overrides.
82 virtual void GattServiceAdded(BluetoothAdapter
* adapter
,
83 BluetoothDevice
* device
,
84 BluetoothGattService
* service
) OVERRIDE
{
85 ASSERT_EQ(adapter_
.get(), adapter
);
86 ASSERT_EQ(service
->GetDevice(), device
);
88 ++gatt_service_added_count_
;
89 last_gatt_service_id_
= service
->GetIdentifier();
90 last_gatt_service_uuid_
= service
->GetUUID();
92 EXPECT_FALSE(service
->IsLocal());
93 EXPECT_TRUE(service
->IsPrimary());
95 EXPECT_EQ(device
->GetGattService(last_gatt_service_id_
), service
);
100 virtual void GattServiceRemoved(BluetoothAdapter
* adapter
,
101 BluetoothDevice
* device
,
102 BluetoothGattService
* service
) OVERRIDE
{
103 ASSERT_EQ(adapter_
.get(), adapter
);
104 ASSERT_EQ(service
->GetDevice(), device
);
106 ++gatt_service_removed_count_
;
107 last_gatt_service_id_
= service
->GetIdentifier();
108 last_gatt_service_uuid_
= service
->GetUUID();
110 EXPECT_FALSE(service
->IsLocal());
111 EXPECT_TRUE(service
->IsPrimary());
113 // The device should return NULL for this service.
114 EXPECT_FALSE(device
->GetGattService(last_gatt_service_id_
));
119 virtual void GattDiscoveryCompleteForService(
120 BluetoothAdapter
* adapter
,
121 BluetoothGattService
* service
) OVERRIDE
{
122 ASSERT_EQ(adapter_
.get(), adapter
);
123 ++gatt_discovery_complete_count_
;
128 virtual void GattServiceChanged(BluetoothAdapter
* adapter
,
129 BluetoothGattService
* service
) OVERRIDE
{
130 ASSERT_EQ(adapter_
.get(), adapter
);
131 ++gatt_service_changed_count_
;
136 virtual void GattCharacteristicAdded(
137 BluetoothAdapter
* adapter
,
138 BluetoothGattCharacteristic
* characteristic
) OVERRIDE
{
139 ASSERT_EQ(adapter_
.get(), adapter
);
141 ++gatt_characteristic_added_count_
;
142 last_gatt_characteristic_id_
= characteristic
->GetIdentifier();
143 last_gatt_characteristic_uuid_
= characteristic
->GetUUID();
145 ASSERT_TRUE(characteristic
->GetService());
146 EXPECT_EQ(characteristic
->GetService()->GetCharacteristic(
147 last_gatt_characteristic_id_
),
153 virtual void GattCharacteristicRemoved(
154 BluetoothAdapter
* adapter
,
155 BluetoothGattCharacteristic
* characteristic
) OVERRIDE
{
156 ASSERT_EQ(adapter_
.get(), adapter
);
158 ++gatt_characteristic_removed_count_
;
159 last_gatt_characteristic_id_
= characteristic
->GetIdentifier();
160 last_gatt_characteristic_uuid_
= characteristic
->GetUUID();
162 // The service should return NULL for this characteristic.
163 ASSERT_TRUE(characteristic
->GetService());
164 EXPECT_FALSE(characteristic
->GetService()->GetCharacteristic(
165 last_gatt_characteristic_id_
));
170 virtual void GattCharacteristicValueChanged(
171 BluetoothAdapter
* adapter
,
172 BluetoothGattCharacteristic
* characteristic
,
173 const std::vector
<uint8
>& value
) OVERRIDE
{
174 ASSERT_EQ(adapter_
.get(), adapter
);
176 ++gatt_characteristic_value_changed_count_
;
177 last_gatt_characteristic_id_
= characteristic
->GetIdentifier();
178 last_gatt_characteristic_uuid_
= characteristic
->GetUUID();
179 last_changed_characteristic_value_
= value
;
181 ASSERT_TRUE(characteristic
->GetService());
182 EXPECT_EQ(characteristic
->GetService()->GetCharacteristic(
183 last_gatt_characteristic_id_
),
189 virtual void GattDescriptorAdded(
190 BluetoothAdapter
* adapter
,
191 BluetoothGattDescriptor
* descriptor
) OVERRIDE
{
192 ASSERT_EQ(adapter_
.get(), adapter
);
194 ++gatt_descriptor_added_count_
;
195 last_gatt_descriptor_id_
= descriptor
->GetIdentifier();
196 last_gatt_descriptor_uuid_
= descriptor
->GetUUID();
198 ASSERT_TRUE(descriptor
->GetCharacteristic());
199 EXPECT_EQ(descriptor
->GetCharacteristic()->GetDescriptor(
200 last_gatt_descriptor_id_
),
206 virtual void GattDescriptorRemoved(
207 BluetoothAdapter
* adapter
,
208 BluetoothGattDescriptor
* descriptor
) OVERRIDE
{
209 ASSERT_EQ(adapter_
.get(), adapter
);
211 ++gatt_descriptor_removed_count_
;
212 last_gatt_descriptor_id_
= descriptor
->GetIdentifier();
213 last_gatt_descriptor_uuid_
= descriptor
->GetUUID();
215 // The characteristic should return NULL for this descriptor..
216 ASSERT_TRUE(descriptor
->GetCharacteristic());
217 EXPECT_FALSE(descriptor
->GetCharacteristic()->GetDescriptor(
218 last_gatt_descriptor_id_
));
223 virtual void GattDescriptorValueChanged(
224 BluetoothAdapter
* adapter
,
225 BluetoothGattDescriptor
* descriptor
,
226 const std::vector
<uint8
>& value
) OVERRIDE
{
227 ASSERT_EQ(adapter_
.get(), adapter
);
229 ++gatt_descriptor_value_changed_count_
;
230 last_gatt_descriptor_id_
= descriptor
->GetIdentifier();
231 last_gatt_descriptor_uuid_
= descriptor
->GetUUID();
232 last_changed_descriptor_value_
= value
;
234 ASSERT_TRUE(descriptor
->GetCharacteristic());
235 EXPECT_EQ(descriptor
->GetCharacteristic()->GetDescriptor(
236 last_gatt_descriptor_id_
),
242 int gatt_service_added_count_
;
243 int gatt_service_removed_count_
;
244 int gatt_service_changed_count_
;
245 int gatt_discovery_complete_count_
;
246 int gatt_characteristic_added_count_
;
247 int gatt_characteristic_removed_count_
;
248 int gatt_characteristic_value_changed_count_
;
249 int gatt_descriptor_added_count_
;
250 int gatt_descriptor_removed_count_
;
251 int gatt_descriptor_value_changed_count_
;
252 std::string last_gatt_service_id_
;
253 BluetoothUUID last_gatt_service_uuid_
;
254 std::string last_gatt_characteristic_id_
;
255 BluetoothUUID last_gatt_characteristic_uuid_
;
256 std::vector
<uint8
> last_changed_characteristic_value_
;
257 std::string last_gatt_descriptor_id_
;
258 BluetoothUUID last_gatt_descriptor_uuid_
;
259 std::vector
<uint8
> last_changed_descriptor_value_
;
262 // Some tests use a message loop since background processing is simulated;
263 // break out of those loops.
264 void QuitMessageLoop() {
265 if (base::MessageLoop::current() &&
266 base::MessageLoop::current()->is_running())
267 base::MessageLoop::current()->Quit();
270 scoped_refptr
<BluetoothAdapter
> adapter_
;
275 class BluetoothGattChromeOSTest
: public testing::Test
{
277 BluetoothGattChromeOSTest()
278 : fake_bluetooth_gatt_service_client_(NULL
),
279 success_callback_count_(0),
280 error_callback_count_(0) {
283 virtual void SetUp() {
284 scoped_ptr
<DBusThreadManagerSetter
> dbus_setter
=
285 chromeos::DBusThreadManager::GetSetterForTesting();
286 fake_bluetooth_device_client_
= new FakeBluetoothDeviceClient
;
287 fake_bluetooth_gatt_service_client_
=
288 new FakeBluetoothGattServiceClient
;
289 fake_bluetooth_gatt_characteristic_client_
=
290 new FakeBluetoothGattCharacteristicClient
;
291 fake_bluetooth_gatt_descriptor_client_
=
292 new FakeBluetoothGattDescriptorClient
;
293 dbus_setter
->SetBluetoothDeviceClient(
294 scoped_ptr
<BluetoothDeviceClient
>(
295 fake_bluetooth_device_client_
));
296 dbus_setter
->SetBluetoothGattServiceClient(
297 scoped_ptr
<BluetoothGattServiceClient
>(
298 fake_bluetooth_gatt_service_client_
));
299 dbus_setter
->SetBluetoothGattCharacteristicClient(
300 scoped_ptr
<BluetoothGattCharacteristicClient
>(
301 fake_bluetooth_gatt_characteristic_client_
));
302 dbus_setter
->SetBluetoothGattDescriptorClient(
303 scoped_ptr
<BluetoothGattDescriptorClient
>(
304 fake_bluetooth_gatt_descriptor_client_
));
305 dbus_setter
->SetBluetoothAdapterClient(
306 scoped_ptr
<BluetoothAdapterClient
>(new FakeBluetoothAdapterClient
));
307 dbus_setter
->SetBluetoothInputClient(
308 scoped_ptr
<BluetoothInputClient
>(new FakeBluetoothInputClient
));
309 dbus_setter
->SetBluetoothAgentManagerClient(
310 scoped_ptr
<BluetoothAgentManagerClient
>(
311 new FakeBluetoothAgentManagerClient
));
315 adapter_
->SetPowered(
317 base::Bind(&base::DoNothing
),
318 base::Bind(&base::DoNothing
));
319 ASSERT_TRUE(adapter_
->IsPowered());
322 virtual void TearDown() {
324 update_sessions_
.clear();
326 DBusThreadManager::Shutdown();
330 device::BluetoothAdapterFactory::GetAdapter(
331 base::Bind(&BluetoothGattChromeOSTest::AdapterCallback
,
332 base::Unretained(this)));
333 ASSERT_TRUE(adapter_
.get() != NULL
);
334 ASSERT_TRUE(adapter_
->IsInitialized());
335 ASSERT_TRUE(adapter_
->IsPresent());
338 void AdapterCallback(scoped_refptr
<BluetoothAdapter
> adapter
) {
342 void SuccessCallback() {
343 ++success_callback_count_
;
346 void ValueCallback(const std::vector
<uint8
>& value
) {
347 ++success_callback_count_
;
348 last_read_value_
= value
;
351 void GattConnectionCallback(scoped_ptr
<BluetoothGattConnection
> conn
) {
352 ++success_callback_count_
;
353 gatt_conn_
= conn
.Pass();
356 void NotifySessionCallback(scoped_ptr
<BluetoothGattNotifySession
> session
) {
357 ++success_callback_count_
;
358 update_sessions_
.push_back(session
.release());
362 void ServiceErrorCallback(BluetoothGattService::GattErrorCode err
) {
363 ++error_callback_count_
;
364 last_service_error_
= err
;
367 void ErrorCallback() {
368 ++error_callback_count_
;
371 void DBusErrorCallback(const std::string
& error_name
,
372 const std::string
& error_message
) {
373 ++error_callback_count_
;
376 void ConnectErrorCallback(BluetoothDevice::ConnectErrorCode error
) {
377 ++error_callback_count_
;
381 void QuitMessageLoop() {
382 if (base::MessageLoop::current() &&
383 base::MessageLoop::current()->is_running())
384 base::MessageLoop::current()->Quit();
387 base::MessageLoop message_loop_
;
389 FakeBluetoothDeviceClient
* fake_bluetooth_device_client_
;
390 FakeBluetoothGattServiceClient
* fake_bluetooth_gatt_service_client_
;
391 FakeBluetoothGattCharacteristicClient
*
392 fake_bluetooth_gatt_characteristic_client_
;
393 FakeBluetoothGattDescriptorClient
* fake_bluetooth_gatt_descriptor_client_
;
394 scoped_ptr
<device::BluetoothGattConnection
> gatt_conn_
;
395 ScopedVector
<BluetoothGattNotifySession
> update_sessions_
;
396 scoped_refptr
<BluetoothAdapter
> adapter_
;
398 int success_callback_count_
;
399 int error_callback_count_
;
400 std::vector
<uint8
> last_read_value_
;
401 BluetoothGattService::GattErrorCode last_service_error_
;
404 TEST_F(BluetoothGattChromeOSTest
, GattConnection
) {
405 fake_bluetooth_device_client_
->CreateDevice(
406 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
407 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
408 BluetoothDevice
* device
= adapter_
->GetDevice(
409 FakeBluetoothDeviceClient::kLowEnergyAddress
);
411 ASSERT_FALSE(device
->IsConnected());
412 ASSERT_FALSE(gatt_conn_
.get());
413 ASSERT_EQ(0, success_callback_count_
);
414 ASSERT_EQ(0, error_callback_count_
);
416 device
->CreateGattConnection(
417 base::Bind(&BluetoothGattChromeOSTest::GattConnectionCallback
,
418 base::Unretained(this)),
419 base::Bind(&BluetoothGattChromeOSTest::ConnectErrorCallback
,
420 base::Unretained(this)));
422 EXPECT_EQ(1, success_callback_count_
);
423 EXPECT_EQ(0, error_callback_count_
);
424 EXPECT_TRUE(device
->IsConnected());
425 ASSERT_TRUE(gatt_conn_
.get());
426 EXPECT_TRUE(gatt_conn_
->IsConnected());
427 EXPECT_EQ(FakeBluetoothDeviceClient::kLowEnergyAddress
,
428 gatt_conn_
->GetDeviceAddress());
430 gatt_conn_
->Disconnect(
431 base::Bind(&BluetoothGattChromeOSTest::SuccessCallback
,
432 base::Unretained(this)));
433 EXPECT_EQ(2, success_callback_count_
);
434 EXPECT_EQ(0, error_callback_count_
);
435 EXPECT_TRUE(device
->IsConnected());
436 EXPECT_FALSE(gatt_conn_
->IsConnected());
438 device
->CreateGattConnection(
439 base::Bind(&BluetoothGattChromeOSTest::GattConnectionCallback
,
440 base::Unretained(this)),
441 base::Bind(&BluetoothGattChromeOSTest::ConnectErrorCallback
,
442 base::Unretained(this)));
444 EXPECT_EQ(3, success_callback_count_
);
445 EXPECT_EQ(0, error_callback_count_
);
446 EXPECT_TRUE(device
->IsConnected());
447 ASSERT_TRUE(gatt_conn_
.get());
448 EXPECT_TRUE(gatt_conn_
->IsConnected());
451 base::Bind(&BluetoothGattChromeOSTest::SuccessCallback
,
452 base::Unretained(this)),
453 base::Bind(&BluetoothGattChromeOSTest::ErrorCallback
,
454 base::Unretained(this)));
456 EXPECT_EQ(4, success_callback_count_
);
457 EXPECT_EQ(0, error_callback_count_
);
458 ASSERT_TRUE(gatt_conn_
.get());
459 EXPECT_FALSE(gatt_conn_
->IsConnected());
461 device
->CreateGattConnection(
462 base::Bind(&BluetoothGattChromeOSTest::GattConnectionCallback
,
463 base::Unretained(this)),
464 base::Bind(&BluetoothGattChromeOSTest::ConnectErrorCallback
,
465 base::Unretained(this)));
467 EXPECT_EQ(5, success_callback_count_
);
468 EXPECT_EQ(0, error_callback_count_
);
469 EXPECT_TRUE(device
->IsConnected());
470 EXPECT_TRUE(gatt_conn_
->IsConnected());
472 fake_bluetooth_device_client_
->RemoveDevice(
473 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
474 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
475 ASSERT_TRUE(gatt_conn_
.get());
476 EXPECT_FALSE(gatt_conn_
->IsConnected());
479 TEST_F(BluetoothGattChromeOSTest
, GattServiceAddedAndRemoved
) {
480 // Create a fake LE device. We store the device pointer here because this is a
481 // test. It's unsafe to do this in production as the device might get deleted.
482 fake_bluetooth_device_client_
->CreateDevice(
483 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
484 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
485 BluetoothDevice
* device
= adapter_
->GetDevice(
486 FakeBluetoothDeviceClient::kLowEnergyAddress
);
489 TestObserver
observer(adapter_
);
491 EXPECT_EQ(0, observer
.gatt_service_added_count_
);
492 EXPECT_EQ(0, observer
.gatt_service_removed_count_
);
493 EXPECT_TRUE(observer
.last_gatt_service_id_
.empty());
494 EXPECT_FALSE(observer
.last_gatt_service_uuid_
.IsValid());
495 EXPECT_TRUE(device
->GetGattServices().empty());
497 // Expose the fake Heart Rate Service.
498 fake_bluetooth_gatt_service_client_
->ExposeHeartRateService(
499 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
500 EXPECT_EQ(1, observer
.gatt_service_added_count_
);
501 EXPECT_EQ(0, observer
.gatt_service_removed_count_
);
502 EXPECT_FALSE(observer
.last_gatt_service_id_
.empty());
503 EXPECT_EQ(1U, device
->GetGattServices().size());
505 BluetoothUUID(FakeBluetoothGattServiceClient::kHeartRateServiceUUID
),
506 observer
.last_gatt_service_uuid_
);
508 BluetoothGattService
* service
=
509 device
->GetGattService(observer
.last_gatt_service_id_
);
510 EXPECT_FALSE(service
->IsLocal());
511 EXPECT_TRUE(service
->IsPrimary());
512 EXPECT_EQ(service
, device
->GetGattServices()[0]);
513 EXPECT_EQ(service
, device
->GetGattService(service
->GetIdentifier()));
515 EXPECT_EQ(observer
.last_gatt_service_uuid_
, service
->GetUUID());
518 observer
.last_gatt_service_uuid_
= BluetoothUUID();
519 observer
.last_gatt_service_id_
.clear();
520 fake_bluetooth_gatt_service_client_
->HideHeartRateService();
522 EXPECT_EQ(1, observer
.gatt_service_added_count_
);
523 EXPECT_EQ(1, observer
.gatt_service_removed_count_
);
524 EXPECT_FALSE(observer
.last_gatt_service_id_
.empty());
525 EXPECT_TRUE(device
->GetGattServices().empty());
527 BluetoothUUID(FakeBluetoothGattServiceClient::kHeartRateServiceUUID
),
528 observer
.last_gatt_service_uuid_
);
530 EXPECT_EQ(NULL
, device
->GetGattService(observer
.last_gatt_service_id_
));
532 // Expose the service again.
533 observer
.last_gatt_service_uuid_
= BluetoothUUID();
534 observer
.last_gatt_service_id_
.clear();
535 fake_bluetooth_gatt_service_client_
->ExposeHeartRateService(
536 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
537 EXPECT_EQ(2, observer
.gatt_service_added_count_
);
538 EXPECT_EQ(1, observer
.gatt_service_removed_count_
);
539 EXPECT_FALSE(observer
.last_gatt_service_id_
.empty());
540 EXPECT_EQ(1U, device
->GetGattServices().size());
542 BluetoothUUID(FakeBluetoothGattServiceClient::kHeartRateServiceUUID
),
543 observer
.last_gatt_service_uuid_
);
545 // The object |service| points to should have been deallocated. |device|
546 // should contain a brand new instance.
547 service
= device
->GetGattService(observer
.last_gatt_service_id_
);
548 EXPECT_EQ(service
, device
->GetGattServices()[0]);
549 EXPECT_FALSE(service
->IsLocal());
550 EXPECT_TRUE(service
->IsPrimary());
552 EXPECT_EQ(observer
.last_gatt_service_uuid_
, service
->GetUUID());
554 // Remove the device. The observer should be notified of the removed service.
555 // |device| becomes invalid after this.
556 observer
.last_gatt_service_uuid_
= BluetoothUUID();
557 observer
.last_gatt_service_id_
.clear();
558 fake_bluetooth_device_client_
->RemoveDevice(
559 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
560 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
562 EXPECT_EQ(2, observer
.gatt_service_added_count_
);
563 EXPECT_EQ(2, observer
.gatt_service_removed_count_
);
564 EXPECT_FALSE(observer
.last_gatt_service_id_
.empty());
566 BluetoothUUID(FakeBluetoothGattServiceClient::kHeartRateServiceUUID
),
567 observer
.last_gatt_service_uuid_
);
569 NULL
, adapter_
->GetDevice(FakeBluetoothDeviceClient::kLowEnergyAddress
));
572 TEST_F(BluetoothGattChromeOSTest
, GattCharacteristicAddedAndRemoved
) {
573 fake_bluetooth_device_client_
->CreateDevice(
574 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
575 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
576 BluetoothDevice
* device
= adapter_
->GetDevice(
577 FakeBluetoothDeviceClient::kLowEnergyAddress
);
580 TestObserver
observer(adapter_
);
582 // Expose the fake Heart Rate service. This will asynchronously expose
584 fake_bluetooth_gatt_service_client_
->ExposeHeartRateService(
585 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
586 ASSERT_EQ(1, observer
.gatt_service_added_count_
);
588 BluetoothGattService
* service
=
589 device
->GetGattService(observer
.last_gatt_service_id_
);
591 EXPECT_EQ(0, observer
.gatt_service_changed_count_
);
592 EXPECT_EQ(0, observer
.gatt_discovery_complete_count_
);
593 EXPECT_EQ(0, observer
.gatt_characteristic_added_count_
);
594 EXPECT_EQ(0, observer
.gatt_characteristic_removed_count_
);
595 EXPECT_EQ(0, observer
.gatt_characteristic_value_changed_count_
);
596 EXPECT_TRUE(service
->GetCharacteristics().empty());
598 // Run the message loop so that the characteristics appear.
599 base::MessageLoop::current()->Run();
601 // 3 characteristics should appear. Only 1 of the characteristics sends
602 // value changed signals. Service changed should be fired once for
604 EXPECT_EQ(0, observer
.gatt_service_changed_count_
);
605 EXPECT_EQ(1, observer
.gatt_discovery_complete_count_
);
606 EXPECT_EQ(3, observer
.gatt_characteristic_added_count_
);
607 EXPECT_EQ(0, observer
.gatt_characteristic_removed_count_
);
608 EXPECT_EQ(0, observer
.gatt_characteristic_value_changed_count_
);
609 EXPECT_EQ(3U, service
->GetCharacteristics().size());
611 // Hide the characteristics. 3 removed signals should be received.
612 fake_bluetooth_gatt_characteristic_client_
->HideHeartRateCharacteristics();
613 EXPECT_EQ(0, observer
.gatt_service_changed_count_
);
614 EXPECT_EQ(3, observer
.gatt_characteristic_added_count_
);
615 EXPECT_EQ(3, observer
.gatt_characteristic_removed_count_
);
616 EXPECT_EQ(0, observer
.gatt_characteristic_value_changed_count_
);
617 EXPECT_TRUE(service
->GetCharacteristics().empty());
619 // Re-expose the heart rate characteristics. We shouldn't get another
620 // GattDiscoveryCompleteForService call, since the service thinks that
621 // discovery is done. On the bluetoothd side, characteristics will be removed
622 // only if the service will also be subsequently removed.
623 fake_bluetooth_gatt_characteristic_client_
->ExposeHeartRateCharacteristics(
624 fake_bluetooth_gatt_service_client_
->GetHeartRateServicePath());
625 EXPECT_EQ(0, observer
.gatt_service_changed_count_
);
626 EXPECT_EQ(1, observer
.gatt_discovery_complete_count_
);
627 EXPECT_EQ(6, observer
.gatt_characteristic_added_count_
);
628 EXPECT_EQ(3, observer
.gatt_characteristic_removed_count_
);
629 EXPECT_EQ(0, observer
.gatt_characteristic_value_changed_count_
);
630 EXPECT_EQ(3U, service
->GetCharacteristics().size());
632 // Hide the service. All characteristics should disappear.
633 fake_bluetooth_gatt_service_client_
->HideHeartRateService();
634 EXPECT_EQ(0, observer
.gatt_service_changed_count_
);
635 EXPECT_EQ(6, observer
.gatt_characteristic_added_count_
);
636 EXPECT_EQ(6, observer
.gatt_characteristic_removed_count_
);
637 EXPECT_EQ(0, observer
.gatt_characteristic_value_changed_count_
);
640 TEST_F(BluetoothGattChromeOSTest
, GattDescriptorAddedAndRemoved
) {
641 fake_bluetooth_device_client_
->CreateDevice(
642 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
643 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
644 BluetoothDevice
* device
= adapter_
->GetDevice(
645 FakeBluetoothDeviceClient::kLowEnergyAddress
);
648 TestObserver
observer(adapter_
);
650 // Expose the fake Heart Rate service. This will asynchronously expose
652 fake_bluetooth_gatt_service_client_
->ExposeHeartRateService(
653 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
654 ASSERT_EQ(1, observer
.gatt_service_added_count_
);
656 BluetoothGattService
* service
=
657 device
->GetGattService(observer
.last_gatt_service_id_
);
659 EXPECT_EQ(0, observer
.gatt_service_changed_count_
);
660 EXPECT_EQ(0, observer
.gatt_descriptor_added_count_
);
661 EXPECT_EQ(0, observer
.gatt_descriptor_removed_count_
);
662 EXPECT_EQ(0, observer
.gatt_descriptor_value_changed_count_
);
664 EXPECT_TRUE(service
->GetCharacteristics().empty());
666 // Run the message loop so that the characteristics appear.
667 base::MessageLoop::current()->Run();
668 EXPECT_EQ(0, observer
.gatt_service_changed_count_
);
670 // Only the Heart Rate Measurement characteristic has a descriptor.
671 EXPECT_EQ(1, observer
.gatt_descriptor_added_count_
);
672 EXPECT_EQ(0, observer
.gatt_descriptor_removed_count_
);
673 EXPECT_EQ(0, observer
.gatt_descriptor_value_changed_count_
);
675 BluetoothGattCharacteristic
* characteristic
= service
->GetCharacteristic(
676 fake_bluetooth_gatt_characteristic_client_
->
677 GetBodySensorLocationPath().value());
678 ASSERT_TRUE(characteristic
);
679 EXPECT_TRUE(characteristic
->GetDescriptors().empty());
681 characteristic
= service
->GetCharacteristic(
682 fake_bluetooth_gatt_characteristic_client_
->
683 GetHeartRateControlPointPath().value());
684 ASSERT_TRUE(characteristic
);
685 EXPECT_TRUE(characteristic
->GetDescriptors().empty());
687 characteristic
= service
->GetCharacteristic(
688 fake_bluetooth_gatt_characteristic_client_
->
689 GetHeartRateMeasurementPath().value());
690 ASSERT_TRUE(characteristic
);
691 EXPECT_EQ(1U, characteristic
->GetDescriptors().size());
693 BluetoothGattDescriptor
* descriptor
= characteristic
->GetDescriptors()[0];
694 EXPECT_FALSE(descriptor
->IsLocal());
695 EXPECT_EQ(BluetoothGattDescriptor::ClientCharacteristicConfigurationUuid(),
696 descriptor
->GetUUID());
697 EXPECT_EQ(descriptor
->GetUUID(), observer
.last_gatt_descriptor_uuid_
);
698 EXPECT_EQ(descriptor
->GetIdentifier(), observer
.last_gatt_descriptor_id_
);
700 // Hide the descriptor.
701 fake_bluetooth_gatt_descriptor_client_
->HideDescriptor(
702 dbus::ObjectPath(descriptor
->GetIdentifier()));
703 EXPECT_TRUE(characteristic
->GetDescriptors().empty());
704 EXPECT_EQ(0, observer
.gatt_service_changed_count_
);
705 EXPECT_EQ(1, observer
.gatt_descriptor_added_count_
);
706 EXPECT_EQ(1, observer
.gatt_descriptor_removed_count_
);
707 EXPECT_EQ(0, observer
.gatt_descriptor_value_changed_count_
);
709 // Expose the descriptor again.
710 observer
.last_gatt_descriptor_id_
.clear();
711 observer
.last_gatt_descriptor_uuid_
= BluetoothUUID();
712 fake_bluetooth_gatt_descriptor_client_
->ExposeDescriptor(
713 dbus::ObjectPath(characteristic
->GetIdentifier()),
714 FakeBluetoothGattDescriptorClient::
715 kClientCharacteristicConfigurationUUID
);
716 EXPECT_EQ(0, observer
.gatt_service_changed_count_
);
717 EXPECT_EQ(1U, characteristic
->GetDescriptors().size());
718 EXPECT_EQ(2, observer
.gatt_descriptor_added_count_
);
719 EXPECT_EQ(1, observer
.gatt_descriptor_removed_count_
);
720 EXPECT_EQ(0, observer
.gatt_descriptor_value_changed_count_
);
722 descriptor
= characteristic
->GetDescriptors()[0];
723 EXPECT_FALSE(descriptor
->IsLocal());
724 EXPECT_EQ(BluetoothGattDescriptor::ClientCharacteristicConfigurationUuid(),
725 descriptor
->GetUUID());
726 EXPECT_EQ(descriptor
->GetUUID(), observer
.last_gatt_descriptor_uuid_
);
727 EXPECT_EQ(descriptor
->GetIdentifier(), observer
.last_gatt_descriptor_id_
);
730 TEST_F(BluetoothGattChromeOSTest
, AdapterAddedAfterGattService
) {
731 // This unit test tests that all remote GATT objects are created for D-Bus
732 // objects that were already exposed.
734 ASSERT_FALSE(device::BluetoothAdapterFactory::HasSharedInstanceForTesting());
736 // Create the fake D-Bus objects.
737 fake_bluetooth_device_client_
->CreateDevice(
738 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
739 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
740 fake_bluetooth_gatt_service_client_
->ExposeHeartRateService(
741 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
742 while (!fake_bluetooth_gatt_characteristic_client_
->IsHeartRateVisible())
743 base::RunLoop().RunUntilIdle();
744 ASSERT_TRUE(fake_bluetooth_gatt_service_client_
->IsHeartRateVisible());
745 ASSERT_TRUE(fake_bluetooth_gatt_characteristic_client_
->IsHeartRateVisible());
747 // Create the adapter. This should create all the GATT objects.
749 BluetoothDevice
* device
= adapter_
->GetDevice(
750 FakeBluetoothDeviceClient::kLowEnergyAddress
);
752 EXPECT_EQ(1U, device
->GetGattServices().size());
754 BluetoothGattService
* service
= device
->GetGattServices()[0];
755 ASSERT_TRUE(service
);
756 EXPECT_FALSE(service
->IsLocal());
757 EXPECT_TRUE(service
->IsPrimary());
759 BluetoothUUID(FakeBluetoothGattServiceClient::kHeartRateServiceUUID
),
761 EXPECT_EQ(service
, device
->GetGattServices()[0]);
762 EXPECT_EQ(service
, device
->GetGattService(service
->GetIdentifier()));
763 EXPECT_FALSE(service
->IsLocal());
764 EXPECT_EQ(3U, service
->GetCharacteristics().size());
766 BluetoothGattCharacteristic
* characteristic
= service
->GetCharacteristic(
767 fake_bluetooth_gatt_characteristic_client_
->
768 GetBodySensorLocationPath().value());
769 ASSERT_TRUE(characteristic
);
771 BluetoothUUID(FakeBluetoothGattCharacteristicClient::
772 kBodySensorLocationUUID
),
773 characteristic
->GetUUID());
774 EXPECT_FALSE(characteristic
->IsLocal());
775 EXPECT_TRUE(characteristic
->GetDescriptors().empty());
777 characteristic
= service
->GetCharacteristic(
778 fake_bluetooth_gatt_characteristic_client_
->
779 GetHeartRateControlPointPath().value());
780 ASSERT_TRUE(characteristic
);
782 BluetoothUUID(FakeBluetoothGattCharacteristicClient::
783 kHeartRateControlPointUUID
),
784 characteristic
->GetUUID());
785 EXPECT_FALSE(characteristic
->IsLocal());
786 EXPECT_TRUE(characteristic
->GetDescriptors().empty());
788 characteristic
= service
->GetCharacteristic(
789 fake_bluetooth_gatt_characteristic_client_
->
790 GetHeartRateMeasurementPath().value());
791 ASSERT_TRUE(characteristic
);
793 BluetoothUUID(FakeBluetoothGattCharacteristicClient::
794 kHeartRateMeasurementUUID
),
795 characteristic
->GetUUID());
796 EXPECT_FALSE(characteristic
->IsLocal());
797 EXPECT_EQ(1U, characteristic
->GetDescriptors().size());
799 BluetoothGattDescriptor
* descriptor
= characteristic
->GetDescriptors()[0];
800 ASSERT_TRUE(descriptor
);
801 EXPECT_EQ(BluetoothGattDescriptor::ClientCharacteristicConfigurationUuid(),
802 descriptor
->GetUUID());
803 EXPECT_FALSE(descriptor
->IsLocal());
806 TEST_F(BluetoothGattChromeOSTest
, GattCharacteristicValue
) {
807 fake_bluetooth_device_client_
->CreateDevice(
808 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
809 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
810 BluetoothDevice
* device
= adapter_
->GetDevice(
811 FakeBluetoothDeviceClient::kLowEnergyAddress
);
814 TestObserver
observer(adapter_
);
816 // Expose the fake Heart Rate service. This will asynchronously expose
818 fake_bluetooth_gatt_service_client_
->ExposeHeartRateService(
819 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
820 ASSERT_EQ(1, observer
.gatt_service_added_count_
);
822 BluetoothGattService
* service
=
823 device
->GetGattService(observer
.last_gatt_service_id_
);
825 EXPECT_EQ(0, observer
.gatt_characteristic_value_changed_count_
);
827 // Run the message loop so that the characteristics appear.
828 base::MessageLoop::current()->Run();
830 // Issue write request to non-writeable characteristics.
831 observer
.last_gatt_characteristic_id_
.clear();
832 observer
.last_gatt_characteristic_uuid_
= BluetoothUUID();
834 std::vector
<uint8
> write_value
;
835 write_value
.push_back(0x01);
836 BluetoothGattCharacteristic
* characteristic
=
837 service
->GetCharacteristic(fake_bluetooth_gatt_characteristic_client_
->
838 GetHeartRateMeasurementPath().value());
839 ASSERT_TRUE(characteristic
);
840 EXPECT_FALSE(characteristic
->IsNotifying());
841 EXPECT_EQ(fake_bluetooth_gatt_characteristic_client_
->
842 GetHeartRateMeasurementPath().value(),
843 characteristic
->GetIdentifier());
844 EXPECT_EQ(kHeartRateMeasurementUUID
, characteristic
->GetUUID());
845 characteristic
->WriteRemoteCharacteristic(
847 base::Bind(&BluetoothGattChromeOSTest::SuccessCallback
,
848 base::Unretained(this)),
849 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback
,
850 base::Unretained(this)));
851 EXPECT_TRUE(observer
.last_gatt_characteristic_id_
.empty());
852 EXPECT_FALSE(observer
.last_gatt_characteristic_uuid_
.IsValid());
853 EXPECT_EQ(0, success_callback_count_
);
854 EXPECT_EQ(1, error_callback_count_
);
855 EXPECT_EQ(BluetoothGattService::GATT_ERROR_NOT_SUPPORTED
,
856 last_service_error_
);
857 EXPECT_EQ(0, observer
.gatt_characteristic_value_changed_count_
);
859 characteristic
= service
->GetCharacteristic(
860 fake_bluetooth_gatt_characteristic_client_
->
861 GetBodySensorLocationPath().value());
862 ASSERT_TRUE(characteristic
);
863 EXPECT_EQ(fake_bluetooth_gatt_characteristic_client_
->
864 GetBodySensorLocationPath().value(),
865 characteristic
->GetIdentifier());
866 EXPECT_EQ(kBodySensorLocationUUID
, characteristic
->GetUUID());
867 characteristic
->WriteRemoteCharacteristic(
869 base::Bind(&BluetoothGattChromeOSTest::SuccessCallback
,
870 base::Unretained(this)),
871 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback
,
872 base::Unretained(this)));
873 EXPECT_TRUE(observer
.last_gatt_characteristic_id_
.empty());
874 EXPECT_FALSE(observer
.last_gatt_characteristic_uuid_
.IsValid());
875 EXPECT_EQ(0, success_callback_count_
);
876 EXPECT_EQ(2, error_callback_count_
);
877 EXPECT_EQ(BluetoothGattService::GATT_ERROR_NOT_PERMITTED
,
878 last_service_error_
);
879 EXPECT_EQ(0, observer
.gatt_characteristic_value_changed_count_
);
881 // Issue write request to writeable characteristic. The "Body Sensor Location"
882 // characteristic does not send notifications and WriteValue does not result
883 // in a CharacteristicValueChanged event, thus no such event should be
885 characteristic
= service
->GetCharacteristic(
886 fake_bluetooth_gatt_characteristic_client_
->
887 GetHeartRateControlPointPath().value());
888 ASSERT_TRUE(characteristic
);
889 EXPECT_EQ(fake_bluetooth_gatt_characteristic_client_
->
890 GetHeartRateControlPointPath().value(),
891 characteristic
->GetIdentifier());
892 EXPECT_EQ(kHeartRateControlPointUUID
, characteristic
->GetUUID());
893 characteristic
->WriteRemoteCharacteristic(
895 base::Bind(&BluetoothGattChromeOSTest::SuccessCallback
,
896 base::Unretained(this)),
897 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback
,
898 base::Unretained(this)));
899 EXPECT_TRUE(observer
.last_gatt_characteristic_id_
.empty());
900 EXPECT_FALSE(observer
.last_gatt_characteristic_uuid_
.IsValid());
901 EXPECT_EQ(1, success_callback_count_
);
902 EXPECT_EQ(2, error_callback_count_
);
903 EXPECT_EQ(0, observer
.gatt_characteristic_value_changed_count_
);
905 // Issue some invalid write requests to the characteristic.
906 // The value should still not change.
908 std::vector
<uint8
> invalid_write_length
;
909 invalid_write_length
.push_back(0x01);
910 invalid_write_length
.push_back(0x00);
911 characteristic
->WriteRemoteCharacteristic(
912 invalid_write_length
,
913 base::Bind(&BluetoothGattChromeOSTest::SuccessCallback
,
914 base::Unretained(this)),
915 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback
,
916 base::Unretained(this)));
917 EXPECT_EQ(1, success_callback_count_
);
918 EXPECT_EQ(3, error_callback_count_
);
919 EXPECT_EQ(BluetoothGattService::GATT_ERROR_INVALID_LENGTH
,
920 last_service_error_
);
921 EXPECT_EQ(0, observer
.gatt_characteristic_value_changed_count_
);
923 std::vector
<uint8
> invalid_write_value
;
924 invalid_write_value
.push_back(0x02);
925 characteristic
->WriteRemoteCharacteristic(
927 base::Bind(&BluetoothGattChromeOSTest::SuccessCallback
,
928 base::Unretained(this)),
929 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback
,
930 base::Unretained(this)));
931 EXPECT_EQ(1, success_callback_count_
);
932 EXPECT_EQ(4, error_callback_count_
);
933 EXPECT_EQ(BluetoothGattService::GATT_ERROR_FAILED
, last_service_error_
);
934 EXPECT_EQ(0, observer
.gatt_characteristic_value_changed_count_
);
936 // Issue a read request. A successful read results in a
937 // CharacteristicValueChanged notification.
938 characteristic
= service
->GetCharacteristic(
939 fake_bluetooth_gatt_characteristic_client_
->
940 GetBodySensorLocationPath().value());
941 ASSERT_TRUE(characteristic
);
942 EXPECT_EQ(fake_bluetooth_gatt_characteristic_client_
->
943 GetBodySensorLocationPath().value(),
944 characteristic
->GetIdentifier());
945 EXPECT_EQ(kBodySensorLocationUUID
, characteristic
->GetUUID());
946 characteristic
->ReadRemoteCharacteristic(
947 base::Bind(&BluetoothGattChromeOSTest::ValueCallback
,
948 base::Unretained(this)),
949 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback
,
950 base::Unretained(this)));
951 EXPECT_EQ(2, success_callback_count_
);
952 EXPECT_EQ(4, error_callback_count_
);
953 EXPECT_EQ(1, observer
.gatt_characteristic_value_changed_count_
);
954 EXPECT_TRUE(ValuesEqual(characteristic
->GetValue(), last_read_value_
));
956 // Test long-running actions.
957 fake_bluetooth_gatt_characteristic_client_
->SetExtraProcessing(1);
958 characteristic
= service
->GetCharacteristic(
959 fake_bluetooth_gatt_characteristic_client_
->GetBodySensorLocationPath()
961 ASSERT_TRUE(characteristic
);
963 fake_bluetooth_gatt_characteristic_client_
->GetBodySensorLocationPath()
965 characteristic
->GetIdentifier());
966 EXPECT_EQ(kBodySensorLocationUUID
, characteristic
->GetUUID());
967 characteristic
->ReadRemoteCharacteristic(
968 base::Bind(&BluetoothGattChromeOSTest::ValueCallback
,
969 base::Unretained(this)),
970 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback
,
971 base::Unretained(this)));
973 // Callback counts shouldn't change, this one will be delayed until after
975 EXPECT_EQ(2, success_callback_count_
);
976 EXPECT_EQ(4, error_callback_count_
);
977 EXPECT_EQ(1, observer
.gatt_characteristic_value_changed_count_
);
979 // Next read should error because IN_PROGRESS
980 characteristic
->ReadRemoteCharacteristic(
981 base::Bind(&BluetoothGattChromeOSTest::ValueCallback
,
982 base::Unretained(this)),
983 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback
,
984 base::Unretained(this)));
985 EXPECT_EQ(5, error_callback_count_
);
986 EXPECT_EQ(BluetoothGattService::GATT_ERROR_IN_PROGRESS
, last_service_error_
);
988 // But previous call finished.
989 EXPECT_EQ(3, success_callback_count_
);
990 EXPECT_EQ(2, observer
.gatt_characteristic_value_changed_count_
);
991 EXPECT_TRUE(ValuesEqual(characteristic
->GetValue(), last_read_value_
));
992 fake_bluetooth_gatt_characteristic_client_
->SetExtraProcessing(0);
994 // Test unauthorized actions.
995 fake_bluetooth_gatt_characteristic_client_
->SetAuthorized(false);
996 characteristic
->ReadRemoteCharacteristic(
997 base::Bind(&BluetoothGattChromeOSTest::ValueCallback
,
998 base::Unretained(this)),
999 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback
,
1000 base::Unretained(this)));
1001 EXPECT_EQ(3, success_callback_count_
);
1002 EXPECT_EQ(6, error_callback_count_
);
1003 EXPECT_EQ(BluetoothGattService::GATT_ERROR_NOT_AUTHORIZED
,
1004 last_service_error_
);
1005 EXPECT_EQ(2, observer
.gatt_characteristic_value_changed_count_
);
1006 fake_bluetooth_gatt_characteristic_client_
->SetAuthorized(true);
1008 // Test unauthenticated / needs login.
1009 fake_bluetooth_gatt_characteristic_client_
->SetAuthenticated(false);
1010 characteristic
->ReadRemoteCharacteristic(
1011 base::Bind(&BluetoothGattChromeOSTest::ValueCallback
,
1012 base::Unretained(this)),
1013 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback
,
1014 base::Unretained(this)));
1015 EXPECT_EQ(3, success_callback_count_
);
1016 EXPECT_EQ(7, error_callback_count_
);
1017 EXPECT_EQ(BluetoothGattService::GATT_ERROR_NOT_PAIRED
, last_service_error_
);
1018 EXPECT_EQ(2, observer
.gatt_characteristic_value_changed_count_
);
1019 fake_bluetooth_gatt_characteristic_client_
->SetAuthenticated(true);
1022 TEST_F(BluetoothGattChromeOSTest
, GattCharacteristicProperties
) {
1023 fake_bluetooth_device_client_
->CreateDevice(
1024 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
1025 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
1026 BluetoothDevice
* device
= adapter_
->GetDevice(
1027 FakeBluetoothDeviceClient::kLowEnergyAddress
);
1028 ASSERT_TRUE(device
);
1030 TestObserver
observer(adapter_
);
1032 // Expose the fake Heart Rate service. This will asynchronously expose
1034 fake_bluetooth_gatt_service_client_
->ExposeHeartRateService(
1035 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
1037 BluetoothGattService
* service
=
1038 device
->GetGattService(observer
.last_gatt_service_id_
);
1040 EXPECT_TRUE(service
->GetCharacteristics().empty());
1042 // Run the message loop so that the characteristics appear.
1043 base::MessageLoop::current()->Run();
1045 BluetoothGattCharacteristic
*characteristic
= service
->GetCharacteristic(
1046 fake_bluetooth_gatt_characteristic_client_
->
1047 GetBodySensorLocationPath().value());
1048 EXPECT_EQ(BluetoothGattCharacteristic::kPropertyRead
,
1049 characteristic
->GetProperties());
1051 characteristic
= service
->GetCharacteristic(
1052 fake_bluetooth_gatt_characteristic_client_
->
1053 GetHeartRateControlPointPath().value());
1054 EXPECT_EQ(BluetoothGattCharacteristic::kPropertyWrite
,
1055 characteristic
->GetProperties());
1057 characteristic
= service
->GetCharacteristic(
1058 fake_bluetooth_gatt_characteristic_client_
->
1059 GetHeartRateMeasurementPath().value());
1060 EXPECT_EQ(BluetoothGattCharacteristic::kPropertyNotify
,
1061 characteristic
->GetProperties());
1064 TEST_F(BluetoothGattChromeOSTest
, GattDescriptorValue
) {
1065 fake_bluetooth_device_client_
->CreateDevice(
1066 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
1067 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
1068 BluetoothDevice
* device
= adapter_
->GetDevice(
1069 FakeBluetoothDeviceClient::kLowEnergyAddress
);
1070 ASSERT_TRUE(device
);
1072 TestObserver
observer(adapter_
);
1074 // Expose the fake Heart Rate service. This will asynchronously expose
1076 fake_bluetooth_gatt_service_client_
->ExposeHeartRateService(
1077 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
1078 ASSERT_EQ(1, observer
.gatt_service_added_count_
);
1080 BluetoothGattService
* service
=
1081 device
->GetGattService(observer
.last_gatt_service_id_
);
1083 EXPECT_EQ(0, observer
.gatt_service_changed_count_
);
1084 EXPECT_EQ(0, observer
.gatt_discovery_complete_count_
);
1085 EXPECT_EQ(0, observer
.gatt_descriptor_value_changed_count_
);
1086 EXPECT_TRUE(service
->GetCharacteristics().empty());
1088 // Run the message loop so that the characteristics appear.
1089 base::MessageLoop::current()->Run();
1090 EXPECT_EQ(0, observer
.gatt_service_changed_count_
);
1091 EXPECT_EQ(1, observer
.gatt_discovery_complete_count_
);
1093 // Only the Heart Rate Measurement characteristic has a descriptor.
1094 BluetoothGattCharacteristic
* characteristic
= service
->GetCharacteristic(
1095 fake_bluetooth_gatt_characteristic_client_
->
1096 GetHeartRateMeasurementPath().value());
1097 ASSERT_TRUE(characteristic
);
1098 EXPECT_EQ(1U, characteristic
->GetDescriptors().size());
1100 BluetoothGattDescriptor
* descriptor
= characteristic
->GetDescriptors()[0];
1101 EXPECT_FALSE(descriptor
->IsLocal());
1102 EXPECT_EQ(BluetoothGattDescriptor::ClientCharacteristicConfigurationUuid(),
1103 descriptor
->GetUUID());
1105 std::vector
<uint8
> desc_value
;
1106 desc_value
.push_back(1);
1107 desc_value
.push_back(0);
1109 /* The cached value will be empty until the first read request */
1110 EXPECT_FALSE(ValuesEqual(desc_value
, descriptor
->GetValue()));
1111 EXPECT_TRUE(descriptor
->GetValue().empty());
1113 EXPECT_EQ(0, success_callback_count_
);
1114 EXPECT_EQ(0, error_callback_count_
);
1115 EXPECT_TRUE(last_read_value_
.empty());
1117 // Read value. GattDescriptorValueChanged event will be sent after a
1119 descriptor
->ReadRemoteDescriptor(
1120 base::Bind(&BluetoothGattChromeOSTest::ValueCallback
,
1121 base::Unretained(this)),
1122 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback
,
1123 base::Unretained(this)));
1124 EXPECT_EQ(1, success_callback_count_
);
1125 EXPECT_EQ(0, error_callback_count_
);
1126 EXPECT_TRUE(ValuesEqual(last_read_value_
, descriptor
->GetValue()));
1127 EXPECT_TRUE(ValuesEqual(desc_value
, descriptor
->GetValue()));
1128 EXPECT_EQ(0, observer
.gatt_service_changed_count_
);
1129 EXPECT_EQ(1, observer
.gatt_descriptor_value_changed_count_
);
1131 // Write value. Writes to this descriptor will fail.
1132 desc_value
[0] = 0x03;
1133 descriptor
->WriteRemoteDescriptor(
1135 base::Bind(&BluetoothGattChromeOSTest::SuccessCallback
,
1136 base::Unretained(this)),
1137 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback
,
1138 base::Unretained(this)));
1139 EXPECT_EQ(1, success_callback_count_
);
1140 EXPECT_EQ(1, error_callback_count_
);
1141 EXPECT_EQ(BluetoothGattService::GATT_ERROR_NOT_PERMITTED
,
1142 last_service_error_
);
1143 EXPECT_TRUE(ValuesEqual(last_read_value_
, descriptor
->GetValue()));
1144 EXPECT_FALSE(ValuesEqual(desc_value
, descriptor
->GetValue()));
1145 EXPECT_EQ(0, observer
.gatt_service_changed_count_
);
1146 EXPECT_EQ(1, observer
.gatt_descriptor_value_changed_count_
);
1149 descriptor
->ReadRemoteDescriptor(
1150 base::Bind(&BluetoothGattChromeOSTest::ValueCallback
,
1151 base::Unretained(this)),
1152 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback
,
1153 base::Unretained(this)));
1154 EXPECT_EQ(2, success_callback_count_
);
1155 EXPECT_EQ(1, error_callback_count_
);
1156 EXPECT_TRUE(ValuesEqual(last_read_value_
, descriptor
->GetValue()));
1157 EXPECT_FALSE(ValuesEqual(desc_value
, descriptor
->GetValue()));
1158 EXPECT_EQ(0, observer
.gatt_service_changed_count_
);
1159 EXPECT_EQ(2, observer
.gatt_descriptor_value_changed_count_
);
1162 TEST_F(BluetoothGattChromeOSTest
, NotifySessions
) {
1163 fake_bluetooth_device_client_
->CreateDevice(
1164 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
1165 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
1166 BluetoothDevice
* device
=
1167 adapter_
->GetDevice(FakeBluetoothDeviceClient::kLowEnergyAddress
);
1168 ASSERT_TRUE(device
);
1170 TestObserver
observer(adapter_
);
1172 // Expose the fake Heart Rate service. This will asynchronously expose
1174 fake_bluetooth_gatt_service_client_
->ExposeHeartRateService(
1175 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
1176 ASSERT_EQ(1, observer
.gatt_service_added_count_
);
1178 BluetoothGattService
* service
=
1179 device
->GetGattService(observer
.last_gatt_service_id_
);
1181 EXPECT_EQ(0, observer
.gatt_characteristic_value_changed_count_
);
1183 // Run the message loop so that the characteristics appear.
1184 base::MessageLoop::current()->Run();
1186 BluetoothGattCharacteristic
* characteristic
= service
->GetCharacteristic(
1187 fake_bluetooth_gatt_characteristic_client_
->GetHeartRateMeasurementPath()
1189 ASSERT_TRUE(characteristic
);
1190 EXPECT_FALSE(characteristic
->IsNotifying());
1191 EXPECT_TRUE(update_sessions_
.empty());
1193 // Request to start notifications.
1194 characteristic
->StartNotifySession(
1195 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback
,
1196 base::Unretained(this)),
1197 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback
,
1198 base::Unretained(this)));
1200 // The operation still hasn't completed but we should have received the first
1202 EXPECT_EQ(0, success_callback_count_
);
1203 EXPECT_EQ(0, error_callback_count_
);
1204 EXPECT_EQ(1, observer
.gatt_characteristic_value_changed_count_
);
1205 EXPECT_TRUE(update_sessions_
.empty());
1207 // Send a two more requests, which should get queued.
1208 characteristic
->StartNotifySession(
1209 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback
,
1210 base::Unretained(this)),
1211 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback
,
1212 base::Unretained(this)));
1213 characteristic
->StartNotifySession(
1214 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback
,
1215 base::Unretained(this)),
1216 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback
,
1217 base::Unretained(this)));
1218 EXPECT_EQ(0, success_callback_count_
);
1219 EXPECT_EQ(0, error_callback_count_
);
1220 EXPECT_EQ(1, observer
.gatt_characteristic_value_changed_count_
);
1221 EXPECT_TRUE(update_sessions_
.empty());
1222 EXPECT_TRUE(characteristic
->IsNotifying());
1224 // Run the main loop. The initial call should complete. The queued call should
1225 // succeed immediately.
1226 base::MessageLoop::current()->Run();
1228 EXPECT_EQ(3, success_callback_count_
);
1229 EXPECT_EQ(0, error_callback_count_
);
1230 EXPECT_EQ(1, observer
.gatt_characteristic_value_changed_count_
);
1231 EXPECT_EQ(3U, update_sessions_
.size());
1233 // Notifications should be getting sent regularly now.
1234 base::MessageLoop::current()->Run();
1235 EXPECT_GT(observer
.gatt_characteristic_value_changed_count_
, 1);
1237 // Stop one of the sessions. The session should become inactive but the
1238 // characteristic should still be notifying.
1239 BluetoothGattNotifySession
* session
= update_sessions_
[0];
1240 EXPECT_TRUE(session
->IsActive());
1241 session
->Stop(base::Bind(&BluetoothGattChromeOSTest::SuccessCallback
,
1242 base::Unretained(this)));
1243 EXPECT_EQ(4, success_callback_count_
);
1244 EXPECT_EQ(0, error_callback_count_
);
1245 EXPECT_FALSE(session
->IsActive());
1246 EXPECT_EQ(characteristic
->GetIdentifier(),
1247 session
->GetCharacteristicIdentifier());
1248 EXPECT_TRUE(characteristic
->IsNotifying());
1250 // Delete another session. Characteristic should still be notifying.
1251 update_sessions_
.pop_back();
1252 EXPECT_EQ(2U, update_sessions_
.size());
1253 EXPECT_TRUE(characteristic
->IsNotifying());
1254 EXPECT_FALSE(update_sessions_
[0]->IsActive());
1255 EXPECT_TRUE(update_sessions_
[1]->IsActive());
1257 // Clear the last session.
1258 update_sessions_
.clear();
1259 EXPECT_TRUE(update_sessions_
.empty());
1260 EXPECT_FALSE(characteristic
->IsNotifying());
1262 success_callback_count_
= 0;
1263 observer
.gatt_characteristic_value_changed_count_
= 0;
1265 // Enable notifications again.
1266 characteristic
->StartNotifySession(
1267 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback
,
1268 base::Unretained(this)),
1269 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback
,
1270 base::Unretained(this)));
1271 EXPECT_EQ(0, success_callback_count_
);
1272 EXPECT_EQ(0, error_callback_count_
);
1273 EXPECT_EQ(1, observer
.gatt_characteristic_value_changed_count_
);
1274 EXPECT_TRUE(update_sessions_
.empty());
1275 EXPECT_TRUE(characteristic
->IsNotifying());
1277 // Run the message loop. Notifications should begin.
1278 base::MessageLoop::current()->Run();
1280 EXPECT_EQ(1, success_callback_count_
);
1281 EXPECT_EQ(0, error_callback_count_
);
1282 EXPECT_EQ(1, observer
.gatt_characteristic_value_changed_count_
);
1283 EXPECT_EQ(1U, update_sessions_
.size());
1284 EXPECT_TRUE(update_sessions_
[0]->IsActive());
1285 EXPECT_TRUE(characteristic
->IsNotifying());
1287 // Check that notifications are happening.
1288 base::MessageLoop::current()->Run();
1289 EXPECT_GT(observer
.gatt_characteristic_value_changed_count_
, 1);
1291 // Request another session. This should return immediately.
1292 characteristic
->StartNotifySession(
1293 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback
,
1294 base::Unretained(this)),
1295 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback
,
1296 base::Unretained(this)));
1297 EXPECT_EQ(2, success_callback_count_
);
1298 EXPECT_EQ(0, error_callback_count_
);
1299 EXPECT_EQ(2U, update_sessions_
.size());
1300 EXPECT_TRUE(update_sessions_
[0]->IsActive());
1301 EXPECT_TRUE(update_sessions_
[1]->IsActive());
1302 EXPECT_TRUE(characteristic
->IsNotifying());
1304 // Hide the characteristic. The sessions should become inactive.
1305 fake_bluetooth_gatt_characteristic_client_
->HideHeartRateCharacteristics();
1306 EXPECT_EQ(2U, update_sessions_
.size());
1307 EXPECT_FALSE(update_sessions_
[0]->IsActive());
1308 EXPECT_FALSE(update_sessions_
[1]->IsActive());
1311 TEST_F(BluetoothGattChromeOSTest
, NotifySessionsMadeInactive
) {
1312 fake_bluetooth_device_client_
->CreateDevice(
1313 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
1314 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
1315 BluetoothDevice
* device
=
1316 adapter_
->GetDevice(FakeBluetoothDeviceClient::kLowEnergyAddress
);
1317 ASSERT_TRUE(device
);
1319 TestObserver
observer(adapter_
);
1321 // Expose the fake Heart Rate service. This will asynchronously expose
1323 fake_bluetooth_gatt_service_client_
->ExposeHeartRateService(
1324 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
1325 ASSERT_EQ(1, observer
.gatt_service_added_count_
);
1327 BluetoothGattService
* service
=
1328 device
->GetGattService(observer
.last_gatt_service_id_
);
1330 EXPECT_EQ(0, observer
.gatt_characteristic_value_changed_count_
);
1332 // Run the message loop so that the characteristics appear.
1333 base::MessageLoop::current()->Run();
1335 BluetoothGattCharacteristic
* characteristic
= service
->GetCharacteristic(
1336 fake_bluetooth_gatt_characteristic_client_
->GetHeartRateMeasurementPath()
1338 ASSERT_TRUE(characteristic
);
1339 EXPECT_FALSE(characteristic
->IsNotifying());
1340 EXPECT_TRUE(update_sessions_
.empty());
1342 // Send several requests to start notifications.
1343 characteristic
->StartNotifySession(
1344 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback
,
1345 base::Unretained(this)),
1346 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback
,
1347 base::Unretained(this)));
1348 characteristic
->StartNotifySession(
1349 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback
,
1350 base::Unretained(this)),
1351 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback
,
1352 base::Unretained(this)));
1353 characteristic
->StartNotifySession(
1354 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback
,
1355 base::Unretained(this)),
1356 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback
,
1357 base::Unretained(this)));
1358 characteristic
->StartNotifySession(
1359 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback
,
1360 base::Unretained(this)),
1361 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback
,
1362 base::Unretained(this)));
1364 // The operation still hasn't completed but we should have received the first
1366 EXPECT_EQ(0, success_callback_count_
);
1367 EXPECT_EQ(0, error_callback_count_
);
1368 EXPECT_EQ(1, observer
.gatt_characteristic_value_changed_count_
);
1369 EXPECT_TRUE(characteristic
->IsNotifying());
1370 EXPECT_TRUE(update_sessions_
.empty());
1372 // Run the main loop. The initial call should complete. The queued calls
1373 // should succeed immediately.
1374 base::MessageLoop::current()->Run();
1376 EXPECT_EQ(4, success_callback_count_
);
1377 EXPECT_EQ(0, error_callback_count_
);
1378 EXPECT_EQ(1, observer
.gatt_characteristic_value_changed_count_
);
1379 EXPECT_TRUE(characteristic
->IsNotifying());
1380 EXPECT_EQ(4U, update_sessions_
.size());
1382 for (int i
= 0; i
< 4; i
++)
1383 EXPECT_TRUE(update_sessions_
[0]->IsActive());
1385 // Stop notifications directly through the client. The sessions should get
1386 // marked as inactive.
1387 fake_bluetooth_gatt_characteristic_client_
->StopNotify(
1388 fake_bluetooth_gatt_characteristic_client_
->GetHeartRateMeasurementPath(),
1389 base::Bind(&BluetoothGattChromeOSTest::SuccessCallback
,
1390 base::Unretained(this)),
1391 base::Bind(&BluetoothGattChromeOSTest::DBusErrorCallback
,
1392 base::Unretained(this)));
1393 EXPECT_EQ(5, success_callback_count_
);
1394 EXPECT_EQ(0, error_callback_count_
);
1395 EXPECT_FALSE(characteristic
->IsNotifying());
1396 EXPECT_EQ(4U, update_sessions_
.size());
1398 for (int i
= 0; i
< 4; i
++)
1399 EXPECT_FALSE(update_sessions_
[0]->IsActive());
1401 // It should be possible to restart notifications and the call should reset
1402 // the session count and make a request through the client.
1403 update_sessions_
.clear();
1404 success_callback_count_
= 0;
1405 observer
.gatt_characteristic_value_changed_count_
= 0;
1406 characteristic
->StartNotifySession(
1407 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback
,
1408 base::Unretained(this)),
1409 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback
,
1410 base::Unretained(this)));
1412 EXPECT_EQ(0, success_callback_count_
);
1413 EXPECT_EQ(0, error_callback_count_
);
1414 EXPECT_EQ(1, observer
.gatt_characteristic_value_changed_count_
);
1415 EXPECT_TRUE(characteristic
->IsNotifying());
1416 EXPECT_TRUE(update_sessions_
.empty());
1418 base::MessageLoop::current()->Run();
1420 EXPECT_EQ(1, success_callback_count_
);
1421 EXPECT_EQ(0, error_callback_count_
);
1422 EXPECT_EQ(1, observer
.gatt_characteristic_value_changed_count_
);
1423 EXPECT_TRUE(characteristic
->IsNotifying());
1424 EXPECT_EQ(1U, update_sessions_
.size());
1425 EXPECT_TRUE(update_sessions_
[0]->IsActive());
1428 } // namespace chromeos