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