Make castv2 performance test work.
[chromium-blink-merge.git] / device / bluetooth / bluetooth_gatt_chromeos_unittest.cc
blobb4549c726acdd1c28a7bae2f0b8455f8355326e9
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;
37 namespace chromeos {
39 namespace {
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
49 // are equal.
50 bool ValuesEqual(const std::vector<uint8>& value0,
51 const std::vector<uint8>& value1) {
52 if (value0.size() != value1.size())
53 return false;
54 for (size_t i = 0; i < value0.size(); ++i)
55 if (value0[i] != value1[i])
56 return false;
57 return true;
60 class TestObserver : public BluetoothAdapter::Observer {
61 public:
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),
73 adapter_(adapter) {
74 adapter_->AddObserver(this);
77 ~TestObserver() override { adapter_->RemoveObserver(this); }
79 // BluetoothAdapter::Observer overrides.
80 void GattServiceAdded(BluetoothAdapter* adapter,
81 BluetoothDevice* device,
82 BluetoothGattService* service) override {
83 ASSERT_EQ(adapter_.get(), adapter);
84 ASSERT_EQ(service->GetDevice(), device);
86 ++gatt_service_added_count_;
87 last_gatt_service_id_ = service->GetIdentifier();
88 last_gatt_service_uuid_ = service->GetUUID();
90 EXPECT_FALSE(service->IsLocal());
91 EXPECT_TRUE(service->IsPrimary());
93 EXPECT_EQ(device->GetGattService(last_gatt_service_id_), service);
95 QuitMessageLoop();
98 void GattServiceRemoved(BluetoothAdapter* adapter,
99 BluetoothDevice* device,
100 BluetoothGattService* service) override {
101 ASSERT_EQ(adapter_.get(), adapter);
102 ASSERT_EQ(service->GetDevice(), device);
104 ++gatt_service_removed_count_;
105 last_gatt_service_id_ = service->GetIdentifier();
106 last_gatt_service_uuid_ = service->GetUUID();
108 EXPECT_FALSE(service->IsLocal());
109 EXPECT_TRUE(service->IsPrimary());
111 // The device should return NULL for this service.
112 EXPECT_FALSE(device->GetGattService(last_gatt_service_id_));
114 QuitMessageLoop();
117 void GattDiscoveryCompleteForService(BluetoothAdapter* adapter,
118 BluetoothGattService* service) override {
119 ASSERT_EQ(adapter_.get(), adapter);
120 ++gatt_discovery_complete_count_;
122 QuitMessageLoop();
125 void GattServiceChanged(BluetoothAdapter* adapter,
126 BluetoothGattService* service) override {
127 ASSERT_EQ(adapter_.get(), adapter);
128 ++gatt_service_changed_count_;
130 QuitMessageLoop();
133 void GattCharacteristicAdded(
134 BluetoothAdapter* adapter,
135 BluetoothGattCharacteristic* characteristic) override {
136 ASSERT_EQ(adapter_.get(), adapter);
138 ++gatt_characteristic_added_count_;
139 last_gatt_characteristic_id_ = characteristic->GetIdentifier();
140 last_gatt_characteristic_uuid_ = characteristic->GetUUID();
142 ASSERT_TRUE(characteristic->GetService());
143 EXPECT_EQ(characteristic->GetService()->GetCharacteristic(
144 last_gatt_characteristic_id_),
145 characteristic);
147 QuitMessageLoop();
150 void GattCharacteristicRemoved(
151 BluetoothAdapter* adapter,
152 BluetoothGattCharacteristic* characteristic) override {
153 ASSERT_EQ(adapter_.get(), adapter);
155 ++gatt_characteristic_removed_count_;
156 last_gatt_characteristic_id_ = characteristic->GetIdentifier();
157 last_gatt_characteristic_uuid_ = characteristic->GetUUID();
159 // The service should return NULL for this characteristic.
160 ASSERT_TRUE(characteristic->GetService());
161 EXPECT_FALSE(characteristic->GetService()->GetCharacteristic(
162 last_gatt_characteristic_id_));
164 QuitMessageLoop();
167 void GattCharacteristicValueChanged(
168 BluetoothAdapter* adapter,
169 BluetoothGattCharacteristic* characteristic,
170 const std::vector<uint8>& value) override {
171 ASSERT_EQ(adapter_.get(), adapter);
173 ++gatt_characteristic_value_changed_count_;
174 last_gatt_characteristic_id_ = characteristic->GetIdentifier();
175 last_gatt_characteristic_uuid_ = characteristic->GetUUID();
176 last_changed_characteristic_value_ = value;
178 ASSERT_TRUE(characteristic->GetService());
179 EXPECT_EQ(characteristic->GetService()->GetCharacteristic(
180 last_gatt_characteristic_id_),
181 characteristic);
183 QuitMessageLoop();
186 void GattDescriptorAdded(BluetoothAdapter* adapter,
187 BluetoothGattDescriptor* descriptor) override {
188 ASSERT_EQ(adapter_.get(), adapter);
190 ++gatt_descriptor_added_count_;
191 last_gatt_descriptor_id_ = descriptor->GetIdentifier();
192 last_gatt_descriptor_uuid_ = descriptor->GetUUID();
194 ASSERT_TRUE(descriptor->GetCharacteristic());
195 EXPECT_EQ(descriptor->GetCharacteristic()->GetDescriptor(
196 last_gatt_descriptor_id_),
197 descriptor);
199 QuitMessageLoop();
202 void GattDescriptorRemoved(BluetoothAdapter* adapter,
203 BluetoothGattDescriptor* descriptor) override {
204 ASSERT_EQ(adapter_.get(), adapter);
206 ++gatt_descriptor_removed_count_;
207 last_gatt_descriptor_id_ = descriptor->GetIdentifier();
208 last_gatt_descriptor_uuid_ = descriptor->GetUUID();
210 // The characteristic should return NULL for this descriptor..
211 ASSERT_TRUE(descriptor->GetCharacteristic());
212 EXPECT_FALSE(descriptor->GetCharacteristic()->GetDescriptor(
213 last_gatt_descriptor_id_));
215 QuitMessageLoop();
218 void GattDescriptorValueChanged(BluetoothAdapter* adapter,
219 BluetoothGattDescriptor* descriptor,
220 const std::vector<uint8>& value) override {
221 ASSERT_EQ(adapter_.get(), adapter);
223 ++gatt_descriptor_value_changed_count_;
224 last_gatt_descriptor_id_ = descriptor->GetIdentifier();
225 last_gatt_descriptor_uuid_ = descriptor->GetUUID();
226 last_changed_descriptor_value_ = value;
228 ASSERT_TRUE(descriptor->GetCharacteristic());
229 EXPECT_EQ(descriptor->GetCharacteristic()->GetDescriptor(
230 last_gatt_descriptor_id_),
231 descriptor);
233 QuitMessageLoop();
236 int gatt_service_added_count_;
237 int gatt_service_removed_count_;
238 int gatt_service_changed_count_;
239 int gatt_discovery_complete_count_;
240 int gatt_characteristic_added_count_;
241 int gatt_characteristic_removed_count_;
242 int gatt_characteristic_value_changed_count_;
243 int gatt_descriptor_added_count_;
244 int gatt_descriptor_removed_count_;
245 int gatt_descriptor_value_changed_count_;
246 std::string last_gatt_service_id_;
247 BluetoothUUID last_gatt_service_uuid_;
248 std::string last_gatt_characteristic_id_;
249 BluetoothUUID last_gatt_characteristic_uuid_;
250 std::vector<uint8> last_changed_characteristic_value_;
251 std::string last_gatt_descriptor_id_;
252 BluetoothUUID last_gatt_descriptor_uuid_;
253 std::vector<uint8> last_changed_descriptor_value_;
255 private:
256 // Some tests use a message loop since background processing is simulated;
257 // break out of those loops.
258 void QuitMessageLoop() {
259 if (base::MessageLoop::current() &&
260 base::MessageLoop::current()->is_running())
261 base::MessageLoop::current()->Quit();
264 scoped_refptr<BluetoothAdapter> adapter_;
267 } // namespace
269 class BluetoothGattChromeOSTest : public testing::Test {
270 public:
271 BluetoothGattChromeOSTest()
272 : fake_bluetooth_gatt_service_client_(NULL),
273 success_callback_count_(0),
274 error_callback_count_(0) {
277 void SetUp() override {
278 scoped_ptr<DBusThreadManagerSetter> dbus_setter =
279 chromeos::DBusThreadManager::GetSetterForTesting();
280 fake_bluetooth_device_client_ = new FakeBluetoothDeviceClient;
281 fake_bluetooth_gatt_service_client_ =
282 new FakeBluetoothGattServiceClient;
283 fake_bluetooth_gatt_characteristic_client_ =
284 new FakeBluetoothGattCharacteristicClient;
285 fake_bluetooth_gatt_descriptor_client_ =
286 new FakeBluetoothGattDescriptorClient;
287 dbus_setter->SetBluetoothDeviceClient(
288 scoped_ptr<BluetoothDeviceClient>(
289 fake_bluetooth_device_client_));
290 dbus_setter->SetBluetoothGattServiceClient(
291 scoped_ptr<BluetoothGattServiceClient>(
292 fake_bluetooth_gatt_service_client_));
293 dbus_setter->SetBluetoothGattCharacteristicClient(
294 scoped_ptr<BluetoothGattCharacteristicClient>(
295 fake_bluetooth_gatt_characteristic_client_));
296 dbus_setter->SetBluetoothGattDescriptorClient(
297 scoped_ptr<BluetoothGattDescriptorClient>(
298 fake_bluetooth_gatt_descriptor_client_));
299 dbus_setter->SetBluetoothAdapterClient(
300 scoped_ptr<BluetoothAdapterClient>(new FakeBluetoothAdapterClient));
301 dbus_setter->SetBluetoothInputClient(
302 scoped_ptr<BluetoothInputClient>(new FakeBluetoothInputClient));
303 dbus_setter->SetBluetoothAgentManagerClient(
304 scoped_ptr<BluetoothAgentManagerClient>(
305 new FakeBluetoothAgentManagerClient));
307 GetAdapter();
309 adapter_->SetPowered(
310 true,
311 base::Bind(&base::DoNothing),
312 base::Bind(&base::DoNothing));
313 ASSERT_TRUE(adapter_->IsPowered());
316 void TearDown() override {
317 adapter_ = NULL;
318 update_sessions_.clear();
319 gatt_conn_.reset();
320 DBusThreadManager::Shutdown();
323 void GetAdapter() {
324 device::BluetoothAdapterFactory::GetAdapter(
325 base::Bind(&BluetoothGattChromeOSTest::AdapterCallback,
326 base::Unretained(this)));
327 ASSERT_TRUE(adapter_.get() != NULL);
328 ASSERT_TRUE(adapter_->IsInitialized());
329 ASSERT_TRUE(adapter_->IsPresent());
332 void AdapterCallback(scoped_refptr<BluetoothAdapter> adapter) {
333 adapter_ = adapter;
336 void SuccessCallback() {
337 ++success_callback_count_;
340 void ValueCallback(const std::vector<uint8>& value) {
341 ++success_callback_count_;
342 last_read_value_ = value;
345 void GattConnectionCallback(scoped_ptr<BluetoothGattConnection> conn) {
346 ++success_callback_count_;
347 gatt_conn_ = conn.Pass();
350 void NotifySessionCallback(scoped_ptr<BluetoothGattNotifySession> session) {
351 ++success_callback_count_;
352 update_sessions_.push_back(session.release());
353 QuitMessageLoop();
356 void ServiceErrorCallback(BluetoothGattService::GattErrorCode err) {
357 ++error_callback_count_;
358 last_service_error_ = err;
361 void ErrorCallback() {
362 ++error_callback_count_;
365 void DBusErrorCallback(const std::string& error_name,
366 const std::string& error_message) {
367 ++error_callback_count_;
370 void ConnectErrorCallback(BluetoothDevice::ConnectErrorCode error) {
371 ++error_callback_count_;
374 protected:
375 void QuitMessageLoop() {
376 if (base::MessageLoop::current() &&
377 base::MessageLoop::current()->is_running())
378 base::MessageLoop::current()->Quit();
381 base::MessageLoop message_loop_;
383 FakeBluetoothDeviceClient* fake_bluetooth_device_client_;
384 FakeBluetoothGattServiceClient* fake_bluetooth_gatt_service_client_;
385 FakeBluetoothGattCharacteristicClient*
386 fake_bluetooth_gatt_characteristic_client_;
387 FakeBluetoothGattDescriptorClient* fake_bluetooth_gatt_descriptor_client_;
388 scoped_ptr<device::BluetoothGattConnection> gatt_conn_;
389 ScopedVector<BluetoothGattNotifySession> update_sessions_;
390 scoped_refptr<BluetoothAdapter> adapter_;
392 int success_callback_count_;
393 int error_callback_count_;
394 std::vector<uint8> last_read_value_;
395 BluetoothGattService::GattErrorCode last_service_error_;
398 TEST_F(BluetoothGattChromeOSTest, GattConnection) {
399 fake_bluetooth_device_client_->CreateDevice(
400 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
401 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath));
402 BluetoothDevice* device = adapter_->GetDevice(
403 FakeBluetoothDeviceClient::kLowEnergyAddress);
404 ASSERT_TRUE(device);
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());
444 device->Disconnect(
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);
481 ASSERT_TRUE(device);
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());
498 EXPECT_EQ(
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());
511 // Hide the service.
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());
520 EXPECT_EQ(
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());
535 EXPECT_EQ(
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());
559 EXPECT_EQ(
560 BluetoothUUID(FakeBluetoothGattServiceClient::kHeartRateServiceUUID),
561 observer.last_gatt_service_uuid_);
562 EXPECT_EQ(
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);
572 ASSERT_TRUE(device);
574 TestObserver observer(adapter_);
576 // Expose the fake Heart Rate service. This will asynchronously expose
577 // characteristics.
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
597 // descriptor added.
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);
640 ASSERT_TRUE(device);
642 TestObserver observer(adapter_);
644 // Expose the fake Heart Rate service. This will asynchronously expose
645 // characteristics.
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.
727 adapter_ = NULL;
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.
742 GetAdapter();
743 BluetoothDevice* device = adapter_->GetDevice(
744 FakeBluetoothDeviceClient::kLowEnergyAddress);
745 ASSERT_TRUE(device);
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());
752 EXPECT_EQ(
753 BluetoothUUID(FakeBluetoothGattServiceClient::kHeartRateServiceUUID),
754 service->GetUUID());
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);
764 EXPECT_EQ(
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);
775 EXPECT_EQ(
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);
786 EXPECT_EQ(
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);
806 ASSERT_TRUE(device);
808 TestObserver observer(adapter_);
810 // Expose the fake Heart Rate service. This will asynchronously expose
811 // characteristics.
812 fake_bluetooth_gatt_service_client_->ExposeHeartRateService(
813 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath));
814 ASSERT_EQ(1, observer.gatt_service_added_count_);
816 BluetoothGattService* service =
817 device->GetGattService(observer.last_gatt_service_id_);
819 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count_);
821 // Run the message loop so that the characteristics appear.
822 base::MessageLoop::current()->Run();
824 // Issue write request to non-writable characteristics.
825 observer.last_gatt_characteristic_id_.clear();
826 observer.last_gatt_characteristic_uuid_ = BluetoothUUID();
828 std::vector<uint8> write_value;
829 write_value.push_back(0x01);
830 BluetoothGattCharacteristic* characteristic =
831 service->GetCharacteristic(fake_bluetooth_gatt_characteristic_client_->
832 GetHeartRateMeasurementPath().value());
833 ASSERT_TRUE(characteristic);
834 EXPECT_FALSE(characteristic->IsNotifying());
835 EXPECT_EQ(fake_bluetooth_gatt_characteristic_client_->
836 GetHeartRateMeasurementPath().value(),
837 characteristic->GetIdentifier());
838 EXPECT_EQ(kHeartRateMeasurementUUID, characteristic->GetUUID());
839 characteristic->WriteRemoteCharacteristic(
840 write_value,
841 base::Bind(&BluetoothGattChromeOSTest::SuccessCallback,
842 base::Unretained(this)),
843 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
844 base::Unretained(this)));
845 EXPECT_TRUE(observer.last_gatt_characteristic_id_.empty());
846 EXPECT_FALSE(observer.last_gatt_characteristic_uuid_.IsValid());
847 EXPECT_EQ(0, success_callback_count_);
848 EXPECT_EQ(1, error_callback_count_);
849 EXPECT_EQ(BluetoothGattService::GATT_ERROR_NOT_SUPPORTED,
850 last_service_error_);
851 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count_);
853 characteristic = service->GetCharacteristic(
854 fake_bluetooth_gatt_characteristic_client_->
855 GetBodySensorLocationPath().value());
856 ASSERT_TRUE(characteristic);
857 EXPECT_EQ(fake_bluetooth_gatt_characteristic_client_->
858 GetBodySensorLocationPath().value(),
859 characteristic->GetIdentifier());
860 EXPECT_EQ(kBodySensorLocationUUID, characteristic->GetUUID());
861 characteristic->WriteRemoteCharacteristic(
862 write_value,
863 base::Bind(&BluetoothGattChromeOSTest::SuccessCallback,
864 base::Unretained(this)),
865 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
866 base::Unretained(this)));
867 EXPECT_TRUE(observer.last_gatt_characteristic_id_.empty());
868 EXPECT_FALSE(observer.last_gatt_characteristic_uuid_.IsValid());
869 EXPECT_EQ(0, success_callback_count_);
870 EXPECT_EQ(2, error_callback_count_);
871 EXPECT_EQ(BluetoothGattService::GATT_ERROR_NOT_PERMITTED,
872 last_service_error_);
873 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count_);
875 // Issue write request to writable characteristic. The "Body Sensor Location"
876 // characteristic does not send notifications and WriteValue does not result
877 // in a CharacteristicValueChanged event, thus no such event should be
878 // received.
879 characteristic = service->GetCharacteristic(
880 fake_bluetooth_gatt_characteristic_client_->
881 GetHeartRateControlPointPath().value());
882 ASSERT_TRUE(characteristic);
883 EXPECT_EQ(fake_bluetooth_gatt_characteristic_client_->
884 GetHeartRateControlPointPath().value(),
885 characteristic->GetIdentifier());
886 EXPECT_EQ(kHeartRateControlPointUUID, characteristic->GetUUID());
887 characteristic->WriteRemoteCharacteristic(
888 write_value,
889 base::Bind(&BluetoothGattChromeOSTest::SuccessCallback,
890 base::Unretained(this)),
891 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
892 base::Unretained(this)));
893 EXPECT_TRUE(observer.last_gatt_characteristic_id_.empty());
894 EXPECT_FALSE(observer.last_gatt_characteristic_uuid_.IsValid());
895 EXPECT_EQ(1, success_callback_count_);
896 EXPECT_EQ(2, error_callback_count_);
897 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count_);
899 // Issue some invalid write requests to the characteristic.
900 // The value should still not change.
902 std::vector<uint8> invalid_write_length;
903 invalid_write_length.push_back(0x01);
904 invalid_write_length.push_back(0x00);
905 characteristic->WriteRemoteCharacteristic(
906 invalid_write_length,
907 base::Bind(&BluetoothGattChromeOSTest::SuccessCallback,
908 base::Unretained(this)),
909 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
910 base::Unretained(this)));
911 EXPECT_EQ(1, success_callback_count_);
912 EXPECT_EQ(3, error_callback_count_);
913 EXPECT_EQ(BluetoothGattService::GATT_ERROR_INVALID_LENGTH,
914 last_service_error_);
915 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count_);
917 std::vector<uint8> invalid_write_value;
918 invalid_write_value.push_back(0x02);
919 characteristic->WriteRemoteCharacteristic(
920 invalid_write_value,
921 base::Bind(&BluetoothGattChromeOSTest::SuccessCallback,
922 base::Unretained(this)),
923 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
924 base::Unretained(this)));
925 EXPECT_EQ(1, success_callback_count_);
926 EXPECT_EQ(4, error_callback_count_);
927 EXPECT_EQ(BluetoothGattService::GATT_ERROR_FAILED, last_service_error_);
928 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count_);
930 // Issue a read request. A successful read results in a
931 // CharacteristicValueChanged notification.
932 characteristic = service->GetCharacteristic(
933 fake_bluetooth_gatt_characteristic_client_->
934 GetBodySensorLocationPath().value());
935 ASSERT_TRUE(characteristic);
936 EXPECT_EQ(fake_bluetooth_gatt_characteristic_client_->
937 GetBodySensorLocationPath().value(),
938 characteristic->GetIdentifier());
939 EXPECT_EQ(kBodySensorLocationUUID, characteristic->GetUUID());
940 characteristic->ReadRemoteCharacteristic(
941 base::Bind(&BluetoothGattChromeOSTest::ValueCallback,
942 base::Unretained(this)),
943 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
944 base::Unretained(this)));
945 EXPECT_EQ(2, success_callback_count_);
946 EXPECT_EQ(4, error_callback_count_);
947 EXPECT_EQ(1, observer.gatt_characteristic_value_changed_count_);
948 EXPECT_TRUE(ValuesEqual(characteristic->GetValue(), last_read_value_));
950 // Test long-running actions.
951 fake_bluetooth_gatt_characteristic_client_->SetExtraProcessing(1);
952 characteristic = service->GetCharacteristic(
953 fake_bluetooth_gatt_characteristic_client_->GetBodySensorLocationPath()
954 .value());
955 ASSERT_TRUE(characteristic);
956 EXPECT_EQ(
957 fake_bluetooth_gatt_characteristic_client_->GetBodySensorLocationPath()
958 .value(),
959 characteristic->GetIdentifier());
960 EXPECT_EQ(kBodySensorLocationUUID, characteristic->GetUUID());
961 characteristic->ReadRemoteCharacteristic(
962 base::Bind(&BluetoothGattChromeOSTest::ValueCallback,
963 base::Unretained(this)),
964 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
965 base::Unretained(this)));
967 // Callback counts shouldn't change, this one will be delayed until after
968 // tne next one.
969 EXPECT_EQ(2, success_callback_count_);
970 EXPECT_EQ(4, error_callback_count_);
971 EXPECT_EQ(1, observer.gatt_characteristic_value_changed_count_);
973 // Next read should error because IN_PROGRESS
974 characteristic->ReadRemoteCharacteristic(
975 base::Bind(&BluetoothGattChromeOSTest::ValueCallback,
976 base::Unretained(this)),
977 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
978 base::Unretained(this)));
979 EXPECT_EQ(5, error_callback_count_);
980 EXPECT_EQ(BluetoothGattService::GATT_ERROR_IN_PROGRESS, last_service_error_);
982 // But previous call finished.
983 EXPECT_EQ(3, success_callback_count_);
984 EXPECT_EQ(2, observer.gatt_characteristic_value_changed_count_);
985 EXPECT_TRUE(ValuesEqual(characteristic->GetValue(), last_read_value_));
986 fake_bluetooth_gatt_characteristic_client_->SetExtraProcessing(0);
988 // Test unauthorized actions.
989 fake_bluetooth_gatt_characteristic_client_->SetAuthorized(false);
990 characteristic->ReadRemoteCharacteristic(
991 base::Bind(&BluetoothGattChromeOSTest::ValueCallback,
992 base::Unretained(this)),
993 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
994 base::Unretained(this)));
995 EXPECT_EQ(3, success_callback_count_);
996 EXPECT_EQ(6, error_callback_count_);
997 EXPECT_EQ(BluetoothGattService::GATT_ERROR_NOT_AUTHORIZED,
998 last_service_error_);
999 EXPECT_EQ(2, observer.gatt_characteristic_value_changed_count_);
1000 fake_bluetooth_gatt_characteristic_client_->SetAuthorized(true);
1002 // Test unauthenticated / needs login.
1003 fake_bluetooth_gatt_characteristic_client_->SetAuthenticated(false);
1004 characteristic->ReadRemoteCharacteristic(
1005 base::Bind(&BluetoothGattChromeOSTest::ValueCallback,
1006 base::Unretained(this)),
1007 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
1008 base::Unretained(this)));
1009 EXPECT_EQ(3, success_callback_count_);
1010 EXPECT_EQ(7, error_callback_count_);
1011 EXPECT_EQ(BluetoothGattService::GATT_ERROR_NOT_PAIRED, last_service_error_);
1012 EXPECT_EQ(2, observer.gatt_characteristic_value_changed_count_);
1013 fake_bluetooth_gatt_characteristic_client_->SetAuthenticated(true);
1016 TEST_F(BluetoothGattChromeOSTest, GattCharacteristicProperties) {
1017 fake_bluetooth_device_client_->CreateDevice(
1018 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
1019 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath));
1020 BluetoothDevice* device = adapter_->GetDevice(
1021 FakeBluetoothDeviceClient::kLowEnergyAddress);
1022 ASSERT_TRUE(device);
1024 TestObserver observer(adapter_);
1026 // Expose the fake Heart Rate service. This will asynchronously expose
1027 // characteristics.
1028 fake_bluetooth_gatt_service_client_->ExposeHeartRateService(
1029 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath));
1031 BluetoothGattService* service =
1032 device->GetGattService(observer.last_gatt_service_id_);
1034 EXPECT_TRUE(service->GetCharacteristics().empty());
1036 // Run the message loop so that the characteristics appear.
1037 base::MessageLoop::current()->Run();
1039 BluetoothGattCharacteristic *characteristic = service->GetCharacteristic(
1040 fake_bluetooth_gatt_characteristic_client_->
1041 GetBodySensorLocationPath().value());
1042 EXPECT_EQ(BluetoothGattCharacteristic::PROPERTY_READ,
1043 characteristic->GetProperties());
1045 characteristic = service->GetCharacteristic(
1046 fake_bluetooth_gatt_characteristic_client_->
1047 GetHeartRateControlPointPath().value());
1048 EXPECT_EQ(BluetoothGattCharacteristic::PROPERTY_WRITE,
1049 characteristic->GetProperties());
1051 characteristic = service->GetCharacteristic(
1052 fake_bluetooth_gatt_characteristic_client_->
1053 GetHeartRateMeasurementPath().value());
1054 EXPECT_EQ(BluetoothGattCharacteristic::PROPERTY_NOTIFY,
1055 characteristic->GetProperties());
1058 TEST_F(BluetoothGattChromeOSTest, GattDescriptorValue) {
1059 fake_bluetooth_device_client_->CreateDevice(
1060 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
1061 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath));
1062 BluetoothDevice* device = adapter_->GetDevice(
1063 FakeBluetoothDeviceClient::kLowEnergyAddress);
1064 ASSERT_TRUE(device);
1066 TestObserver observer(adapter_);
1068 // Expose the fake Heart Rate service. This will asynchronously expose
1069 // characteristics.
1070 fake_bluetooth_gatt_service_client_->ExposeHeartRateService(
1071 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath));
1072 ASSERT_EQ(1, observer.gatt_service_added_count_);
1074 BluetoothGattService* service =
1075 device->GetGattService(observer.last_gatt_service_id_);
1077 EXPECT_EQ(0, observer.gatt_service_changed_count_);
1078 EXPECT_EQ(0, observer.gatt_discovery_complete_count_);
1079 EXPECT_EQ(0, observer.gatt_descriptor_value_changed_count_);
1080 EXPECT_TRUE(service->GetCharacteristics().empty());
1082 // Run the message loop so that the characteristics appear.
1083 base::MessageLoop::current()->Run();
1084 EXPECT_EQ(0, observer.gatt_service_changed_count_);
1085 EXPECT_EQ(1, observer.gatt_discovery_complete_count_);
1087 // Only the Heart Rate Measurement characteristic has a descriptor.
1088 BluetoothGattCharacteristic* characteristic = service->GetCharacteristic(
1089 fake_bluetooth_gatt_characteristic_client_->
1090 GetHeartRateMeasurementPath().value());
1091 ASSERT_TRUE(characteristic);
1092 EXPECT_EQ(1U, characteristic->GetDescriptors().size());
1093 EXPECT_FALSE(characteristic->IsNotifying());
1095 BluetoothGattDescriptor* descriptor = characteristic->GetDescriptors()[0];
1096 EXPECT_FALSE(descriptor->IsLocal());
1097 EXPECT_EQ(BluetoothGattDescriptor::ClientCharacteristicConfigurationUuid(),
1098 descriptor->GetUUID());
1100 std::vector<uint8_t> desc_value = {0x00, 0x00};
1102 /* The cached value will be empty until the first read request */
1103 EXPECT_FALSE(ValuesEqual(desc_value, descriptor->GetValue()));
1104 EXPECT_TRUE(descriptor->GetValue().empty());
1106 EXPECT_EQ(0, success_callback_count_);
1107 EXPECT_EQ(0, error_callback_count_);
1108 EXPECT_TRUE(last_read_value_.empty());
1110 // Read value. GattDescriptorValueChanged event will be sent after a
1111 // successful read.
1112 descriptor->ReadRemoteDescriptor(
1113 base::Bind(&BluetoothGattChromeOSTest::ValueCallback,
1114 base::Unretained(this)),
1115 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
1116 base::Unretained(this)));
1117 EXPECT_EQ(1, success_callback_count_);
1118 EXPECT_EQ(0, error_callback_count_);
1119 EXPECT_TRUE(ValuesEqual(last_read_value_, descriptor->GetValue()));
1120 EXPECT_TRUE(ValuesEqual(desc_value, descriptor->GetValue()));
1121 EXPECT_EQ(0, observer.gatt_service_changed_count_);
1122 EXPECT_EQ(1, observer.gatt_descriptor_value_changed_count_);
1124 // Write value. Writes to this descriptor will fail.
1125 desc_value[0] = 0x03;
1126 descriptor->WriteRemoteDescriptor(
1127 desc_value,
1128 base::Bind(&BluetoothGattChromeOSTest::SuccessCallback,
1129 base::Unretained(this)),
1130 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
1131 base::Unretained(this)));
1132 EXPECT_EQ(1, success_callback_count_);
1133 EXPECT_EQ(1, error_callback_count_);
1134 EXPECT_EQ(BluetoothGattService::GATT_ERROR_NOT_PERMITTED,
1135 last_service_error_);
1136 EXPECT_TRUE(ValuesEqual(last_read_value_, descriptor->GetValue()));
1137 EXPECT_FALSE(ValuesEqual(desc_value, descriptor->GetValue()));
1138 EXPECT_EQ(0, observer.gatt_service_changed_count_);
1139 EXPECT_EQ(1, observer.gatt_descriptor_value_changed_count_);
1141 // Read value. The value should remain unchanged.
1142 descriptor->ReadRemoteDescriptor(
1143 base::Bind(&BluetoothGattChromeOSTest::ValueCallback,
1144 base::Unretained(this)),
1145 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
1146 base::Unretained(this)));
1147 EXPECT_EQ(2, success_callback_count_);
1148 EXPECT_EQ(1, error_callback_count_);
1149 EXPECT_TRUE(ValuesEqual(last_read_value_, descriptor->GetValue()));
1150 EXPECT_FALSE(ValuesEqual(desc_value, descriptor->GetValue()));
1151 EXPECT_EQ(0, observer.gatt_service_changed_count_);
1152 EXPECT_EQ(1, observer.gatt_descriptor_value_changed_count_);
1154 // Start notifications on the descriptor's characteristic. The descriptor
1155 // value should change.
1156 characteristic->StartNotifySession(
1157 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback,
1158 base::Unretained(this)),
1159 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
1160 base::Unretained(this)));
1161 base::MessageLoop::current()->Run();
1162 EXPECT_EQ(3, success_callback_count_);
1163 EXPECT_EQ(1, error_callback_count_);
1164 EXPECT_EQ(1U, update_sessions_.size());
1165 EXPECT_TRUE(characteristic->IsNotifying());
1167 // Read the new descriptor value. We should receive a value updated event.
1168 descriptor->ReadRemoteDescriptor(
1169 base::Bind(&BluetoothGattChromeOSTest::ValueCallback,
1170 base::Unretained(this)),
1171 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
1172 base::Unretained(this)));
1173 EXPECT_EQ(4, success_callback_count_);
1174 EXPECT_EQ(1, error_callback_count_);
1175 EXPECT_TRUE(ValuesEqual(last_read_value_, descriptor->GetValue()));
1176 EXPECT_FALSE(ValuesEqual(desc_value, descriptor->GetValue()));
1177 EXPECT_EQ(0, observer.gatt_service_changed_count_);
1178 EXPECT_EQ(2, observer.gatt_descriptor_value_changed_count_);
1181 TEST_F(BluetoothGattChromeOSTest, NotifySessions) {
1182 fake_bluetooth_device_client_->CreateDevice(
1183 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
1184 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath));
1185 BluetoothDevice* device =
1186 adapter_->GetDevice(FakeBluetoothDeviceClient::kLowEnergyAddress);
1187 ASSERT_TRUE(device);
1189 TestObserver observer(adapter_);
1191 // Expose the fake Heart Rate service. This will asynchronously expose
1192 // characteristics.
1193 fake_bluetooth_gatt_service_client_->ExposeHeartRateService(
1194 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath));
1195 ASSERT_EQ(1, observer.gatt_service_added_count_);
1197 BluetoothGattService* service =
1198 device->GetGattService(observer.last_gatt_service_id_);
1200 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count_);
1202 // Run the message loop so that the characteristics appear.
1203 base::MessageLoop::current()->Run();
1205 BluetoothGattCharacteristic* characteristic = service->GetCharacteristic(
1206 fake_bluetooth_gatt_characteristic_client_->GetHeartRateMeasurementPath()
1207 .value());
1208 ASSERT_TRUE(characteristic);
1209 EXPECT_FALSE(characteristic->IsNotifying());
1210 EXPECT_TRUE(update_sessions_.empty());
1212 // Request to start notifications.
1213 characteristic->StartNotifySession(
1214 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback,
1215 base::Unretained(this)),
1216 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
1217 base::Unretained(this)));
1219 // The operation still hasn't completed but we should have received the first
1220 // notification.
1221 EXPECT_EQ(0, success_callback_count_);
1222 EXPECT_EQ(0, error_callback_count_);
1223 EXPECT_EQ(1, observer.gatt_characteristic_value_changed_count_);
1224 EXPECT_TRUE(update_sessions_.empty());
1226 // Send a two more requests, which should get queued.
1227 characteristic->StartNotifySession(
1228 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback,
1229 base::Unretained(this)),
1230 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
1231 base::Unretained(this)));
1232 characteristic->StartNotifySession(
1233 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback,
1234 base::Unretained(this)),
1235 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
1236 base::Unretained(this)));
1237 EXPECT_EQ(0, success_callback_count_);
1238 EXPECT_EQ(0, error_callback_count_);
1239 EXPECT_EQ(1, observer.gatt_characteristic_value_changed_count_);
1240 EXPECT_TRUE(update_sessions_.empty());
1241 EXPECT_TRUE(characteristic->IsNotifying());
1243 // Run the main loop. The initial call should complete. The queued call should
1244 // succeed immediately.
1245 base::MessageLoop::current()->Run();
1247 EXPECT_EQ(3, success_callback_count_);
1248 EXPECT_EQ(0, error_callback_count_);
1249 EXPECT_EQ(1, observer.gatt_characteristic_value_changed_count_);
1250 EXPECT_EQ(3U, update_sessions_.size());
1252 // Notifications should be getting sent regularly now.
1253 base::MessageLoop::current()->Run();
1254 EXPECT_GT(observer.gatt_characteristic_value_changed_count_, 1);
1256 // Stop one of the sessions. The session should become inactive but the
1257 // characteristic should still be notifying.
1258 BluetoothGattNotifySession* session = update_sessions_[0];
1259 EXPECT_TRUE(session->IsActive());
1260 session->Stop(base::Bind(&BluetoothGattChromeOSTest::SuccessCallback,
1261 base::Unretained(this)));
1262 EXPECT_EQ(4, success_callback_count_);
1263 EXPECT_EQ(0, error_callback_count_);
1264 EXPECT_FALSE(session->IsActive());
1265 EXPECT_EQ(characteristic->GetIdentifier(),
1266 session->GetCharacteristicIdentifier());
1267 EXPECT_TRUE(characteristic->IsNotifying());
1269 // Delete another session. Characteristic should still be notifying.
1270 update_sessions_.pop_back();
1271 EXPECT_EQ(2U, update_sessions_.size());
1272 EXPECT_TRUE(characteristic->IsNotifying());
1273 EXPECT_FALSE(update_sessions_[0]->IsActive());
1274 EXPECT_TRUE(update_sessions_[1]->IsActive());
1276 // Clear the last session.
1277 update_sessions_.clear();
1278 EXPECT_TRUE(update_sessions_.empty());
1279 EXPECT_FALSE(characteristic->IsNotifying());
1281 success_callback_count_ = 0;
1282 observer.gatt_characteristic_value_changed_count_ = 0;
1284 // Enable notifications again.
1285 characteristic->StartNotifySession(
1286 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback,
1287 base::Unretained(this)),
1288 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
1289 base::Unretained(this)));
1290 EXPECT_EQ(0, success_callback_count_);
1291 EXPECT_EQ(0, error_callback_count_);
1292 EXPECT_EQ(1, observer.gatt_characteristic_value_changed_count_);
1293 EXPECT_TRUE(update_sessions_.empty());
1294 EXPECT_TRUE(characteristic->IsNotifying());
1296 // Run the message loop. Notifications should begin.
1297 base::MessageLoop::current()->Run();
1299 EXPECT_EQ(1, success_callback_count_);
1300 EXPECT_EQ(0, error_callback_count_);
1301 EXPECT_EQ(1, observer.gatt_characteristic_value_changed_count_);
1302 EXPECT_EQ(1U, update_sessions_.size());
1303 EXPECT_TRUE(update_sessions_[0]->IsActive());
1304 EXPECT_TRUE(characteristic->IsNotifying());
1306 // Check that notifications are happening.
1307 base::MessageLoop::current()->Run();
1308 EXPECT_GT(observer.gatt_characteristic_value_changed_count_, 1);
1310 // Request another session. This should return immediately.
1311 characteristic->StartNotifySession(
1312 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback,
1313 base::Unretained(this)),
1314 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
1315 base::Unretained(this)));
1316 EXPECT_EQ(2, success_callback_count_);
1317 EXPECT_EQ(0, error_callback_count_);
1318 EXPECT_EQ(2U, update_sessions_.size());
1319 EXPECT_TRUE(update_sessions_[0]->IsActive());
1320 EXPECT_TRUE(update_sessions_[1]->IsActive());
1321 EXPECT_TRUE(characteristic->IsNotifying());
1323 // Hide the characteristic. The sessions should become inactive.
1324 fake_bluetooth_gatt_characteristic_client_->HideHeartRateCharacteristics();
1325 EXPECT_EQ(2U, update_sessions_.size());
1326 EXPECT_FALSE(update_sessions_[0]->IsActive());
1327 EXPECT_FALSE(update_sessions_[1]->IsActive());
1330 TEST_F(BluetoothGattChromeOSTest, NotifySessionsMadeInactive) {
1331 fake_bluetooth_device_client_->CreateDevice(
1332 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
1333 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath));
1334 BluetoothDevice* device =
1335 adapter_->GetDevice(FakeBluetoothDeviceClient::kLowEnergyAddress);
1336 ASSERT_TRUE(device);
1338 TestObserver observer(adapter_);
1340 // Expose the fake Heart Rate service. This will asynchronously expose
1341 // characteristics.
1342 fake_bluetooth_gatt_service_client_->ExposeHeartRateService(
1343 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath));
1344 ASSERT_EQ(1, observer.gatt_service_added_count_);
1346 BluetoothGattService* service =
1347 device->GetGattService(observer.last_gatt_service_id_);
1349 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count_);
1351 // Run the message loop so that the characteristics appear.
1352 base::MessageLoop::current()->Run();
1354 BluetoothGattCharacteristic* characteristic = service->GetCharacteristic(
1355 fake_bluetooth_gatt_characteristic_client_->GetHeartRateMeasurementPath()
1356 .value());
1357 ASSERT_TRUE(characteristic);
1358 EXPECT_FALSE(characteristic->IsNotifying());
1359 EXPECT_TRUE(update_sessions_.empty());
1361 // Send several requests to start notifications.
1362 characteristic->StartNotifySession(
1363 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback,
1364 base::Unretained(this)),
1365 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
1366 base::Unretained(this)));
1367 characteristic->StartNotifySession(
1368 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback,
1369 base::Unretained(this)),
1370 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
1371 base::Unretained(this)));
1372 characteristic->StartNotifySession(
1373 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback,
1374 base::Unretained(this)),
1375 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
1376 base::Unretained(this)));
1377 characteristic->StartNotifySession(
1378 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback,
1379 base::Unretained(this)),
1380 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
1381 base::Unretained(this)));
1383 // The operation still hasn't completed but we should have received the first
1384 // notification.
1385 EXPECT_EQ(0, success_callback_count_);
1386 EXPECT_EQ(0, error_callback_count_);
1387 EXPECT_EQ(1, observer.gatt_characteristic_value_changed_count_);
1388 EXPECT_TRUE(characteristic->IsNotifying());
1389 EXPECT_TRUE(update_sessions_.empty());
1391 // Run the main loop. The initial call should complete. The queued calls
1392 // should succeed immediately.
1393 base::MessageLoop::current()->Run();
1395 EXPECT_EQ(4, success_callback_count_);
1396 EXPECT_EQ(0, error_callback_count_);
1397 EXPECT_EQ(1, observer.gatt_characteristic_value_changed_count_);
1398 EXPECT_TRUE(characteristic->IsNotifying());
1399 EXPECT_EQ(4U, update_sessions_.size());
1401 for (int i = 0; i < 4; i++)
1402 EXPECT_TRUE(update_sessions_[0]->IsActive());
1404 // Stop notifications directly through the client. The sessions should get
1405 // marked as inactive.
1406 fake_bluetooth_gatt_characteristic_client_->StopNotify(
1407 fake_bluetooth_gatt_characteristic_client_->GetHeartRateMeasurementPath(),
1408 base::Bind(&BluetoothGattChromeOSTest::SuccessCallback,
1409 base::Unretained(this)),
1410 base::Bind(&BluetoothGattChromeOSTest::DBusErrorCallback,
1411 base::Unretained(this)));
1412 EXPECT_EQ(5, success_callback_count_);
1413 EXPECT_EQ(0, error_callback_count_);
1414 EXPECT_FALSE(characteristic->IsNotifying());
1415 EXPECT_EQ(4U, update_sessions_.size());
1417 for (int i = 0; i < 4; i++)
1418 EXPECT_FALSE(update_sessions_[0]->IsActive());
1420 // It should be possible to restart notifications and the call should reset
1421 // the session count and make a request through the client.
1422 update_sessions_.clear();
1423 success_callback_count_ = 0;
1424 observer.gatt_characteristic_value_changed_count_ = 0;
1425 characteristic->StartNotifySession(
1426 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback,
1427 base::Unretained(this)),
1428 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
1429 base::Unretained(this)));
1431 EXPECT_EQ(0, success_callback_count_);
1432 EXPECT_EQ(0, error_callback_count_);
1433 EXPECT_EQ(1, observer.gatt_characteristic_value_changed_count_);
1434 EXPECT_TRUE(characteristic->IsNotifying());
1435 EXPECT_TRUE(update_sessions_.empty());
1437 base::MessageLoop::current()->Run();
1439 EXPECT_EQ(1, success_callback_count_);
1440 EXPECT_EQ(0, error_callback_count_);
1441 EXPECT_EQ(1, observer.gatt_characteristic_value_changed_count_);
1442 EXPECT_TRUE(characteristic->IsNotifying());
1443 EXPECT_EQ(1U, update_sessions_.size());
1444 EXPECT_TRUE(update_sessions_[0]->IsActive());
1447 } // namespace chromeos