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 ErrorCallback() {
363 ++error_callback_count_
;
366 void DBusErrorCallback(const std::string
& error_name
,
367 const std::string
& error_message
) {
368 ++error_callback_count_
;
371 void ConnectErrorCallback(BluetoothDevice::ConnectErrorCode error
) {
372 ++error_callback_count_
;
376 void QuitMessageLoop() {
377 if (base::MessageLoop::current() &&
378 base::MessageLoop::current()->is_running())
379 base::MessageLoop::current()->Quit();
382 base::MessageLoop message_loop_
;
384 FakeBluetoothDeviceClient
* fake_bluetooth_device_client_
;
385 FakeBluetoothGattServiceClient
* fake_bluetooth_gatt_service_client_
;
386 FakeBluetoothGattCharacteristicClient
*
387 fake_bluetooth_gatt_characteristic_client_
;
388 FakeBluetoothGattDescriptorClient
* fake_bluetooth_gatt_descriptor_client_
;
389 scoped_ptr
<device::BluetoothGattConnection
> gatt_conn_
;
390 ScopedVector
<BluetoothGattNotifySession
> update_sessions_
;
391 scoped_refptr
<BluetoothAdapter
> adapter_
;
393 int success_callback_count_
;
394 int error_callback_count_
;
395 std::vector
<uint8
> last_read_value_
;
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-writeable 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::ErrorCallback
,
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(0, observer
.gatt_characteristic_value_changed_count_
);
851 characteristic
= service
->GetCharacteristic(
852 fake_bluetooth_gatt_characteristic_client_
->
853 GetBodySensorLocationPath().value());
854 ASSERT_TRUE(characteristic
);
855 EXPECT_EQ(fake_bluetooth_gatt_characteristic_client_
->
856 GetBodySensorLocationPath().value(),
857 characteristic
->GetIdentifier());
858 EXPECT_EQ(kBodySensorLocationUUID
, characteristic
->GetUUID());
859 characteristic
->WriteRemoteCharacteristic(
861 base::Bind(&BluetoothGattChromeOSTest::SuccessCallback
,
862 base::Unretained(this)),
863 base::Bind(&BluetoothGattChromeOSTest::ErrorCallback
,
864 base::Unretained(this)));
865 EXPECT_TRUE(observer
.last_gatt_characteristic_id_
.empty());
866 EXPECT_FALSE(observer
.last_gatt_characteristic_uuid_
.IsValid());
867 EXPECT_EQ(0, success_callback_count_
);
868 EXPECT_EQ(2, error_callback_count_
);
869 EXPECT_EQ(0, observer
.gatt_characteristic_value_changed_count_
);
871 // Issue write request to writeable characteristic. The "Body Sensor Location"
872 // characteristic does not send notifications and WriteValue does not result
873 // in a CharacteristicValueChanged event, thus no such event should be
875 characteristic
= service
->GetCharacteristic(
876 fake_bluetooth_gatt_characteristic_client_
->
877 GetHeartRateControlPointPath().value());
878 ASSERT_TRUE(characteristic
);
879 EXPECT_EQ(fake_bluetooth_gatt_characteristic_client_
->
880 GetHeartRateControlPointPath().value(),
881 characteristic
->GetIdentifier());
882 EXPECT_EQ(kHeartRateControlPointUUID
, characteristic
->GetUUID());
883 characteristic
->WriteRemoteCharacteristic(
885 base::Bind(&BluetoothGattChromeOSTest::SuccessCallback
,
886 base::Unretained(this)),
887 base::Bind(&BluetoothGattChromeOSTest::ErrorCallback
,
888 base::Unretained(this)));
889 EXPECT_TRUE(observer
.last_gatt_characteristic_id_
.empty());
890 EXPECT_FALSE(observer
.last_gatt_characteristic_uuid_
.IsValid());
891 EXPECT_EQ(1, success_callback_count_
);
892 EXPECT_EQ(2, error_callback_count_
);
893 EXPECT_EQ(0, observer
.gatt_characteristic_value_changed_count_
);
895 // Issue a read request. A successful read results in a
896 // CharacteristicValueChanged notification.
897 characteristic
= service
->GetCharacteristic(
898 fake_bluetooth_gatt_characteristic_client_
->
899 GetBodySensorLocationPath().value());
900 ASSERT_TRUE(characteristic
);
901 EXPECT_EQ(fake_bluetooth_gatt_characteristic_client_
->
902 GetBodySensorLocationPath().value(),
903 characteristic
->GetIdentifier());
904 EXPECT_EQ(kBodySensorLocationUUID
, characteristic
->GetUUID());
905 characteristic
->ReadRemoteCharacteristic(
906 base::Bind(&BluetoothGattChromeOSTest::ValueCallback
,
907 base::Unretained(this)),
908 base::Bind(&BluetoothGattChromeOSTest::ErrorCallback
,
909 base::Unretained(this)));
910 EXPECT_EQ(2, success_callback_count_
);
911 EXPECT_EQ(2, error_callback_count_
);
912 EXPECT_EQ(1, observer
.gatt_characteristic_value_changed_count_
);
913 EXPECT_TRUE(ValuesEqual(characteristic
->GetValue(), last_read_value_
));
916 TEST_F(BluetoothGattChromeOSTest
, GattCharacteristicProperties
) {
917 fake_bluetooth_device_client_
->CreateDevice(
918 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
919 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
920 BluetoothDevice
* device
= adapter_
->GetDevice(
921 FakeBluetoothDeviceClient::kLowEnergyAddress
);
924 TestObserver
observer(adapter_
);
926 // Expose the fake Heart Rate service. This will asynchronously expose
928 fake_bluetooth_gatt_service_client_
->ExposeHeartRateService(
929 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
931 BluetoothGattService
* service
=
932 device
->GetGattService(observer
.last_gatt_service_id_
);
934 EXPECT_TRUE(service
->GetCharacteristics().empty());
936 // Run the message loop so that the characteristics appear.
937 base::MessageLoop::current()->Run();
939 BluetoothGattCharacteristic
*characteristic
= service
->GetCharacteristic(
940 fake_bluetooth_gatt_characteristic_client_
->
941 GetBodySensorLocationPath().value());
942 EXPECT_EQ(BluetoothGattCharacteristic::kPropertyRead
,
943 characteristic
->GetProperties());
945 characteristic
= service
->GetCharacteristic(
946 fake_bluetooth_gatt_characteristic_client_
->
947 GetHeartRateControlPointPath().value());
948 EXPECT_EQ(BluetoothGattCharacteristic::kPropertyWrite
,
949 characteristic
->GetProperties());
951 characteristic
= service
->GetCharacteristic(
952 fake_bluetooth_gatt_characteristic_client_
->
953 GetHeartRateMeasurementPath().value());
954 EXPECT_EQ(BluetoothGattCharacteristic::kPropertyNotify
,
955 characteristic
->GetProperties());
958 TEST_F(BluetoothGattChromeOSTest
, GattDescriptorValue
) {
959 fake_bluetooth_device_client_
->CreateDevice(
960 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
961 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
962 BluetoothDevice
* device
= adapter_
->GetDevice(
963 FakeBluetoothDeviceClient::kLowEnergyAddress
);
966 TestObserver
observer(adapter_
);
968 // Expose the fake Heart Rate service. This will asynchronously expose
970 fake_bluetooth_gatt_service_client_
->ExposeHeartRateService(
971 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
972 ASSERT_EQ(1, observer
.gatt_service_added_count_
);
974 BluetoothGattService
* service
=
975 device
->GetGattService(observer
.last_gatt_service_id_
);
977 EXPECT_EQ(0, observer
.gatt_service_changed_count_
);
978 EXPECT_EQ(0, observer
.gatt_discovery_complete_count_
);
979 EXPECT_EQ(0, observer
.gatt_descriptor_value_changed_count_
);
980 EXPECT_TRUE(service
->GetCharacteristics().empty());
982 // Run the message loop so that the characteristics appear.
983 base::MessageLoop::current()->Run();
984 EXPECT_EQ(0, observer
.gatt_service_changed_count_
);
985 EXPECT_EQ(1, observer
.gatt_discovery_complete_count_
);
987 // Only the Heart Rate Measurement characteristic has a descriptor.
988 BluetoothGattCharacteristic
* characteristic
= service
->GetCharacteristic(
989 fake_bluetooth_gatt_characteristic_client_
->
990 GetHeartRateMeasurementPath().value());
991 ASSERT_TRUE(characteristic
);
992 EXPECT_EQ(1U, characteristic
->GetDescriptors().size());
994 BluetoothGattDescriptor
* descriptor
= characteristic
->GetDescriptors()[0];
995 EXPECT_FALSE(descriptor
->IsLocal());
996 EXPECT_EQ(BluetoothGattDescriptor::ClientCharacteristicConfigurationUuid(),
997 descriptor
->GetUUID());
999 std::vector
<uint8
> desc_value
;
1000 desc_value
.push_back(1);
1001 desc_value
.push_back(0);
1003 /* The cached value will be empty until the first read request */
1004 EXPECT_FALSE(ValuesEqual(desc_value
, descriptor
->GetValue()));
1005 EXPECT_TRUE(descriptor
->GetValue().empty());
1007 EXPECT_EQ(0, success_callback_count_
);
1008 EXPECT_EQ(0, error_callback_count_
);
1009 EXPECT_TRUE(last_read_value_
.empty());
1011 // Read value. GattDescriptorValueChanged event will be sent after a
1013 descriptor
->ReadRemoteDescriptor(
1014 base::Bind(&BluetoothGattChromeOSTest::ValueCallback
,
1015 base::Unretained(this)),
1016 base::Bind(&BluetoothGattChromeOSTest::ErrorCallback
,
1017 base::Unretained(this)));
1018 EXPECT_EQ(1, success_callback_count_
);
1019 EXPECT_EQ(0, error_callback_count_
);
1020 EXPECT_TRUE(ValuesEqual(last_read_value_
, descriptor
->GetValue()));
1021 EXPECT_TRUE(ValuesEqual(desc_value
, descriptor
->GetValue()));
1022 EXPECT_EQ(0, observer
.gatt_service_changed_count_
);
1023 EXPECT_EQ(1, observer
.gatt_descriptor_value_changed_count_
);
1025 // Write value. Writes to this descriptor will fail.
1026 desc_value
[0] = 0x03;
1027 descriptor
->WriteRemoteDescriptor(
1029 base::Bind(&BluetoothGattChromeOSTest::SuccessCallback
,
1030 base::Unretained(this)),
1031 base::Bind(&BluetoothGattChromeOSTest::ErrorCallback
,
1032 base::Unretained(this)));
1033 EXPECT_EQ(1, success_callback_count_
);
1034 EXPECT_EQ(1, error_callback_count_
);
1035 EXPECT_TRUE(ValuesEqual(last_read_value_
, descriptor
->GetValue()));
1036 EXPECT_FALSE(ValuesEqual(desc_value
, descriptor
->GetValue()));
1037 EXPECT_EQ(0, observer
.gatt_service_changed_count_
);
1038 EXPECT_EQ(1, observer
.gatt_descriptor_value_changed_count_
);
1041 descriptor
->ReadRemoteDescriptor(
1042 base::Bind(&BluetoothGattChromeOSTest::ValueCallback
,
1043 base::Unretained(this)),
1044 base::Bind(&BluetoothGattChromeOSTest::ErrorCallback
,
1045 base::Unretained(this)));
1046 EXPECT_EQ(2, success_callback_count_
);
1047 EXPECT_EQ(1, error_callback_count_
);
1048 EXPECT_TRUE(ValuesEqual(last_read_value_
, descriptor
->GetValue()));
1049 EXPECT_FALSE(ValuesEqual(desc_value
, descriptor
->GetValue()));
1050 EXPECT_EQ(0, observer
.gatt_service_changed_count_
);
1051 EXPECT_EQ(2, observer
.gatt_descriptor_value_changed_count_
);
1054 TEST_F(BluetoothGattChromeOSTest
, NotifySessions
) {
1055 fake_bluetooth_device_client_
->CreateDevice(
1056 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
1057 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
1058 BluetoothDevice
* device
=
1059 adapter_
->GetDevice(FakeBluetoothDeviceClient::kLowEnergyAddress
);
1060 ASSERT_TRUE(device
);
1062 TestObserver
observer(adapter_
);
1064 // Expose the fake Heart Rate service. This will asynchronously expose
1066 fake_bluetooth_gatt_service_client_
->ExposeHeartRateService(
1067 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
1068 ASSERT_EQ(1, observer
.gatt_service_added_count_
);
1070 BluetoothGattService
* service
=
1071 device
->GetGattService(observer
.last_gatt_service_id_
);
1073 EXPECT_EQ(0, observer
.gatt_characteristic_value_changed_count_
);
1075 // Run the message loop so that the characteristics appear.
1076 base::MessageLoop::current()->Run();
1078 BluetoothGattCharacteristic
* characteristic
= service
->GetCharacteristic(
1079 fake_bluetooth_gatt_characteristic_client_
->GetHeartRateMeasurementPath()
1081 ASSERT_TRUE(characteristic
);
1082 EXPECT_FALSE(characteristic
->IsNotifying());
1083 EXPECT_TRUE(update_sessions_
.empty());
1085 // Request to start notifications.
1086 characteristic
->StartNotifySession(
1087 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback
,
1088 base::Unretained(this)),
1089 base::Bind(&BluetoothGattChromeOSTest::ErrorCallback
,
1090 base::Unretained(this)));
1092 // The operation still hasn't completed but we should have received the first
1094 EXPECT_EQ(0, success_callback_count_
);
1095 EXPECT_EQ(0, error_callback_count_
);
1096 EXPECT_EQ(1, observer
.gatt_characteristic_value_changed_count_
);
1097 EXPECT_TRUE(update_sessions_
.empty());
1099 // Send a two more requests, which should get queued.
1100 characteristic
->StartNotifySession(
1101 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback
,
1102 base::Unretained(this)),
1103 base::Bind(&BluetoothGattChromeOSTest::ErrorCallback
,
1104 base::Unretained(this)));
1105 characteristic
->StartNotifySession(
1106 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback
,
1107 base::Unretained(this)),
1108 base::Bind(&BluetoothGattChromeOSTest::ErrorCallback
,
1109 base::Unretained(this)));
1110 EXPECT_EQ(0, success_callback_count_
);
1111 EXPECT_EQ(0, error_callback_count_
);
1112 EXPECT_EQ(1, observer
.gatt_characteristic_value_changed_count_
);
1113 EXPECT_TRUE(update_sessions_
.empty());
1114 EXPECT_TRUE(characteristic
->IsNotifying());
1116 // Run the main loop. The initial call should complete. The queued call should
1117 // succeed immediately.
1118 base::MessageLoop::current()->Run();
1120 EXPECT_EQ(3, success_callback_count_
);
1121 EXPECT_EQ(0, error_callback_count_
);
1122 EXPECT_EQ(1, observer
.gatt_characteristic_value_changed_count_
);
1123 EXPECT_EQ(3U, update_sessions_
.size());
1125 // Notifications should be getting sent regularly now.
1126 base::MessageLoop::current()->Run();
1127 EXPECT_GT(observer
.gatt_characteristic_value_changed_count_
, 1);
1129 // Stop one of the sessions. The session should become inactive but the
1130 // characteristic should still be notifying.
1131 BluetoothGattNotifySession
* session
= update_sessions_
[0];
1132 EXPECT_TRUE(session
->IsActive());
1133 session
->Stop(base::Bind(&BluetoothGattChromeOSTest::SuccessCallback
,
1134 base::Unretained(this)));
1135 EXPECT_EQ(4, success_callback_count_
);
1136 EXPECT_EQ(0, error_callback_count_
);
1137 EXPECT_FALSE(session
->IsActive());
1138 EXPECT_EQ(characteristic
->GetIdentifier(),
1139 session
->GetCharacteristicIdentifier());
1140 EXPECT_TRUE(characteristic
->IsNotifying());
1142 // Delete another session. Characteristic should still be notifying.
1143 update_sessions_
.pop_back();
1144 EXPECT_EQ(2U, update_sessions_
.size());
1145 EXPECT_TRUE(characteristic
->IsNotifying());
1146 EXPECT_FALSE(update_sessions_
[0]->IsActive());
1147 EXPECT_TRUE(update_sessions_
[1]->IsActive());
1149 // Clear the last session.
1150 update_sessions_
.clear();
1151 EXPECT_TRUE(update_sessions_
.empty());
1152 EXPECT_FALSE(characteristic
->IsNotifying());
1154 success_callback_count_
= 0;
1155 observer
.gatt_characteristic_value_changed_count_
= 0;
1157 // Enable notifications again.
1158 characteristic
->StartNotifySession(
1159 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback
,
1160 base::Unretained(this)),
1161 base::Bind(&BluetoothGattChromeOSTest::ErrorCallback
,
1162 base::Unretained(this)));
1163 EXPECT_EQ(0, success_callback_count_
);
1164 EXPECT_EQ(0, error_callback_count_
);
1165 EXPECT_EQ(1, observer
.gatt_characteristic_value_changed_count_
);
1166 EXPECT_TRUE(update_sessions_
.empty());
1167 EXPECT_TRUE(characteristic
->IsNotifying());
1169 // Run the message loop. Notifications should begin.
1170 base::MessageLoop::current()->Run();
1172 EXPECT_EQ(1, success_callback_count_
);
1173 EXPECT_EQ(0, error_callback_count_
);
1174 EXPECT_EQ(1, observer
.gatt_characteristic_value_changed_count_
);
1175 EXPECT_EQ(1U, update_sessions_
.size());
1176 EXPECT_TRUE(update_sessions_
[0]->IsActive());
1177 EXPECT_TRUE(characteristic
->IsNotifying());
1179 // Check that notifications are happening.
1180 base::MessageLoop::current()->Run();
1181 EXPECT_GT(observer
.gatt_characteristic_value_changed_count_
, 1);
1183 // Request another session. This should return immediately.
1184 characteristic
->StartNotifySession(
1185 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback
,
1186 base::Unretained(this)),
1187 base::Bind(&BluetoothGattChromeOSTest::ErrorCallback
,
1188 base::Unretained(this)));
1189 EXPECT_EQ(2, success_callback_count_
);
1190 EXPECT_EQ(0, error_callback_count_
);
1191 EXPECT_EQ(2U, update_sessions_
.size());
1192 EXPECT_TRUE(update_sessions_
[0]->IsActive());
1193 EXPECT_TRUE(update_sessions_
[1]->IsActive());
1194 EXPECT_TRUE(characteristic
->IsNotifying());
1196 // Hide the characteristic. The sessions should become inactive.
1197 fake_bluetooth_gatt_characteristic_client_
->HideHeartRateCharacteristics();
1198 EXPECT_EQ(2U, update_sessions_
.size());
1199 EXPECT_FALSE(update_sessions_
[0]->IsActive());
1200 EXPECT_FALSE(update_sessions_
[1]->IsActive());
1203 TEST_F(BluetoothGattChromeOSTest
, NotifySessionsMadeInactive
) {
1204 fake_bluetooth_device_client_
->CreateDevice(
1205 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
1206 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
1207 BluetoothDevice
* device
=
1208 adapter_
->GetDevice(FakeBluetoothDeviceClient::kLowEnergyAddress
);
1209 ASSERT_TRUE(device
);
1211 TestObserver
observer(adapter_
);
1213 // Expose the fake Heart Rate service. This will asynchronously expose
1215 fake_bluetooth_gatt_service_client_
->ExposeHeartRateService(
1216 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath
));
1217 ASSERT_EQ(1, observer
.gatt_service_added_count_
);
1219 BluetoothGattService
* service
=
1220 device
->GetGattService(observer
.last_gatt_service_id_
);
1222 EXPECT_EQ(0, observer
.gatt_characteristic_value_changed_count_
);
1224 // Run the message loop so that the characteristics appear.
1225 base::MessageLoop::current()->Run();
1227 BluetoothGattCharacteristic
* characteristic
= service
->GetCharacteristic(
1228 fake_bluetooth_gatt_characteristic_client_
->GetHeartRateMeasurementPath()
1230 ASSERT_TRUE(characteristic
);
1231 EXPECT_FALSE(characteristic
->IsNotifying());
1232 EXPECT_TRUE(update_sessions_
.empty());
1234 // Send several requests to start notifications.
1235 characteristic
->StartNotifySession(
1236 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback
,
1237 base::Unretained(this)),
1238 base::Bind(&BluetoothGattChromeOSTest::ErrorCallback
,
1239 base::Unretained(this)));
1240 characteristic
->StartNotifySession(
1241 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback
,
1242 base::Unretained(this)),
1243 base::Bind(&BluetoothGattChromeOSTest::ErrorCallback
,
1244 base::Unretained(this)));
1245 characteristic
->StartNotifySession(
1246 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback
,
1247 base::Unretained(this)),
1248 base::Bind(&BluetoothGattChromeOSTest::ErrorCallback
,
1249 base::Unretained(this)));
1250 characteristic
->StartNotifySession(
1251 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback
,
1252 base::Unretained(this)),
1253 base::Bind(&BluetoothGattChromeOSTest::ErrorCallback
,
1254 base::Unretained(this)));
1256 // The operation still hasn't completed but we should have received the first
1258 EXPECT_EQ(0, success_callback_count_
);
1259 EXPECT_EQ(0, error_callback_count_
);
1260 EXPECT_EQ(1, observer
.gatt_characteristic_value_changed_count_
);
1261 EXPECT_TRUE(characteristic
->IsNotifying());
1262 EXPECT_TRUE(update_sessions_
.empty());
1264 // Run the main loop. The initial call should complete. The queued calls
1265 // should succeed immediately.
1266 base::MessageLoop::current()->Run();
1268 EXPECT_EQ(4, success_callback_count_
);
1269 EXPECT_EQ(0, error_callback_count_
);
1270 EXPECT_EQ(1, observer
.gatt_characteristic_value_changed_count_
);
1271 EXPECT_TRUE(characteristic
->IsNotifying());
1272 EXPECT_EQ(4U, update_sessions_
.size());
1274 for (int i
= 0; i
< 4; i
++)
1275 EXPECT_TRUE(update_sessions_
[0]->IsActive());
1277 // Stop notifications directly through the client. The sessions should get
1278 // marked as inactive.
1279 fake_bluetooth_gatt_characteristic_client_
->StopNotify(
1280 fake_bluetooth_gatt_characteristic_client_
->GetHeartRateMeasurementPath(),
1281 base::Bind(&BluetoothGattChromeOSTest::SuccessCallback
,
1282 base::Unretained(this)),
1283 base::Bind(&BluetoothGattChromeOSTest::DBusErrorCallback
,
1284 base::Unretained(this)));
1285 EXPECT_EQ(5, success_callback_count_
);
1286 EXPECT_EQ(0, error_callback_count_
);
1287 EXPECT_FALSE(characteristic
->IsNotifying());
1288 EXPECT_EQ(4U, update_sessions_
.size());
1290 for (int i
= 0; i
< 4; i
++)
1291 EXPECT_FALSE(update_sessions_
[0]->IsActive());
1293 // It should be possible to restart notifications and the call should reset
1294 // the session count and make a request through the client.
1295 update_sessions_
.clear();
1296 success_callback_count_
= 0;
1297 observer
.gatt_characteristic_value_changed_count_
= 0;
1298 characteristic
->StartNotifySession(
1299 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback
,
1300 base::Unretained(this)),
1301 base::Bind(&BluetoothGattChromeOSTest::ErrorCallback
,
1302 base::Unretained(this)));
1304 EXPECT_EQ(0, success_callback_count_
);
1305 EXPECT_EQ(0, error_callback_count_
);
1306 EXPECT_EQ(1, observer
.gatt_characteristic_value_changed_count_
);
1307 EXPECT_TRUE(characteristic
->IsNotifying());
1308 EXPECT_TRUE(update_sessions_
.empty());
1310 base::MessageLoop::current()->Run();
1312 EXPECT_EQ(1, success_callback_count_
);
1313 EXPECT_EQ(0, error_callback_count_
);
1314 EXPECT_EQ(1, observer
.gatt_characteristic_value_changed_count_
);
1315 EXPECT_TRUE(characteristic
->IsNotifying());
1316 EXPECT_EQ(1U, update_sessions_
.size());
1317 EXPECT_TRUE(update_sessions_
[0]->IsActive());
1320 } // namespace chromeos