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