Simplify About Chrome settings page.
[chromium-blink-merge.git] / device / bluetooth / bluetooth_gatt_chromeos_unittest.cc
blob3c34663eee111a3f6f1da6f79d82c0f623f150b3
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 "device/bluetooth/test/test_bluetooth_adapter_observer.h"
27 #include "testing/gtest/include/gtest/gtest.h"
29 using device::BluetoothAdapter;
30 using device::BluetoothDevice;
31 using device::BluetoothGattCharacteristic;
32 using device::BluetoothGattConnection;
33 using device::BluetoothGattDescriptor;
34 using device::BluetoothGattService;
35 using device::BluetoothGattNotifySession;
36 using device::BluetoothUUID;
37 using device::TestBluetoothAdapterObserver;
39 namespace chromeos {
41 namespace {
43 const BluetoothUUID kHeartRateMeasurementUUID(
44 FakeBluetoothGattCharacteristicClient::kHeartRateMeasurementUUID);
45 const BluetoothUUID kBodySensorLocationUUID(
46 FakeBluetoothGattCharacteristicClient::kBodySensorLocationUUID);
47 const BluetoothUUID kHeartRateControlPointUUID(
48 FakeBluetoothGattCharacteristicClient::kHeartRateControlPointUUID);
50 // Compares GATT characteristic/descriptor values. Returns true, if the values
51 // are equal.
52 bool ValuesEqual(const std::vector<uint8>& value0,
53 const std::vector<uint8>& value1) {
54 if (value0.size() != value1.size())
55 return false;
56 for (size_t i = 0; i < value0.size(); ++i)
57 if (value0[i] != value1[i])
58 return false;
59 return true;
62 } // namespace
64 class BluetoothGattChromeOSTest : public testing::Test {
65 public:
66 BluetoothGattChromeOSTest()
67 : fake_bluetooth_gatt_service_client_(NULL),
68 success_callback_count_(0),
69 error_callback_count_(0) {
72 void SetUp() override {
73 scoped_ptr<DBusThreadManagerSetter> dbus_setter =
74 chromeos::DBusThreadManager::GetSetterForTesting();
75 fake_bluetooth_device_client_ = new FakeBluetoothDeviceClient;
76 fake_bluetooth_gatt_service_client_ =
77 new FakeBluetoothGattServiceClient;
78 fake_bluetooth_gatt_characteristic_client_ =
79 new FakeBluetoothGattCharacteristicClient;
80 fake_bluetooth_gatt_descriptor_client_ =
81 new FakeBluetoothGattDescriptorClient;
82 dbus_setter->SetBluetoothDeviceClient(
83 scoped_ptr<BluetoothDeviceClient>(
84 fake_bluetooth_device_client_));
85 dbus_setter->SetBluetoothGattServiceClient(
86 scoped_ptr<BluetoothGattServiceClient>(
87 fake_bluetooth_gatt_service_client_));
88 dbus_setter->SetBluetoothGattCharacteristicClient(
89 scoped_ptr<BluetoothGattCharacteristicClient>(
90 fake_bluetooth_gatt_characteristic_client_));
91 dbus_setter->SetBluetoothGattDescriptorClient(
92 scoped_ptr<BluetoothGattDescriptorClient>(
93 fake_bluetooth_gatt_descriptor_client_));
94 dbus_setter->SetBluetoothAdapterClient(
95 scoped_ptr<BluetoothAdapterClient>(new FakeBluetoothAdapterClient));
96 dbus_setter->SetBluetoothInputClient(
97 scoped_ptr<BluetoothInputClient>(new FakeBluetoothInputClient));
98 dbus_setter->SetBluetoothAgentManagerClient(
99 scoped_ptr<BluetoothAgentManagerClient>(
100 new FakeBluetoothAgentManagerClient));
102 GetAdapter();
104 adapter_->SetPowered(
105 true,
106 base::Bind(&base::DoNothing),
107 base::Bind(&base::DoNothing));
108 ASSERT_TRUE(adapter_->IsPowered());
111 void TearDown() override {
112 adapter_ = NULL;
113 update_sessions_.clear();
114 gatt_conn_.reset();
115 DBusThreadManager::Shutdown();
118 void GetAdapter() {
119 device::BluetoothAdapterFactory::GetAdapter(
120 base::Bind(&BluetoothGattChromeOSTest::AdapterCallback,
121 base::Unretained(this)));
122 ASSERT_TRUE(adapter_.get() != NULL);
123 ASSERT_TRUE(adapter_->IsInitialized());
124 ASSERT_TRUE(adapter_->IsPresent());
127 void AdapterCallback(scoped_refptr<BluetoothAdapter> adapter) {
128 adapter_ = adapter;
131 void SuccessCallback() {
132 ++success_callback_count_;
135 void ValueCallback(const std::vector<uint8>& value) {
136 ++success_callback_count_;
137 last_read_value_ = value;
140 void GattConnectionCallback(scoped_ptr<BluetoothGattConnection> conn) {
141 ++success_callback_count_;
142 gatt_conn_ = conn.Pass();
145 void NotifySessionCallback(scoped_ptr<BluetoothGattNotifySession> session) {
146 ++success_callback_count_;
147 update_sessions_.push_back(session.release());
148 QuitMessageLoop();
151 void ServiceErrorCallback(BluetoothGattService::GattErrorCode err) {
152 ++error_callback_count_;
153 last_service_error_ = err;
156 void ErrorCallback() {
157 ++error_callback_count_;
160 void DBusErrorCallback(const std::string& error_name,
161 const std::string& error_message) {
162 ++error_callback_count_;
165 void ConnectErrorCallback(BluetoothDevice::ConnectErrorCode error) {
166 ++error_callback_count_;
169 protected:
170 void QuitMessageLoop() {
171 if (base::MessageLoop::current() &&
172 base::MessageLoop::current()->is_running())
173 base::MessageLoop::current()->Quit();
176 base::MessageLoop message_loop_;
178 FakeBluetoothDeviceClient* fake_bluetooth_device_client_;
179 FakeBluetoothGattServiceClient* fake_bluetooth_gatt_service_client_;
180 FakeBluetoothGattCharacteristicClient*
181 fake_bluetooth_gatt_characteristic_client_;
182 FakeBluetoothGattDescriptorClient* fake_bluetooth_gatt_descriptor_client_;
183 scoped_ptr<device::BluetoothGattConnection> gatt_conn_;
184 ScopedVector<BluetoothGattNotifySession> update_sessions_;
185 scoped_refptr<BluetoothAdapter> adapter_;
187 int success_callback_count_;
188 int error_callback_count_;
189 std::vector<uint8> last_read_value_;
190 BluetoothGattService::GattErrorCode last_service_error_;
193 TEST_F(BluetoothGattChromeOSTest, GattConnection) {
194 fake_bluetooth_device_client_->CreateDevice(
195 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
196 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath));
197 BluetoothDevice* device = adapter_->GetDevice(
198 FakeBluetoothDeviceClient::kLowEnergyAddress);
199 ASSERT_TRUE(device);
200 ASSERT_FALSE(device->IsConnected());
201 ASSERT_FALSE(gatt_conn_.get());
202 ASSERT_EQ(0, success_callback_count_);
203 ASSERT_EQ(0, error_callback_count_);
205 device->CreateGattConnection(
206 base::Bind(&BluetoothGattChromeOSTest::GattConnectionCallback,
207 base::Unretained(this)),
208 base::Bind(&BluetoothGattChromeOSTest::ConnectErrorCallback,
209 base::Unretained(this)));
211 EXPECT_EQ(1, success_callback_count_);
212 EXPECT_EQ(0, error_callback_count_);
213 EXPECT_TRUE(device->IsConnected());
214 ASSERT_TRUE(gatt_conn_.get());
215 EXPECT_TRUE(gatt_conn_->IsConnected());
216 EXPECT_EQ(FakeBluetoothDeviceClient::kLowEnergyAddress,
217 gatt_conn_->GetDeviceAddress());
219 gatt_conn_->Disconnect(
220 base::Bind(&BluetoothGattChromeOSTest::SuccessCallback,
221 base::Unretained(this)));
222 EXPECT_EQ(2, success_callback_count_);
223 EXPECT_EQ(0, error_callback_count_);
224 EXPECT_TRUE(device->IsConnected());
225 EXPECT_FALSE(gatt_conn_->IsConnected());
227 device->CreateGattConnection(
228 base::Bind(&BluetoothGattChromeOSTest::GattConnectionCallback,
229 base::Unretained(this)),
230 base::Bind(&BluetoothGattChromeOSTest::ConnectErrorCallback,
231 base::Unretained(this)));
233 EXPECT_EQ(3, success_callback_count_);
234 EXPECT_EQ(0, error_callback_count_);
235 EXPECT_TRUE(device->IsConnected());
236 ASSERT_TRUE(gatt_conn_.get());
237 EXPECT_TRUE(gatt_conn_->IsConnected());
239 device->Disconnect(
240 base::Bind(&BluetoothGattChromeOSTest::SuccessCallback,
241 base::Unretained(this)),
242 base::Bind(&BluetoothGattChromeOSTest::ErrorCallback,
243 base::Unretained(this)));
245 EXPECT_EQ(4, success_callback_count_);
246 EXPECT_EQ(0, error_callback_count_);
247 ASSERT_TRUE(gatt_conn_.get());
248 EXPECT_FALSE(gatt_conn_->IsConnected());
250 device->CreateGattConnection(
251 base::Bind(&BluetoothGattChromeOSTest::GattConnectionCallback,
252 base::Unretained(this)),
253 base::Bind(&BluetoothGattChromeOSTest::ConnectErrorCallback,
254 base::Unretained(this)));
256 EXPECT_EQ(5, success_callback_count_);
257 EXPECT_EQ(0, error_callback_count_);
258 EXPECT_TRUE(device->IsConnected());
259 EXPECT_TRUE(gatt_conn_->IsConnected());
261 fake_bluetooth_device_client_->RemoveDevice(
262 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
263 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath));
264 ASSERT_TRUE(gatt_conn_.get());
265 EXPECT_FALSE(gatt_conn_->IsConnected());
268 TEST_F(BluetoothGattChromeOSTest, GattServiceAddedAndRemoved) {
269 // Create a fake LE device. We store the device pointer here because this is a
270 // test. It's unsafe to do this in production as the device might get deleted.
271 fake_bluetooth_device_client_->CreateDevice(
272 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
273 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath));
274 BluetoothDevice* device = adapter_->GetDevice(
275 FakeBluetoothDeviceClient::kLowEnergyAddress);
276 ASSERT_TRUE(device);
278 TestBluetoothAdapterObserver observer(adapter_);
280 EXPECT_EQ(0, observer.gatt_service_added_count());
281 EXPECT_EQ(0, observer.gatt_service_removed_count());
282 EXPECT_TRUE(observer.last_gatt_service_id().empty());
283 EXPECT_FALSE(observer.last_gatt_service_uuid().IsValid());
284 EXPECT_TRUE(device->GetGattServices().empty());
286 // Expose the fake Heart Rate Service.
287 fake_bluetooth_gatt_service_client_->ExposeHeartRateService(
288 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath));
289 EXPECT_EQ(1, observer.gatt_service_added_count());
290 EXPECT_EQ(0, observer.gatt_service_removed_count());
291 EXPECT_FALSE(observer.last_gatt_service_id().empty());
292 EXPECT_EQ(1U, device->GetGattServices().size());
293 EXPECT_EQ(
294 BluetoothUUID(FakeBluetoothGattServiceClient::kHeartRateServiceUUID),
295 observer.last_gatt_service_uuid());
297 BluetoothGattService* service =
298 device->GetGattService(observer.last_gatt_service_id());
299 EXPECT_FALSE(service->IsLocal());
300 EXPECT_TRUE(service->IsPrimary());
301 EXPECT_EQ(service, device->GetGattServices()[0]);
302 EXPECT_EQ(service, device->GetGattService(service->GetIdentifier()));
304 EXPECT_EQ(observer.last_gatt_service_uuid(), service->GetUUID());
306 // Hide the service.
307 observer.last_gatt_service_uuid() = BluetoothUUID();
308 observer.last_gatt_service_id().clear();
309 fake_bluetooth_gatt_service_client_->HideHeartRateService();
311 EXPECT_EQ(1, observer.gatt_service_added_count());
312 EXPECT_EQ(1, observer.gatt_service_removed_count());
313 EXPECT_FALSE(observer.last_gatt_service_id().empty());
314 EXPECT_TRUE(device->GetGattServices().empty());
315 EXPECT_EQ(
316 BluetoothUUID(FakeBluetoothGattServiceClient::kHeartRateServiceUUID),
317 observer.last_gatt_service_uuid());
319 EXPECT_EQ(NULL, device->GetGattService(observer.last_gatt_service_id()));
321 // Expose the service again.
322 observer.last_gatt_service_uuid() = BluetoothUUID();
323 observer.last_gatt_service_id().clear();
324 fake_bluetooth_gatt_service_client_->ExposeHeartRateService(
325 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath));
326 EXPECT_EQ(2, observer.gatt_service_added_count());
327 EXPECT_EQ(1, observer.gatt_service_removed_count());
328 EXPECT_FALSE(observer.last_gatt_service_id().empty());
329 EXPECT_EQ(1U, device->GetGattServices().size());
330 EXPECT_EQ(
331 BluetoothUUID(FakeBluetoothGattServiceClient::kHeartRateServiceUUID),
332 observer.last_gatt_service_uuid());
334 // The object |service| points to should have been deallocated. |device|
335 // should contain a brand new instance.
336 service = device->GetGattService(observer.last_gatt_service_id());
337 EXPECT_EQ(service, device->GetGattServices()[0]);
338 EXPECT_FALSE(service->IsLocal());
339 EXPECT_TRUE(service->IsPrimary());
341 EXPECT_EQ(observer.last_gatt_service_uuid(), service->GetUUID());
343 // Remove the device. The observer should be notified of the removed service.
344 // |device| becomes invalid after this.
345 observer.last_gatt_service_uuid() = BluetoothUUID();
346 observer.last_gatt_service_id().clear();
347 fake_bluetooth_device_client_->RemoveDevice(
348 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
349 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath));
351 EXPECT_EQ(2, observer.gatt_service_added_count());
352 EXPECT_EQ(2, observer.gatt_service_removed_count());
353 EXPECT_FALSE(observer.last_gatt_service_id().empty());
354 EXPECT_EQ(
355 BluetoothUUID(FakeBluetoothGattServiceClient::kHeartRateServiceUUID),
356 observer.last_gatt_service_uuid());
357 EXPECT_EQ(
358 NULL, adapter_->GetDevice(FakeBluetoothDeviceClient::kLowEnergyAddress));
361 TEST_F(BluetoothGattChromeOSTest, GattCharacteristicAddedAndRemoved) {
362 fake_bluetooth_device_client_->CreateDevice(
363 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
364 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath));
365 BluetoothDevice* device = adapter_->GetDevice(
366 FakeBluetoothDeviceClient::kLowEnergyAddress);
367 ASSERT_TRUE(device);
369 TestBluetoothAdapterObserver observer(adapter_);
371 // Expose the fake Heart Rate service. This will asynchronously expose
372 // characteristics.
373 fake_bluetooth_gatt_service_client_->ExposeHeartRateService(
374 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath));
375 ASSERT_EQ(1, observer.gatt_service_added_count());
377 BluetoothGattService* service =
378 device->GetGattService(observer.last_gatt_service_id());
380 EXPECT_EQ(0, observer.gatt_service_changed_count());
381 EXPECT_EQ(0, observer.gatt_discovery_complete_count());
382 EXPECT_EQ(0, observer.gatt_characteristic_added_count());
383 EXPECT_EQ(0, observer.gatt_characteristic_removed_count());
384 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count());
385 EXPECT_TRUE(service->GetCharacteristics().empty());
387 // Run the message loop so that the characteristics appear.
388 base::MessageLoop::current()->Run();
390 // 3 characteristics should appear. Only 1 of the characteristics sends
391 // value changed signals. Service changed should be fired once for
392 // descriptor added.
393 EXPECT_EQ(0, observer.gatt_service_changed_count());
394 EXPECT_EQ(1, observer.gatt_discovery_complete_count());
395 EXPECT_EQ(3, observer.gatt_characteristic_added_count());
396 EXPECT_EQ(0, observer.gatt_characteristic_removed_count());
397 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count());
398 EXPECT_EQ(3U, service->GetCharacteristics().size());
400 // Hide the characteristics. 3 removed signals should be received.
401 fake_bluetooth_gatt_characteristic_client_->HideHeartRateCharacteristics();
402 EXPECT_EQ(0, observer.gatt_service_changed_count());
403 EXPECT_EQ(3, observer.gatt_characteristic_added_count());
404 EXPECT_EQ(3, observer.gatt_characteristic_removed_count());
405 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count());
406 EXPECT_TRUE(service->GetCharacteristics().empty());
408 // Re-expose the heart rate characteristics. We shouldn't get another
409 // GattDiscoveryCompleteForService call, since the service thinks that
410 // discovery is done. On the bluetoothd side, characteristics will be removed
411 // only if the service will also be subsequently removed.
412 fake_bluetooth_gatt_characteristic_client_->ExposeHeartRateCharacteristics(
413 fake_bluetooth_gatt_service_client_->GetHeartRateServicePath());
414 EXPECT_EQ(0, observer.gatt_service_changed_count());
415 EXPECT_EQ(1, observer.gatt_discovery_complete_count());
416 EXPECT_EQ(6, observer.gatt_characteristic_added_count());
417 EXPECT_EQ(3, observer.gatt_characteristic_removed_count());
418 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count());
419 EXPECT_EQ(3U, service->GetCharacteristics().size());
421 // Hide the service. All characteristics should disappear.
422 fake_bluetooth_gatt_service_client_->HideHeartRateService();
423 EXPECT_EQ(0, observer.gatt_service_changed_count());
424 EXPECT_EQ(6, observer.gatt_characteristic_added_count());
425 EXPECT_EQ(6, observer.gatt_characteristic_removed_count());
426 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count());
429 TEST_F(BluetoothGattChromeOSTest, GattDescriptorAddedAndRemoved) {
430 fake_bluetooth_device_client_->CreateDevice(
431 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
432 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath));
433 BluetoothDevice* device = adapter_->GetDevice(
434 FakeBluetoothDeviceClient::kLowEnergyAddress);
435 ASSERT_TRUE(device);
437 TestBluetoothAdapterObserver observer(adapter_);
439 // Expose the fake Heart Rate service. This will asynchronously expose
440 // characteristics.
441 fake_bluetooth_gatt_service_client_->ExposeHeartRateService(
442 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath));
443 ASSERT_EQ(1, observer.gatt_service_added_count());
445 BluetoothGattService* service =
446 device->GetGattService(observer.last_gatt_service_id());
448 EXPECT_EQ(0, observer.gatt_service_changed_count());
449 EXPECT_EQ(0, observer.gatt_descriptor_added_count());
450 EXPECT_EQ(0, observer.gatt_descriptor_removed_count());
451 EXPECT_EQ(0, observer.gatt_descriptor_value_changed_count());
453 EXPECT_TRUE(service->GetCharacteristics().empty());
455 // Run the message loop so that the characteristics appear.
456 base::MessageLoop::current()->Run();
457 EXPECT_EQ(0, observer.gatt_service_changed_count());
459 // Only the Heart Rate Measurement characteristic has a descriptor.
460 EXPECT_EQ(1, observer.gatt_descriptor_added_count());
461 EXPECT_EQ(0, observer.gatt_descriptor_removed_count());
462 EXPECT_EQ(0, observer.gatt_descriptor_value_changed_count());
464 BluetoothGattCharacteristic* characteristic = service->GetCharacteristic(
465 fake_bluetooth_gatt_characteristic_client_->
466 GetBodySensorLocationPath().value());
467 ASSERT_TRUE(characteristic);
468 EXPECT_TRUE(characteristic->GetDescriptors().empty());
470 characteristic = service->GetCharacteristic(
471 fake_bluetooth_gatt_characteristic_client_->
472 GetHeartRateControlPointPath().value());
473 ASSERT_TRUE(characteristic);
474 EXPECT_TRUE(characteristic->GetDescriptors().empty());
476 characteristic = service->GetCharacteristic(
477 fake_bluetooth_gatt_characteristic_client_->
478 GetHeartRateMeasurementPath().value());
479 ASSERT_TRUE(characteristic);
480 EXPECT_EQ(1U, characteristic->GetDescriptors().size());
482 BluetoothGattDescriptor* descriptor = characteristic->GetDescriptors()[0];
483 EXPECT_FALSE(descriptor->IsLocal());
484 EXPECT_EQ(BluetoothGattDescriptor::ClientCharacteristicConfigurationUuid(),
485 descriptor->GetUUID());
486 EXPECT_EQ(descriptor->GetUUID(), observer.last_gatt_descriptor_uuid());
487 EXPECT_EQ(descriptor->GetIdentifier(), observer.last_gatt_descriptor_id());
489 // Hide the descriptor.
490 fake_bluetooth_gatt_descriptor_client_->HideDescriptor(
491 dbus::ObjectPath(descriptor->GetIdentifier()));
492 EXPECT_TRUE(characteristic->GetDescriptors().empty());
493 EXPECT_EQ(0, observer.gatt_service_changed_count());
494 EXPECT_EQ(1, observer.gatt_descriptor_added_count());
495 EXPECT_EQ(1, observer.gatt_descriptor_removed_count());
496 EXPECT_EQ(0, observer.gatt_descriptor_value_changed_count());
498 // Expose the descriptor again.
499 observer.last_gatt_descriptor_id().clear();
500 observer.last_gatt_descriptor_uuid() = BluetoothUUID();
501 fake_bluetooth_gatt_descriptor_client_->ExposeDescriptor(
502 dbus::ObjectPath(characteristic->GetIdentifier()),
503 FakeBluetoothGattDescriptorClient::
504 kClientCharacteristicConfigurationUUID);
505 EXPECT_EQ(0, observer.gatt_service_changed_count());
506 EXPECT_EQ(1U, characteristic->GetDescriptors().size());
507 EXPECT_EQ(2, observer.gatt_descriptor_added_count());
508 EXPECT_EQ(1, observer.gatt_descriptor_removed_count());
509 EXPECT_EQ(0, observer.gatt_descriptor_value_changed_count());
511 descriptor = characteristic->GetDescriptors()[0];
512 EXPECT_FALSE(descriptor->IsLocal());
513 EXPECT_EQ(BluetoothGattDescriptor::ClientCharacteristicConfigurationUuid(),
514 descriptor->GetUUID());
515 EXPECT_EQ(descriptor->GetUUID(), observer.last_gatt_descriptor_uuid());
516 EXPECT_EQ(descriptor->GetIdentifier(), observer.last_gatt_descriptor_id());
519 TEST_F(BluetoothGattChromeOSTest, AdapterAddedAfterGattService) {
520 // This unit test tests that all remote GATT objects are created for D-Bus
521 // objects that were already exposed.
522 adapter_ = NULL;
523 ASSERT_FALSE(device::BluetoothAdapterFactory::HasSharedInstanceForTesting());
525 // Create the fake D-Bus objects.
526 fake_bluetooth_device_client_->CreateDevice(
527 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
528 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath));
529 fake_bluetooth_gatt_service_client_->ExposeHeartRateService(
530 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath));
531 while (!fake_bluetooth_gatt_characteristic_client_->IsHeartRateVisible())
532 base::RunLoop().RunUntilIdle();
533 ASSERT_TRUE(fake_bluetooth_gatt_service_client_->IsHeartRateVisible());
534 ASSERT_TRUE(fake_bluetooth_gatt_characteristic_client_->IsHeartRateVisible());
536 // Create the adapter. This should create all the GATT objects.
537 GetAdapter();
538 BluetoothDevice* device = adapter_->GetDevice(
539 FakeBluetoothDeviceClient::kLowEnergyAddress);
540 ASSERT_TRUE(device);
541 EXPECT_EQ(1U, device->GetGattServices().size());
543 BluetoothGattService* service = device->GetGattServices()[0];
544 ASSERT_TRUE(service);
545 EXPECT_FALSE(service->IsLocal());
546 EXPECT_TRUE(service->IsPrimary());
547 EXPECT_EQ(
548 BluetoothUUID(FakeBluetoothGattServiceClient::kHeartRateServiceUUID),
549 service->GetUUID());
550 EXPECT_EQ(service, device->GetGattServices()[0]);
551 EXPECT_EQ(service, device->GetGattService(service->GetIdentifier()));
552 EXPECT_FALSE(service->IsLocal());
553 EXPECT_EQ(3U, service->GetCharacteristics().size());
555 BluetoothGattCharacteristic* characteristic = service->GetCharacteristic(
556 fake_bluetooth_gatt_characteristic_client_->
557 GetBodySensorLocationPath().value());
558 ASSERT_TRUE(characteristic);
559 EXPECT_EQ(
560 BluetoothUUID(FakeBluetoothGattCharacteristicClient::
561 kBodySensorLocationUUID),
562 characteristic->GetUUID());
563 EXPECT_FALSE(characteristic->IsLocal());
564 EXPECT_TRUE(characteristic->GetDescriptors().empty());
566 characteristic = service->GetCharacteristic(
567 fake_bluetooth_gatt_characteristic_client_->
568 GetHeartRateControlPointPath().value());
569 ASSERT_TRUE(characteristic);
570 EXPECT_EQ(
571 BluetoothUUID(FakeBluetoothGattCharacteristicClient::
572 kHeartRateControlPointUUID),
573 characteristic->GetUUID());
574 EXPECT_FALSE(characteristic->IsLocal());
575 EXPECT_TRUE(characteristic->GetDescriptors().empty());
577 characteristic = service->GetCharacteristic(
578 fake_bluetooth_gatt_characteristic_client_->
579 GetHeartRateMeasurementPath().value());
580 ASSERT_TRUE(characteristic);
581 EXPECT_EQ(
582 BluetoothUUID(FakeBluetoothGattCharacteristicClient::
583 kHeartRateMeasurementUUID),
584 characteristic->GetUUID());
585 EXPECT_FALSE(characteristic->IsLocal());
586 EXPECT_EQ(1U, characteristic->GetDescriptors().size());
588 BluetoothGattDescriptor* descriptor = characteristic->GetDescriptors()[0];
589 ASSERT_TRUE(descriptor);
590 EXPECT_EQ(BluetoothGattDescriptor::ClientCharacteristicConfigurationUuid(),
591 descriptor->GetUUID());
592 EXPECT_FALSE(descriptor->IsLocal());
595 TEST_F(BluetoothGattChromeOSTest, GattCharacteristicValue) {
596 fake_bluetooth_device_client_->CreateDevice(
597 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
598 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath));
599 BluetoothDevice* device = adapter_->GetDevice(
600 FakeBluetoothDeviceClient::kLowEnergyAddress);
601 ASSERT_TRUE(device);
603 TestBluetoothAdapterObserver observer(adapter_);
605 // Expose the fake Heart Rate service. This will asynchronously expose
606 // characteristics.
607 fake_bluetooth_gatt_service_client_->ExposeHeartRateService(
608 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath));
609 ASSERT_EQ(1, observer.gatt_service_added_count());
611 BluetoothGattService* service =
612 device->GetGattService(observer.last_gatt_service_id());
614 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count());
616 // Run the message loop so that the characteristics appear.
617 base::MessageLoop::current()->Run();
619 // Issue write request to non-writable characteristics.
620 observer.Reset();
622 std::vector<uint8> write_value;
623 write_value.push_back(0x01);
624 BluetoothGattCharacteristic* characteristic =
625 service->GetCharacteristic(fake_bluetooth_gatt_characteristic_client_->
626 GetHeartRateMeasurementPath().value());
627 ASSERT_TRUE(characteristic);
628 EXPECT_FALSE(characteristic->IsNotifying());
629 EXPECT_EQ(fake_bluetooth_gatt_characteristic_client_->
630 GetHeartRateMeasurementPath().value(),
631 characteristic->GetIdentifier());
632 EXPECT_EQ(kHeartRateMeasurementUUID, characteristic->GetUUID());
633 characteristic->WriteRemoteCharacteristic(
634 write_value,
635 base::Bind(&BluetoothGattChromeOSTest::SuccessCallback,
636 base::Unretained(this)),
637 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
638 base::Unretained(this)));
639 EXPECT_TRUE(observer.last_gatt_characteristic_id().empty());
640 EXPECT_FALSE(observer.last_gatt_characteristic_uuid().IsValid());
641 EXPECT_EQ(0, success_callback_count_);
642 EXPECT_EQ(1, error_callback_count_);
643 EXPECT_EQ(BluetoothGattService::GATT_ERROR_NOT_SUPPORTED,
644 last_service_error_);
645 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count());
647 characteristic = service->GetCharacteristic(
648 fake_bluetooth_gatt_characteristic_client_->
649 GetBodySensorLocationPath().value());
650 ASSERT_TRUE(characteristic);
651 EXPECT_EQ(fake_bluetooth_gatt_characteristic_client_->
652 GetBodySensorLocationPath().value(),
653 characteristic->GetIdentifier());
654 EXPECT_EQ(kBodySensorLocationUUID, characteristic->GetUUID());
655 characteristic->WriteRemoteCharacteristic(
656 write_value,
657 base::Bind(&BluetoothGattChromeOSTest::SuccessCallback,
658 base::Unretained(this)),
659 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
660 base::Unretained(this)));
661 EXPECT_TRUE(observer.last_gatt_characteristic_id().empty());
662 EXPECT_FALSE(observer.last_gatt_characteristic_uuid().IsValid());
663 EXPECT_EQ(0, success_callback_count_);
664 EXPECT_EQ(2, error_callback_count_);
665 EXPECT_EQ(BluetoothGattService::GATT_ERROR_NOT_PERMITTED,
666 last_service_error_);
667 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count());
669 // Issue write request to writable characteristic. The "Body Sensor Location"
670 // characteristic does not send notifications and WriteValue does not result
671 // in a CharacteristicValueChanged event, thus no such event should be
672 // received.
673 characteristic = service->GetCharacteristic(
674 fake_bluetooth_gatt_characteristic_client_->
675 GetHeartRateControlPointPath().value());
676 ASSERT_TRUE(characteristic);
677 EXPECT_EQ(fake_bluetooth_gatt_characteristic_client_->
678 GetHeartRateControlPointPath().value(),
679 characteristic->GetIdentifier());
680 EXPECT_EQ(kHeartRateControlPointUUID, characteristic->GetUUID());
681 characteristic->WriteRemoteCharacteristic(
682 write_value,
683 base::Bind(&BluetoothGattChromeOSTest::SuccessCallback,
684 base::Unretained(this)),
685 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
686 base::Unretained(this)));
687 EXPECT_TRUE(observer.last_gatt_characteristic_id().empty());
688 EXPECT_FALSE(observer.last_gatt_characteristic_uuid().IsValid());
689 EXPECT_EQ(1, success_callback_count_);
690 EXPECT_EQ(2, error_callback_count_);
691 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count());
693 // Issue some invalid write requests to the characteristic.
694 // The value should still not change.
696 std::vector<uint8> invalid_write_length;
697 invalid_write_length.push_back(0x01);
698 invalid_write_length.push_back(0x00);
699 characteristic->WriteRemoteCharacteristic(
700 invalid_write_length,
701 base::Bind(&BluetoothGattChromeOSTest::SuccessCallback,
702 base::Unretained(this)),
703 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
704 base::Unretained(this)));
705 EXPECT_EQ(1, success_callback_count_);
706 EXPECT_EQ(3, error_callback_count_);
707 EXPECT_EQ(BluetoothGattService::GATT_ERROR_INVALID_LENGTH,
708 last_service_error_);
709 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count());
711 std::vector<uint8> invalid_write_value;
712 invalid_write_value.push_back(0x02);
713 characteristic->WriteRemoteCharacteristic(
714 invalid_write_value,
715 base::Bind(&BluetoothGattChromeOSTest::SuccessCallback,
716 base::Unretained(this)),
717 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
718 base::Unretained(this)));
719 EXPECT_EQ(1, success_callback_count_);
720 EXPECT_EQ(4, error_callback_count_);
721 EXPECT_EQ(BluetoothGattService::GATT_ERROR_FAILED, last_service_error_);
722 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count());
724 // Issue a read request. A successful read results in a
725 // CharacteristicValueChanged notification.
726 characteristic = service->GetCharacteristic(
727 fake_bluetooth_gatt_characteristic_client_->
728 GetBodySensorLocationPath().value());
729 ASSERT_TRUE(characteristic);
730 EXPECT_EQ(fake_bluetooth_gatt_characteristic_client_->
731 GetBodySensorLocationPath().value(),
732 characteristic->GetIdentifier());
733 EXPECT_EQ(kBodySensorLocationUUID, characteristic->GetUUID());
734 characteristic->ReadRemoteCharacteristic(
735 base::Bind(&BluetoothGattChromeOSTest::ValueCallback,
736 base::Unretained(this)),
737 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
738 base::Unretained(this)));
739 EXPECT_EQ(2, success_callback_count_);
740 EXPECT_EQ(4, error_callback_count_);
741 EXPECT_EQ(1, observer.gatt_characteristic_value_changed_count());
742 EXPECT_TRUE(ValuesEqual(characteristic->GetValue(), last_read_value_));
744 // Test long-running actions.
745 fake_bluetooth_gatt_characteristic_client_->SetExtraProcessing(1);
746 characteristic = service->GetCharacteristic(
747 fake_bluetooth_gatt_characteristic_client_->GetBodySensorLocationPath()
748 .value());
749 ASSERT_TRUE(characteristic);
750 EXPECT_EQ(
751 fake_bluetooth_gatt_characteristic_client_->GetBodySensorLocationPath()
752 .value(),
753 characteristic->GetIdentifier());
754 EXPECT_EQ(kBodySensorLocationUUID, characteristic->GetUUID());
755 characteristic->ReadRemoteCharacteristic(
756 base::Bind(&BluetoothGattChromeOSTest::ValueCallback,
757 base::Unretained(this)),
758 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
759 base::Unretained(this)));
761 // Callback counts shouldn't change, this one will be delayed until after
762 // tne next one.
763 EXPECT_EQ(2, success_callback_count_);
764 EXPECT_EQ(4, error_callback_count_);
765 EXPECT_EQ(1, observer.gatt_characteristic_value_changed_count());
767 // Next read should error because IN_PROGRESS
768 characteristic->ReadRemoteCharacteristic(
769 base::Bind(&BluetoothGattChromeOSTest::ValueCallback,
770 base::Unretained(this)),
771 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
772 base::Unretained(this)));
773 EXPECT_EQ(5, error_callback_count_);
774 EXPECT_EQ(BluetoothGattService::GATT_ERROR_IN_PROGRESS, last_service_error_);
776 // But previous call finished.
777 EXPECT_EQ(3, success_callback_count_);
778 EXPECT_EQ(2, observer.gatt_characteristic_value_changed_count());
779 EXPECT_TRUE(ValuesEqual(characteristic->GetValue(), last_read_value_));
780 fake_bluetooth_gatt_characteristic_client_->SetExtraProcessing(0);
782 // Test unauthorized actions.
783 fake_bluetooth_gatt_characteristic_client_->SetAuthorized(false);
784 characteristic->ReadRemoteCharacteristic(
785 base::Bind(&BluetoothGattChromeOSTest::ValueCallback,
786 base::Unretained(this)),
787 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
788 base::Unretained(this)));
789 EXPECT_EQ(3, success_callback_count_);
790 EXPECT_EQ(6, error_callback_count_);
791 EXPECT_EQ(BluetoothGattService::GATT_ERROR_NOT_AUTHORIZED,
792 last_service_error_);
793 EXPECT_EQ(2, observer.gatt_characteristic_value_changed_count());
794 fake_bluetooth_gatt_characteristic_client_->SetAuthorized(true);
796 // Test unauthenticated / needs login.
797 fake_bluetooth_gatt_characteristic_client_->SetAuthenticated(false);
798 characteristic->ReadRemoteCharacteristic(
799 base::Bind(&BluetoothGattChromeOSTest::ValueCallback,
800 base::Unretained(this)),
801 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
802 base::Unretained(this)));
803 EXPECT_EQ(3, success_callback_count_);
804 EXPECT_EQ(7, error_callback_count_);
805 EXPECT_EQ(BluetoothGattService::GATT_ERROR_NOT_PAIRED, last_service_error_);
806 EXPECT_EQ(2, observer.gatt_characteristic_value_changed_count());
807 fake_bluetooth_gatt_characteristic_client_->SetAuthenticated(true);
810 TEST_F(BluetoothGattChromeOSTest, GattCharacteristicProperties) {
811 fake_bluetooth_device_client_->CreateDevice(
812 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
813 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath));
814 BluetoothDevice* device = adapter_->GetDevice(
815 FakeBluetoothDeviceClient::kLowEnergyAddress);
816 ASSERT_TRUE(device);
818 TestBluetoothAdapterObserver observer(adapter_);
820 // Expose the fake Heart Rate service. This will asynchronously expose
821 // characteristics.
822 fake_bluetooth_gatt_service_client_->ExposeHeartRateService(
823 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath));
825 BluetoothGattService* service =
826 device->GetGattService(observer.last_gatt_service_id());
828 EXPECT_TRUE(service->GetCharacteristics().empty());
830 // Run the message loop so that the characteristics appear.
831 base::MessageLoop::current()->Run();
833 BluetoothGattCharacteristic *characteristic = service->GetCharacteristic(
834 fake_bluetooth_gatt_characteristic_client_->
835 GetBodySensorLocationPath().value());
836 EXPECT_EQ(BluetoothGattCharacteristic::PROPERTY_READ,
837 characteristic->GetProperties());
839 characteristic = service->GetCharacteristic(
840 fake_bluetooth_gatt_characteristic_client_->
841 GetHeartRateControlPointPath().value());
842 EXPECT_EQ(BluetoothGattCharacteristic::PROPERTY_WRITE,
843 characteristic->GetProperties());
845 characteristic = service->GetCharacteristic(
846 fake_bluetooth_gatt_characteristic_client_->
847 GetHeartRateMeasurementPath().value());
848 EXPECT_EQ(BluetoothGattCharacteristic::PROPERTY_NOTIFY,
849 characteristic->GetProperties());
852 TEST_F(BluetoothGattChromeOSTest, GattDescriptorValue) {
853 fake_bluetooth_device_client_->CreateDevice(
854 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
855 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath));
856 BluetoothDevice* device = adapter_->GetDevice(
857 FakeBluetoothDeviceClient::kLowEnergyAddress);
858 ASSERT_TRUE(device);
860 TestBluetoothAdapterObserver observer(adapter_);
862 // Expose the fake Heart Rate service. This will asynchronously expose
863 // characteristics.
864 fake_bluetooth_gatt_service_client_->ExposeHeartRateService(
865 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath));
866 ASSERT_EQ(1, observer.gatt_service_added_count());
868 BluetoothGattService* service =
869 device->GetGattService(observer.last_gatt_service_id());
871 EXPECT_EQ(0, observer.gatt_service_changed_count());
872 EXPECT_EQ(0, observer.gatt_discovery_complete_count());
873 EXPECT_EQ(0, observer.gatt_descriptor_value_changed_count());
874 EXPECT_TRUE(service->GetCharacteristics().empty());
876 // Run the message loop so that the characteristics appear.
877 base::MessageLoop::current()->Run();
878 EXPECT_EQ(0, observer.gatt_service_changed_count());
879 EXPECT_EQ(1, observer.gatt_discovery_complete_count());
881 // Only the Heart Rate Measurement characteristic has a descriptor.
882 BluetoothGattCharacteristic* characteristic = service->GetCharacteristic(
883 fake_bluetooth_gatt_characteristic_client_->
884 GetHeartRateMeasurementPath().value());
885 ASSERT_TRUE(characteristic);
886 EXPECT_EQ(1U, characteristic->GetDescriptors().size());
887 EXPECT_FALSE(characteristic->IsNotifying());
889 BluetoothGattDescriptor* descriptor = characteristic->GetDescriptors()[0];
890 EXPECT_FALSE(descriptor->IsLocal());
891 EXPECT_EQ(BluetoothGattDescriptor::ClientCharacteristicConfigurationUuid(),
892 descriptor->GetUUID());
894 std::vector<uint8_t> desc_value = {0x00, 0x00};
896 /* The cached value will be empty until the first read request */
897 EXPECT_FALSE(ValuesEqual(desc_value, descriptor->GetValue()));
898 EXPECT_TRUE(descriptor->GetValue().empty());
900 EXPECT_EQ(0, success_callback_count_);
901 EXPECT_EQ(0, error_callback_count_);
902 EXPECT_TRUE(last_read_value_.empty());
904 // Read value. GattDescriptorValueChanged event will be sent after a
905 // successful read.
906 descriptor->ReadRemoteDescriptor(
907 base::Bind(&BluetoothGattChromeOSTest::ValueCallback,
908 base::Unretained(this)),
909 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
910 base::Unretained(this)));
911 EXPECT_EQ(1, success_callback_count_);
912 EXPECT_EQ(0, error_callback_count_);
913 EXPECT_TRUE(ValuesEqual(last_read_value_, descriptor->GetValue()));
914 EXPECT_TRUE(ValuesEqual(desc_value, descriptor->GetValue()));
915 EXPECT_EQ(0, observer.gatt_service_changed_count());
916 EXPECT_EQ(1, observer.gatt_descriptor_value_changed_count());
918 // Write value. Writes to this descriptor will fail.
919 desc_value[0] = 0x03;
920 descriptor->WriteRemoteDescriptor(
921 desc_value,
922 base::Bind(&BluetoothGattChromeOSTest::SuccessCallback,
923 base::Unretained(this)),
924 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
925 base::Unretained(this)));
926 EXPECT_EQ(1, success_callback_count_);
927 EXPECT_EQ(1, error_callback_count_);
928 EXPECT_EQ(BluetoothGattService::GATT_ERROR_NOT_PERMITTED,
929 last_service_error_);
930 EXPECT_TRUE(ValuesEqual(last_read_value_, descriptor->GetValue()));
931 EXPECT_FALSE(ValuesEqual(desc_value, descriptor->GetValue()));
932 EXPECT_EQ(0, observer.gatt_service_changed_count());
933 EXPECT_EQ(1, observer.gatt_descriptor_value_changed_count());
935 // Read value. The value should remain unchanged.
936 descriptor->ReadRemoteDescriptor(
937 base::Bind(&BluetoothGattChromeOSTest::ValueCallback,
938 base::Unretained(this)),
939 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
940 base::Unretained(this)));
941 EXPECT_EQ(2, success_callback_count_);
942 EXPECT_EQ(1, error_callback_count_);
943 EXPECT_TRUE(ValuesEqual(last_read_value_, descriptor->GetValue()));
944 EXPECT_FALSE(ValuesEqual(desc_value, descriptor->GetValue()));
945 EXPECT_EQ(0, observer.gatt_service_changed_count());
946 EXPECT_EQ(1, observer.gatt_descriptor_value_changed_count());
948 // Start notifications on the descriptor's characteristic. The descriptor
949 // value should change.
950 characteristic->StartNotifySession(
951 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback,
952 base::Unretained(this)),
953 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
954 base::Unretained(this)));
955 base::MessageLoop::current()->Run();
956 EXPECT_EQ(3, success_callback_count_);
957 EXPECT_EQ(1, error_callback_count_);
958 EXPECT_EQ(1U, update_sessions_.size());
959 EXPECT_TRUE(characteristic->IsNotifying());
961 // Read the new descriptor value. We should receive a value updated event.
962 descriptor->ReadRemoteDescriptor(
963 base::Bind(&BluetoothGattChromeOSTest::ValueCallback,
964 base::Unretained(this)),
965 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
966 base::Unretained(this)));
967 EXPECT_EQ(4, success_callback_count_);
968 EXPECT_EQ(1, error_callback_count_);
969 EXPECT_TRUE(ValuesEqual(last_read_value_, descriptor->GetValue()));
970 EXPECT_FALSE(ValuesEqual(desc_value, descriptor->GetValue()));
971 EXPECT_EQ(0, observer.gatt_service_changed_count());
972 EXPECT_EQ(2, observer.gatt_descriptor_value_changed_count());
975 TEST_F(BluetoothGattChromeOSTest, NotifySessions) {
976 fake_bluetooth_device_client_->CreateDevice(
977 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
978 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath));
979 BluetoothDevice* device =
980 adapter_->GetDevice(FakeBluetoothDeviceClient::kLowEnergyAddress);
981 ASSERT_TRUE(device);
983 TestBluetoothAdapterObserver observer(adapter_);
985 // Expose the fake Heart Rate service. This will asynchronously expose
986 // characteristics.
987 fake_bluetooth_gatt_service_client_->ExposeHeartRateService(
988 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath));
989 ASSERT_EQ(1, observer.gatt_service_added_count());
991 BluetoothGattService* service =
992 device->GetGattService(observer.last_gatt_service_id());
994 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count());
996 // Run the message loop so that the characteristics appear.
997 base::MessageLoop::current()->Run();
999 BluetoothGattCharacteristic* characteristic = service->GetCharacteristic(
1000 fake_bluetooth_gatt_characteristic_client_->GetHeartRateMeasurementPath()
1001 .value());
1002 ASSERT_TRUE(characteristic);
1003 EXPECT_FALSE(characteristic->IsNotifying());
1004 EXPECT_TRUE(update_sessions_.empty());
1006 // Request to start notifications.
1007 characteristic->StartNotifySession(
1008 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback,
1009 base::Unretained(this)),
1010 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
1011 base::Unretained(this)));
1013 // The operation still hasn't completed but we should have received the first
1014 // notification.
1015 EXPECT_EQ(0, success_callback_count_);
1016 EXPECT_EQ(0, error_callback_count_);
1017 EXPECT_EQ(1, observer.gatt_characteristic_value_changed_count());
1018 EXPECT_TRUE(update_sessions_.empty());
1020 // Send a two more requests, which should get queued.
1021 characteristic->StartNotifySession(
1022 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback,
1023 base::Unretained(this)),
1024 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
1025 base::Unretained(this)));
1026 characteristic->StartNotifySession(
1027 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback,
1028 base::Unretained(this)),
1029 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
1030 base::Unretained(this)));
1031 EXPECT_EQ(0, success_callback_count_);
1032 EXPECT_EQ(0, error_callback_count_);
1033 EXPECT_EQ(1, observer.gatt_characteristic_value_changed_count());
1034 EXPECT_TRUE(update_sessions_.empty());
1035 EXPECT_TRUE(characteristic->IsNotifying());
1037 // Run the main loop. The initial call should complete. The queued call should
1038 // succeed immediately.
1039 base::MessageLoop::current()->Run();
1041 EXPECT_EQ(3, success_callback_count_);
1042 EXPECT_EQ(0, error_callback_count_);
1043 EXPECT_EQ(1, observer.gatt_characteristic_value_changed_count());
1044 EXPECT_EQ(3U, update_sessions_.size());
1046 // Notifications should be getting sent regularly now.
1047 base::MessageLoop::current()->Run();
1048 EXPECT_GT(observer.gatt_characteristic_value_changed_count(), 1);
1050 // Stop one of the sessions. The session should become inactive but the
1051 // characteristic should still be notifying.
1052 BluetoothGattNotifySession* session = update_sessions_[0];
1053 EXPECT_TRUE(session->IsActive());
1054 session->Stop(base::Bind(&BluetoothGattChromeOSTest::SuccessCallback,
1055 base::Unretained(this)));
1056 EXPECT_EQ(4, success_callback_count_);
1057 EXPECT_EQ(0, error_callback_count_);
1058 EXPECT_FALSE(session->IsActive());
1059 EXPECT_EQ(characteristic->GetIdentifier(),
1060 session->GetCharacteristicIdentifier());
1061 EXPECT_TRUE(characteristic->IsNotifying());
1063 // Delete another session. Characteristic should still be notifying.
1064 update_sessions_.pop_back();
1065 EXPECT_EQ(2U, update_sessions_.size());
1066 EXPECT_TRUE(characteristic->IsNotifying());
1067 EXPECT_FALSE(update_sessions_[0]->IsActive());
1068 EXPECT_TRUE(update_sessions_[1]->IsActive());
1070 // Clear the last session.
1071 update_sessions_.clear();
1072 EXPECT_TRUE(update_sessions_.empty());
1073 EXPECT_FALSE(characteristic->IsNotifying());
1075 success_callback_count_ = 0;
1076 observer.Reset();
1078 // Enable notifications again.
1079 characteristic->StartNotifySession(
1080 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback,
1081 base::Unretained(this)),
1082 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
1083 base::Unretained(this)));
1084 EXPECT_EQ(0, success_callback_count_);
1085 EXPECT_EQ(0, error_callback_count_);
1086 EXPECT_EQ(1, observer.gatt_characteristic_value_changed_count());
1087 EXPECT_TRUE(update_sessions_.empty());
1088 EXPECT_TRUE(characteristic->IsNotifying());
1090 // Run the message loop. Notifications should begin.
1091 base::MessageLoop::current()->Run();
1093 EXPECT_EQ(1, success_callback_count_);
1094 EXPECT_EQ(0, error_callback_count_);
1095 EXPECT_EQ(1, observer.gatt_characteristic_value_changed_count());
1096 EXPECT_EQ(1U, update_sessions_.size());
1097 EXPECT_TRUE(update_sessions_[0]->IsActive());
1098 EXPECT_TRUE(characteristic->IsNotifying());
1100 // Check that notifications are happening.
1101 base::MessageLoop::current()->Run();
1102 EXPECT_GT(observer.gatt_characteristic_value_changed_count(), 1);
1104 // Request another session. This should return immediately.
1105 characteristic->StartNotifySession(
1106 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback,
1107 base::Unretained(this)),
1108 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
1109 base::Unretained(this)));
1110 EXPECT_EQ(2, success_callback_count_);
1111 EXPECT_EQ(0, error_callback_count_);
1112 EXPECT_EQ(2U, update_sessions_.size());
1113 EXPECT_TRUE(update_sessions_[0]->IsActive());
1114 EXPECT_TRUE(update_sessions_[1]->IsActive());
1115 EXPECT_TRUE(characteristic->IsNotifying());
1117 // Hide the characteristic. The sessions should become inactive.
1118 fake_bluetooth_gatt_characteristic_client_->HideHeartRateCharacteristics();
1119 EXPECT_EQ(2U, update_sessions_.size());
1120 EXPECT_FALSE(update_sessions_[0]->IsActive());
1121 EXPECT_FALSE(update_sessions_[1]->IsActive());
1124 TEST_F(BluetoothGattChromeOSTest, NotifySessionsMadeInactive) {
1125 fake_bluetooth_device_client_->CreateDevice(
1126 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
1127 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath));
1128 BluetoothDevice* device =
1129 adapter_->GetDevice(FakeBluetoothDeviceClient::kLowEnergyAddress);
1130 ASSERT_TRUE(device);
1132 TestBluetoothAdapterObserver observer(adapter_);
1134 // Expose the fake Heart Rate service. This will asynchronously expose
1135 // characteristics.
1136 fake_bluetooth_gatt_service_client_->ExposeHeartRateService(
1137 dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath));
1138 ASSERT_EQ(1, observer.gatt_service_added_count());
1140 BluetoothGattService* service =
1141 device->GetGattService(observer.last_gatt_service_id());
1143 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count());
1145 // Run the message loop so that the characteristics appear.
1146 base::MessageLoop::current()->Run();
1148 BluetoothGattCharacteristic* characteristic = service->GetCharacteristic(
1149 fake_bluetooth_gatt_characteristic_client_->GetHeartRateMeasurementPath()
1150 .value());
1151 ASSERT_TRUE(characteristic);
1152 EXPECT_FALSE(characteristic->IsNotifying());
1153 EXPECT_TRUE(update_sessions_.empty());
1155 // Send several requests to start notifications.
1156 characteristic->StartNotifySession(
1157 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback,
1158 base::Unretained(this)),
1159 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
1160 base::Unretained(this)));
1161 characteristic->StartNotifySession(
1162 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback,
1163 base::Unretained(this)),
1164 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
1165 base::Unretained(this)));
1166 characteristic->StartNotifySession(
1167 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback,
1168 base::Unretained(this)),
1169 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
1170 base::Unretained(this)));
1171 characteristic->StartNotifySession(
1172 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback,
1173 base::Unretained(this)),
1174 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
1175 base::Unretained(this)));
1177 // The operation still hasn't completed but we should have received the first
1178 // notification.
1179 EXPECT_EQ(0, success_callback_count_);
1180 EXPECT_EQ(0, error_callback_count_);
1181 EXPECT_EQ(1, observer.gatt_characteristic_value_changed_count());
1182 EXPECT_TRUE(characteristic->IsNotifying());
1183 EXPECT_TRUE(update_sessions_.empty());
1185 // Run the main loop. The initial call should complete. The queued calls
1186 // should succeed immediately.
1187 base::MessageLoop::current()->Run();
1189 EXPECT_EQ(4, success_callback_count_);
1190 EXPECT_EQ(0, error_callback_count_);
1191 EXPECT_EQ(1, observer.gatt_characteristic_value_changed_count());
1192 EXPECT_TRUE(characteristic->IsNotifying());
1193 EXPECT_EQ(4U, update_sessions_.size());
1195 for (int i = 0; i < 4; i++)
1196 EXPECT_TRUE(update_sessions_[0]->IsActive());
1198 // Stop notifications directly through the client. The sessions should get
1199 // marked as inactive.
1200 fake_bluetooth_gatt_characteristic_client_->StopNotify(
1201 fake_bluetooth_gatt_characteristic_client_->GetHeartRateMeasurementPath(),
1202 base::Bind(&BluetoothGattChromeOSTest::SuccessCallback,
1203 base::Unretained(this)),
1204 base::Bind(&BluetoothGattChromeOSTest::DBusErrorCallback,
1205 base::Unretained(this)));
1206 EXPECT_EQ(5, success_callback_count_);
1207 EXPECT_EQ(0, error_callback_count_);
1208 EXPECT_FALSE(characteristic->IsNotifying());
1209 EXPECT_EQ(4U, update_sessions_.size());
1211 for (int i = 0; i < 4; i++)
1212 EXPECT_FALSE(update_sessions_[0]->IsActive());
1214 // It should be possible to restart notifications and the call should reset
1215 // the session count and make a request through the client.
1216 update_sessions_.clear();
1217 success_callback_count_ = 0;
1218 observer.Reset();
1219 characteristic->StartNotifySession(
1220 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback,
1221 base::Unretained(this)),
1222 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
1223 base::Unretained(this)));
1225 EXPECT_EQ(0, success_callback_count_);
1226 EXPECT_EQ(0, error_callback_count_);
1227 EXPECT_EQ(1, observer.gatt_characteristic_value_changed_count());
1228 EXPECT_TRUE(characteristic->IsNotifying());
1229 EXPECT_TRUE(update_sessions_.empty());
1231 base::MessageLoop::current()->Run();
1233 EXPECT_EQ(1, success_callback_count_);
1234 EXPECT_EQ(0, error_callback_count_);
1235 EXPECT_EQ(1, observer.gatt_characteristic_value_changed_count());
1236 EXPECT_TRUE(characteristic->IsNotifying());
1237 EXPECT_EQ(1U, update_sessions_.size());
1238 EXPECT_TRUE(update_sessions_[0]->IsActive());
1241 } // namespace chromeos