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