Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(438)

Side by Side Diff: device/bluetooth/bluetooth_gatt_bluez_unittest.cc

Issue 1898643002: Refactor device::BluetoothGattXXX classes to split into remote/local. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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.
4
5 #include <stddef.h>
6 #include <stdint.h>
7
8 #include <memory>
9 #include <utility>
10
11 #include "base/memory/scoped_vector.h"
12 #include "base/message_loop/message_loop.h"
13 #include "base/run_loop.h"
14 #include "dbus/object_path.h"
15 #include "device/bluetooth/bluetooth_adapter.h"
16 #include "device/bluetooth/bluetooth_adapter_factory.h"
17 #include "device/bluetooth/bluetooth_device.h"
18 #include "device/bluetooth/bluetooth_gatt_characteristic.h"
19 #include "device/bluetooth/bluetooth_gatt_connection.h"
20 #include "device/bluetooth/bluetooth_gatt_descriptor.h"
21 #include "device/bluetooth/bluetooth_gatt_notify_session.h"
22 #include "device/bluetooth/bluetooth_gatt_service.h"
23 #include "device/bluetooth/bluetooth_uuid.h"
24 #include "device/bluetooth/dbus/bluez_dbus_manager.h"
25 #include "device/bluetooth/dbus/fake_bluetooth_adapter_client.h"
26 #include "device/bluetooth/dbus/fake_bluetooth_agent_manager_client.h"
27 #include "device/bluetooth/dbus/fake_bluetooth_device_client.h"
28 #include "device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_client.h"
29 #include "device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_client.h"
30 #include "device/bluetooth/dbus/fake_bluetooth_gatt_service_client.h"
31 #include "device/bluetooth/dbus/fake_bluetooth_input_client.h"
32 #include "device/bluetooth/test/test_bluetooth_adapter_observer.h"
33 #include "testing/gtest/include/gtest/gtest.h"
34
35 using device::BluetoothAdapter;
36 using device::BluetoothDevice;
37 using device::BluetoothGattCharacteristic;
38 using device::BluetoothGattConnection;
39 using device::BluetoothGattDescriptor;
40 using device::BluetoothGattService;
41 using device::BluetoothGattNotifySession;
42 using device::BluetoothUUID;
43 using device::TestBluetoothAdapterObserver;
44
45 namespace bluez {
46
47 namespace {
48
49 const BluetoothUUID kHeartRateMeasurementUUID(
50 bluez::FakeBluetoothGattCharacteristicClient::kHeartRateMeasurementUUID);
51 const BluetoothUUID kBodySensorLocationUUID(
52 bluez::FakeBluetoothGattCharacteristicClient::kBodySensorLocationUUID);
53 const BluetoothUUID kHeartRateControlPointUUID(
54 bluez::FakeBluetoothGattCharacteristicClient::kHeartRateControlPointUUID);
55
56 // Compares GATT characteristic/descriptor values. Returns true, if the values
57 // are equal.
58 bool ValuesEqual(const std::vector<uint8_t>& value0,
59 const std::vector<uint8_t>& value1) {
60 if (value0.size() != value1.size())
61 return false;
62 for (size_t i = 0; i < value0.size(); ++i)
63 if (value0[i] != value1[i])
64 return false;
65 return true;
66 }
67
68 } // namespace
69
70 class BluetoothGattBlueZTest : public testing::Test {
71 public:
72 BluetoothGattBlueZTest()
73 : fake_bluetooth_gatt_service_client_(NULL),
74 success_callback_count_(0),
75 error_callback_count_(0) {}
76
77 void SetUp() override {
78 std::unique_ptr<bluez::BluezDBusManagerSetter> dbus_setter =
79 bluez::BluezDBusManager::GetSetterForTesting();
80 fake_bluetooth_device_client_ = new bluez::FakeBluetoothDeviceClient;
81 fake_bluetooth_gatt_service_client_ =
82 new bluez::FakeBluetoothGattServiceClient;
83 fake_bluetooth_gatt_characteristic_client_ =
84 new bluez::FakeBluetoothGattCharacteristicClient;
85 fake_bluetooth_gatt_descriptor_client_ =
86 new bluez::FakeBluetoothGattDescriptorClient;
87 dbus_setter->SetBluetoothDeviceClient(
88 std::unique_ptr<bluez::BluetoothDeviceClient>(
89 fake_bluetooth_device_client_));
90 dbus_setter->SetBluetoothGattServiceClient(
91 std::unique_ptr<bluez::BluetoothGattServiceClient>(
92 fake_bluetooth_gatt_service_client_));
93 dbus_setter->SetBluetoothGattCharacteristicClient(
94 std::unique_ptr<bluez::BluetoothGattCharacteristicClient>(
95 fake_bluetooth_gatt_characteristic_client_));
96 dbus_setter->SetBluetoothGattDescriptorClient(
97 std::unique_ptr<bluez::BluetoothGattDescriptorClient>(
98 fake_bluetooth_gatt_descriptor_client_));
99 dbus_setter->SetBluetoothAdapterClient(
100 std::unique_ptr<bluez::BluetoothAdapterClient>(
101 new bluez::FakeBluetoothAdapterClient));
102 dbus_setter->SetBluetoothInputClient(
103 std::unique_ptr<bluez::BluetoothInputClient>(
104 new bluez::FakeBluetoothInputClient));
105 dbus_setter->SetBluetoothAgentManagerClient(
106 std::unique_ptr<bluez::BluetoothAgentManagerClient>(
107 new bluez::FakeBluetoothAgentManagerClient));
108
109 GetAdapter();
110
111 adapter_->SetPowered(true, base::Bind(&base::DoNothing),
112 base::Bind(&base::DoNothing));
113 ASSERT_TRUE(adapter_->IsPowered());
114 }
115
116 void TearDown() override {
117 adapter_ = NULL;
118 update_sessions_.clear();
119 gatt_conn_.reset();
120 bluez::BluezDBusManager::Shutdown();
121 }
122
123 void GetAdapter() {
124 device::BluetoothAdapterFactory::GetAdapter(base::Bind(
125 &BluetoothGattBlueZTest::AdapterCallback, base::Unretained(this)));
126 base::MessageLoop::current()->Run();
127 ASSERT_TRUE(adapter_.get() != NULL);
128 ASSERT_TRUE(adapter_->IsInitialized());
129 ASSERT_TRUE(adapter_->IsPresent());
130 }
131
132 void AdapterCallback(scoped_refptr<BluetoothAdapter> adapter) {
133 adapter_ = adapter;
134 if (base::MessageLoop::current() &&
135 base::MessageLoop::current()->is_running()) {
136 base::MessageLoop::current()->QuitWhenIdle();
137 }
138 }
139
140 void SuccessCallback() { ++success_callback_count_; }
141
142 void ValueCallback(const std::vector<uint8_t>& value) {
143 ++success_callback_count_;
144 last_read_value_ = value;
145 }
146
147 void GattConnectionCallback(std::unique_ptr<BluetoothGattConnection> conn) {
148 ++success_callback_count_;
149 gatt_conn_ = std::move(conn);
150 }
151
152 void NotifySessionCallback(
153 std::unique_ptr<BluetoothGattNotifySession> session) {
154 ++success_callback_count_;
155 update_sessions_.push_back(session.release());
156 QuitMessageLoop();
157 }
158
159 void ServiceErrorCallback(BluetoothGattService::GattErrorCode err) {
160 ++error_callback_count_;
161 last_service_error_ = err;
162 }
163
164 void ErrorCallback() { ++error_callback_count_; }
165
166 void DBusErrorCallback(const std::string& error_name,
167 const std::string& error_message) {
168 ++error_callback_count_;
169 }
170
171 void ConnectErrorCallback(BluetoothDevice::ConnectErrorCode error) {
172 ++error_callback_count_;
173 }
174
175 protected:
176 void QuitMessageLoop() {
177 if (base::MessageLoop::current() &&
178 base::MessageLoop::current()->is_running())
179 base::MessageLoop::current()->QuitWhenIdle();
180 }
181
182 base::MessageLoop message_loop_;
183
184 bluez::FakeBluetoothDeviceClient* fake_bluetooth_device_client_;
185 bluez::FakeBluetoothGattServiceClient* fake_bluetooth_gatt_service_client_;
186 bluez::FakeBluetoothGattCharacteristicClient*
187 fake_bluetooth_gatt_characteristic_client_;
188 bluez::FakeBluetoothGattDescriptorClient*
189 fake_bluetooth_gatt_descriptor_client_;
190 std::unique_ptr<device::BluetoothGattConnection> gatt_conn_;
191 ScopedVector<BluetoothGattNotifySession> update_sessions_;
192 scoped_refptr<BluetoothAdapter> adapter_;
193
194 int success_callback_count_;
195 int error_callback_count_;
196 std::vector<uint8_t> last_read_value_;
197 BluetoothGattService::GattErrorCode last_service_error_;
198 };
199
200 TEST_F(BluetoothGattBlueZTest, GattConnection) {
201 fake_bluetooth_device_client_->CreateDevice(
202 dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
203 dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
204 BluetoothDevice* device =
205 adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress);
206 ASSERT_TRUE(device);
207 ASSERT_FALSE(device->IsConnected());
208 ASSERT_FALSE(gatt_conn_.get());
209 ASSERT_EQ(0, success_callback_count_);
210 ASSERT_EQ(0, error_callback_count_);
211
212 device->CreateGattConnection(
213 base::Bind(&BluetoothGattBlueZTest::GattConnectionCallback,
214 base::Unretained(this)),
215 base::Bind(&BluetoothGattBlueZTest::ConnectErrorCallback,
216 base::Unretained(this)));
217
218 EXPECT_EQ(1, success_callback_count_);
219 EXPECT_EQ(0, error_callback_count_);
220 EXPECT_TRUE(device->IsConnected());
221 ASSERT_TRUE(gatt_conn_.get());
222 EXPECT_TRUE(gatt_conn_->IsConnected());
223 EXPECT_EQ(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress,
224 gatt_conn_->GetDeviceAddress());
225
226 gatt_conn_->Disconnect();
227 EXPECT_FALSE(device->IsConnected());
228 EXPECT_FALSE(gatt_conn_->IsConnected());
229
230 device->CreateGattConnection(
231 base::Bind(&BluetoothGattBlueZTest::GattConnectionCallback,
232 base::Unretained(this)),
233 base::Bind(&BluetoothGattBlueZTest::ConnectErrorCallback,
234 base::Unretained(this)));
235
236 EXPECT_EQ(2, success_callback_count_);
237 EXPECT_EQ(0, error_callback_count_);
238 EXPECT_TRUE(device->IsConnected());
239 ASSERT_TRUE(gatt_conn_.get());
240 EXPECT_TRUE(gatt_conn_->IsConnected());
241
242 device->Disconnect(base::Bind(&BluetoothGattBlueZTest::SuccessCallback,
243 base::Unretained(this)),
244 base::Bind(&BluetoothGattBlueZTest::ErrorCallback,
245 base::Unretained(this)));
246
247 EXPECT_EQ(3, success_callback_count_);
248 EXPECT_EQ(0, error_callback_count_);
249 EXPECT_FALSE(device->IsConnected());
250 ASSERT_TRUE(gatt_conn_.get());
251 EXPECT_FALSE(gatt_conn_->IsConnected());
252
253 device->CreateGattConnection(
254 base::Bind(&BluetoothGattBlueZTest::GattConnectionCallback,
255 base::Unretained(this)),
256 base::Bind(&BluetoothGattBlueZTest::ConnectErrorCallback,
257 base::Unretained(this)));
258
259 EXPECT_EQ(4, success_callback_count_);
260 EXPECT_EQ(0, error_callback_count_);
261 EXPECT_TRUE(device->IsConnected());
262 EXPECT_TRUE(gatt_conn_->IsConnected());
263
264 fake_bluetooth_device_client_->RemoveDevice(
265 dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
266 dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
267 ASSERT_TRUE(gatt_conn_.get());
268 EXPECT_FALSE(gatt_conn_->IsConnected());
269 }
270
271 TEST_F(BluetoothGattBlueZTest, GattServiceAddedAndRemoved) {
272 // Create a fake LE device. We store the device pointer here because this is a
273 // test. It's unsafe to do this in production as the device might get deleted.
274 fake_bluetooth_device_client_->CreateDevice(
275 dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
276 dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
277 BluetoothDevice* device =
278 adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress);
279 ASSERT_TRUE(device);
280
281 TestBluetoothAdapterObserver observer(adapter_);
282
283 EXPECT_EQ(0, observer.gatt_service_added_count());
284 EXPECT_EQ(0, observer.gatt_service_removed_count());
285 EXPECT_TRUE(observer.last_gatt_service_id().empty());
286 EXPECT_FALSE(observer.last_gatt_service_uuid().IsValid());
287 EXPECT_TRUE(device->GetGattServices().empty());
288
289 // Expose the fake Heart Rate Service.
290 fake_bluetooth_gatt_service_client_->ExposeHeartRateService(
291 dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
292 EXPECT_EQ(1, observer.gatt_service_added_count());
293 EXPECT_EQ(0, observer.gatt_service_removed_count());
294 EXPECT_FALSE(observer.last_gatt_service_id().empty());
295 EXPECT_EQ(1U, device->GetGattServices().size());
296 EXPECT_EQ(BluetoothUUID(
297 bluez::FakeBluetoothGattServiceClient::kHeartRateServiceUUID),
298 observer.last_gatt_service_uuid());
299
300 BluetoothGattService* service =
301 device->GetGattService(observer.last_gatt_service_id());
302 EXPECT_FALSE(service->IsLocal());
303 EXPECT_TRUE(service->IsPrimary());
304 EXPECT_EQ(service, device->GetGattServices()[0]);
305 EXPECT_EQ(service, device->GetGattService(service->GetIdentifier()));
306
307 EXPECT_EQ(observer.last_gatt_service_uuid(), service->GetUUID());
308
309 // Hide the service.
310 observer.last_gatt_service_uuid() = BluetoothUUID();
311 observer.last_gatt_service_id().clear();
312 fake_bluetooth_gatt_service_client_->HideHeartRateService();
313
314 EXPECT_EQ(1, observer.gatt_service_added_count());
315 EXPECT_EQ(1, observer.gatt_service_removed_count());
316 EXPECT_FALSE(observer.last_gatt_service_id().empty());
317 EXPECT_TRUE(device->GetGattServices().empty());
318 EXPECT_EQ(BluetoothUUID(
319 bluez::FakeBluetoothGattServiceClient::kHeartRateServiceUUID),
320 observer.last_gatt_service_uuid());
321
322 EXPECT_EQ(NULL, device->GetGattService(observer.last_gatt_service_id()));
323
324 // Expose the service again.
325 observer.last_gatt_service_uuid() = BluetoothUUID();
326 observer.last_gatt_service_id().clear();
327 fake_bluetooth_gatt_service_client_->ExposeHeartRateService(
328 dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
329 EXPECT_EQ(2, observer.gatt_service_added_count());
330 EXPECT_EQ(1, observer.gatt_service_removed_count());
331 EXPECT_FALSE(observer.last_gatt_service_id().empty());
332 EXPECT_EQ(1U, device->GetGattServices().size());
333 EXPECT_EQ(BluetoothUUID(
334 bluez::FakeBluetoothGattServiceClient::kHeartRateServiceUUID),
335 observer.last_gatt_service_uuid());
336
337 // The object |service| points to should have been deallocated. |device|
338 // should contain a brand new instance.
339 service = device->GetGattService(observer.last_gatt_service_id());
340 EXPECT_EQ(service, device->GetGattServices()[0]);
341 EXPECT_FALSE(service->IsLocal());
342 EXPECT_TRUE(service->IsPrimary());
343
344 EXPECT_EQ(observer.last_gatt_service_uuid(), service->GetUUID());
345
346 // Remove the device. The observer should be notified of the removed service.
347 // |device| becomes invalid after this.
348 observer.last_gatt_service_uuid() = BluetoothUUID();
349 observer.last_gatt_service_id().clear();
350 fake_bluetooth_device_client_->RemoveDevice(
351 dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
352 dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
353
354 EXPECT_EQ(2, observer.gatt_service_added_count());
355 EXPECT_EQ(2, observer.gatt_service_removed_count());
356 EXPECT_FALSE(observer.last_gatt_service_id().empty());
357 EXPECT_EQ(BluetoothUUID(
358 bluez::FakeBluetoothGattServiceClient::kHeartRateServiceUUID),
359 observer.last_gatt_service_uuid());
360 EXPECT_EQ(NULL, adapter_->GetDevice(
361 bluez::FakeBluetoothDeviceClient::kLowEnergyAddress));
362 }
363
364 TEST_F(BluetoothGattBlueZTest, ServicesDiscovered) {
365 // Create a fake LE device. We store the device pointer here because this is a
366 // test. It's unsafe to do this in production as the device might get deleted.
367 fake_bluetooth_device_client_->CreateDevice(
368 dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
369 dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
370 BluetoothDevice* device =
371 adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress);
372 bluez::FakeBluetoothDeviceClient::Properties* properties =
373 fake_bluetooth_device_client_->GetProperties(
374 dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
375
376 ASSERT_TRUE(device);
377
378 TestBluetoothAdapterObserver observer(adapter_);
379
380 EXPECT_EQ(0, observer.gatt_services_discovered_count());
381
382 // Expose the fake Heart Rate Service.
383 fake_bluetooth_gatt_service_client_->ExposeHeartRateService(
384 dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
385 // Notify that all services have been discovered.
386 properties->gatt_services.ReplaceValue(
387 fake_bluetooth_gatt_service_client_->GetServices());
388
389 EXPECT_TRUE(device->IsGattServicesDiscoveryComplete());
390 EXPECT_EQ(1u, device->GetGattServices().size());
391 EXPECT_EQ(1, observer.gatt_services_discovered_count());
392 EXPECT_EQ(device, observer.last_device());
393 EXPECT_EQ(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress,
394 observer.last_device_address());
395
396 // Disconnect from the device:
397 device->Disconnect(base::Bind(&BluetoothGattBlueZTest::SuccessCallback,
398 base::Unretained(this)),
399 base::Bind(&BluetoothGattBlueZTest::ErrorCallback,
400 base::Unretained(this)));
401 fake_bluetooth_gatt_service_client_->HideHeartRateService();
402 properties->connected.ReplaceValue(false);
403
404 EXPECT_FALSE(device->IsConnected());
405 EXPECT_FALSE(device->IsGattServicesDiscoveryComplete());
406 EXPECT_EQ(0u, device->GetGattServices().size());
407
408 // Verify that the device can be connected to again:
409 device->CreateGattConnection(
410 base::Bind(&BluetoothGattBlueZTest::GattConnectionCallback,
411 base::Unretained(this)),
412 base::Bind(&BluetoothGattBlueZTest::ConnectErrorCallback,
413 base::Unretained(this)));
414 properties->connected.ReplaceValue(true);
415 EXPECT_TRUE(device->IsConnected());
416
417 // Verify that service discovery can be done again:
418 fake_bluetooth_gatt_service_client_->ExposeHeartRateService(
419 dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
420 properties->gatt_services.ReplaceValue(
421 fake_bluetooth_gatt_service_client_->GetServices());
422 EXPECT_TRUE(device->IsGattServicesDiscoveryComplete());
423 EXPECT_EQ(1u, device->GetGattServices().size());
424 }
425
426 TEST_F(BluetoothGattBlueZTest, GattCharacteristicAddedAndRemoved) {
427 fake_bluetooth_device_client_->CreateDevice(
428 dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
429 dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
430 BluetoothDevice* device =
431 adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress);
432 ASSERT_TRUE(device);
433
434 TestBluetoothAdapterObserver observer(adapter_);
435
436 // Expose the fake Heart Rate service. This will asynchronously expose
437 // characteristics.
438 fake_bluetooth_gatt_service_client_->ExposeHeartRateService(
439 dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
440 ASSERT_EQ(1, observer.gatt_service_added_count());
441
442 BluetoothGattService* service =
443 device->GetGattService(observer.last_gatt_service_id());
444
445 EXPECT_EQ(0, observer.gatt_service_changed_count());
446 EXPECT_EQ(0, observer.gatt_discovery_complete_count());
447 EXPECT_EQ(0, observer.gatt_characteristic_added_count());
448 EXPECT_EQ(0, observer.gatt_characteristic_removed_count());
449 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count());
450 EXPECT_TRUE(service->GetCharacteristics().empty());
451
452 // Run the message loop so that the characteristics appear.
453 base::MessageLoop::current()->Run();
454
455 // 3 characteristics should appear. Only 1 of the characteristics sends
456 // value changed signals. Service changed should be fired once for
457 // descriptor added.
458 EXPECT_EQ(0, observer.gatt_service_changed_count());
459 EXPECT_EQ(1, observer.gatt_discovery_complete_count());
460 EXPECT_EQ(3, observer.gatt_characteristic_added_count());
461 EXPECT_EQ(0, observer.gatt_characteristic_removed_count());
462 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count());
463 EXPECT_EQ(3U, service->GetCharacteristics().size());
464
465 // Hide the characteristics. 3 removed signals should be received.
466 fake_bluetooth_gatt_characteristic_client_->HideHeartRateCharacteristics();
467 EXPECT_EQ(0, observer.gatt_service_changed_count());
468 EXPECT_EQ(3, observer.gatt_characteristic_added_count());
469 EXPECT_EQ(3, observer.gatt_characteristic_removed_count());
470 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count());
471 EXPECT_TRUE(service->GetCharacteristics().empty());
472
473 // Re-expose the heart rate characteristics. We shouldn't get another
474 // GattDiscoveryCompleteForService call, since the service thinks that
475 // discovery is done. On the bluetoothd side, characteristics will be removed
476 // only if the service will also be subsequently removed.
477 fake_bluetooth_gatt_characteristic_client_->ExposeHeartRateCharacteristics(
478 fake_bluetooth_gatt_service_client_->GetHeartRateServicePath());
479 EXPECT_EQ(0, observer.gatt_service_changed_count());
480 EXPECT_EQ(1, observer.gatt_discovery_complete_count());
481 EXPECT_EQ(6, observer.gatt_characteristic_added_count());
482 EXPECT_EQ(3, observer.gatt_characteristic_removed_count());
483 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count());
484 EXPECT_EQ(3U, service->GetCharacteristics().size());
485
486 // Hide the service. All characteristics should disappear.
487 fake_bluetooth_gatt_service_client_->HideHeartRateService();
488 EXPECT_EQ(0, observer.gatt_service_changed_count());
489 EXPECT_EQ(6, observer.gatt_characteristic_added_count());
490 EXPECT_EQ(6, observer.gatt_characteristic_removed_count());
491 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count());
492 }
493
494 TEST_F(BluetoothGattBlueZTest, GattDescriptorAddedAndRemoved) {
495 fake_bluetooth_device_client_->CreateDevice(
496 dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
497 dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
498 BluetoothDevice* device =
499 adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress);
500 ASSERT_TRUE(device);
501
502 TestBluetoothAdapterObserver observer(adapter_);
503
504 // Expose the fake Heart Rate service. This will asynchronously expose
505 // characteristics.
506 fake_bluetooth_gatt_service_client_->ExposeHeartRateService(
507 dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
508 ASSERT_EQ(1, observer.gatt_service_added_count());
509
510 BluetoothGattService* service =
511 device->GetGattService(observer.last_gatt_service_id());
512
513 EXPECT_EQ(0, observer.gatt_service_changed_count());
514 EXPECT_EQ(0, observer.gatt_descriptor_added_count());
515 EXPECT_EQ(0, observer.gatt_descriptor_removed_count());
516 EXPECT_EQ(0, observer.gatt_descriptor_value_changed_count());
517
518 EXPECT_TRUE(service->GetCharacteristics().empty());
519
520 // Run the message loop so that the characteristics appear.
521 base::MessageLoop::current()->Run();
522 EXPECT_EQ(0, observer.gatt_service_changed_count());
523
524 // Only the Heart Rate Measurement characteristic has a descriptor.
525 EXPECT_EQ(1, observer.gatt_descriptor_added_count());
526 EXPECT_EQ(0, observer.gatt_descriptor_removed_count());
527 EXPECT_EQ(0, observer.gatt_descriptor_value_changed_count());
528
529 BluetoothGattCharacteristic* characteristic = service->GetCharacteristic(
530 fake_bluetooth_gatt_characteristic_client_->GetBodySensorLocationPath()
531 .value());
532 ASSERT_TRUE(characteristic);
533 EXPECT_TRUE(characteristic->GetDescriptors().empty());
534
535 characteristic = service->GetCharacteristic(
536 fake_bluetooth_gatt_characteristic_client_->GetHeartRateControlPointPath()
537 .value());
538 ASSERT_TRUE(characteristic);
539 EXPECT_TRUE(characteristic->GetDescriptors().empty());
540
541 characteristic = service->GetCharacteristic(
542 fake_bluetooth_gatt_characteristic_client_->GetHeartRateMeasurementPath()
543 .value());
544 ASSERT_TRUE(characteristic);
545 EXPECT_EQ(1U, characteristic->GetDescriptors().size());
546
547 BluetoothGattDescriptor* descriptor = characteristic->GetDescriptors()[0];
548 EXPECT_FALSE(descriptor->IsLocal());
549 EXPECT_EQ(BluetoothGattDescriptor::ClientCharacteristicConfigurationUuid(),
550 descriptor->GetUUID());
551 EXPECT_EQ(descriptor->GetUUID(), observer.last_gatt_descriptor_uuid());
552 EXPECT_EQ(descriptor->GetIdentifier(), observer.last_gatt_descriptor_id());
553
554 // Hide the descriptor.
555 fake_bluetooth_gatt_descriptor_client_->HideDescriptor(
556 dbus::ObjectPath(descriptor->GetIdentifier()));
557 EXPECT_TRUE(characteristic->GetDescriptors().empty());
558 EXPECT_EQ(0, observer.gatt_service_changed_count());
559 EXPECT_EQ(1, observer.gatt_descriptor_added_count());
560 EXPECT_EQ(1, observer.gatt_descriptor_removed_count());
561 EXPECT_EQ(0, observer.gatt_descriptor_value_changed_count());
562
563 // Expose the descriptor again.
564 observer.last_gatt_descriptor_id().clear();
565 observer.last_gatt_descriptor_uuid() = BluetoothUUID();
566 fake_bluetooth_gatt_descriptor_client_->ExposeDescriptor(
567 dbus::ObjectPath(characteristic->GetIdentifier()),
568 bluez::FakeBluetoothGattDescriptorClient::
569 kClientCharacteristicConfigurationUUID);
570 EXPECT_EQ(0, observer.gatt_service_changed_count());
571 EXPECT_EQ(1U, characteristic->GetDescriptors().size());
572 EXPECT_EQ(2, observer.gatt_descriptor_added_count());
573 EXPECT_EQ(1, observer.gatt_descriptor_removed_count());
574 EXPECT_EQ(0, observer.gatt_descriptor_value_changed_count());
575
576 descriptor = characteristic->GetDescriptors()[0];
577 EXPECT_FALSE(descriptor->IsLocal());
578 EXPECT_EQ(BluetoothGattDescriptor::ClientCharacteristicConfigurationUuid(),
579 descriptor->GetUUID());
580 EXPECT_EQ(descriptor->GetUUID(), observer.last_gatt_descriptor_uuid());
581 EXPECT_EQ(descriptor->GetIdentifier(), observer.last_gatt_descriptor_id());
582 }
583
584 TEST_F(BluetoothGattBlueZTest, AdapterAddedAfterGattService) {
585 // This unit test tests that all remote GATT objects are created for D-Bus
586 // objects that were already exposed.
587 adapter_ = NULL;
588 ASSERT_FALSE(device::BluetoothAdapterFactory::HasSharedInstanceForTesting());
589
590 // Create the fake D-Bus objects.
591 fake_bluetooth_device_client_->CreateDevice(
592 dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
593 dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
594 fake_bluetooth_gatt_service_client_->ExposeHeartRateService(
595 dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
596 while (!fake_bluetooth_gatt_characteristic_client_->IsHeartRateVisible())
597 base::RunLoop().RunUntilIdle();
598 ASSERT_TRUE(fake_bluetooth_gatt_service_client_->IsHeartRateVisible());
599 ASSERT_TRUE(fake_bluetooth_gatt_characteristic_client_->IsHeartRateVisible());
600
601 // Create the adapter. This should create all the GATT objects.
602 GetAdapter();
603 BluetoothDevice* device =
604 adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress);
605 ASSERT_TRUE(device);
606 EXPECT_EQ(1U, device->GetGattServices().size());
607
608 BluetoothGattService* service = device->GetGattServices()[0];
609 ASSERT_TRUE(service);
610 EXPECT_FALSE(service->IsLocal());
611 EXPECT_TRUE(service->IsPrimary());
612 EXPECT_EQ(BluetoothUUID(
613 bluez::FakeBluetoothGattServiceClient::kHeartRateServiceUUID),
614 service->GetUUID());
615 EXPECT_EQ(service, device->GetGattServices()[0]);
616 EXPECT_EQ(service, device->GetGattService(service->GetIdentifier()));
617 EXPECT_FALSE(service->IsLocal());
618 EXPECT_EQ(3U, service->GetCharacteristics().size());
619
620 BluetoothGattCharacteristic* characteristic = service->GetCharacteristic(
621 fake_bluetooth_gatt_characteristic_client_->GetBodySensorLocationPath()
622 .value());
623 ASSERT_TRUE(characteristic);
624 EXPECT_EQ(BluetoothUUID(bluez::FakeBluetoothGattCharacteristicClient::
625 kBodySensorLocationUUID),
626 characteristic->GetUUID());
627 EXPECT_FALSE(characteristic->IsLocal());
628 EXPECT_TRUE(characteristic->GetDescriptors().empty());
629
630 characteristic = service->GetCharacteristic(
631 fake_bluetooth_gatt_characteristic_client_->GetHeartRateControlPointPath()
632 .value());
633 ASSERT_TRUE(characteristic);
634 EXPECT_EQ(BluetoothUUID(bluez::FakeBluetoothGattCharacteristicClient::
635 kHeartRateControlPointUUID),
636 characteristic->GetUUID());
637 EXPECT_FALSE(characteristic->IsLocal());
638 EXPECT_TRUE(characteristic->GetDescriptors().empty());
639
640 characteristic = service->GetCharacteristic(
641 fake_bluetooth_gatt_characteristic_client_->GetHeartRateMeasurementPath()
642 .value());
643 ASSERT_TRUE(characteristic);
644 EXPECT_EQ(BluetoothUUID(bluez::FakeBluetoothGattCharacteristicClient::
645 kHeartRateMeasurementUUID),
646 characteristic->GetUUID());
647 EXPECT_FALSE(characteristic->IsLocal());
648 EXPECT_EQ(1U, characteristic->GetDescriptors().size());
649
650 BluetoothGattDescriptor* descriptor = characteristic->GetDescriptors()[0];
651 ASSERT_TRUE(descriptor);
652 EXPECT_EQ(BluetoothGattDescriptor::ClientCharacteristicConfigurationUuid(),
653 descriptor->GetUUID());
654 EXPECT_FALSE(descriptor->IsLocal());
655 }
656
657 TEST_F(BluetoothGattBlueZTest, GattCharacteristicValue) {
658 fake_bluetooth_device_client_->CreateDevice(
659 dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
660 dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
661 BluetoothDevice* device =
662 adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress);
663 ASSERT_TRUE(device);
664
665 TestBluetoothAdapterObserver observer(adapter_);
666
667 // Expose the fake Heart Rate service. This will asynchronously expose
668 // characteristics.
669 fake_bluetooth_gatt_service_client_->ExposeHeartRateService(
670 dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
671 ASSERT_EQ(1, observer.gatt_service_added_count());
672
673 BluetoothGattService* service =
674 device->GetGattService(observer.last_gatt_service_id());
675
676 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count());
677
678 // Run the message loop so that the characteristics appear.
679 base::MessageLoop::current()->Run();
680
681 // Issue write request to non-writable characteristics.
682 observer.Reset();
683
684 std::vector<uint8_t> write_value;
685 write_value.push_back(0x01);
686 BluetoothGattCharacteristic* characteristic = service->GetCharacteristic(
687 fake_bluetooth_gatt_characteristic_client_->GetHeartRateMeasurementPath()
688 .value());
689 ASSERT_TRUE(characteristic);
690 EXPECT_FALSE(characteristic->IsNotifying());
691 EXPECT_EQ(
692 fake_bluetooth_gatt_characteristic_client_->GetHeartRateMeasurementPath()
693 .value(),
694 characteristic->GetIdentifier());
695 EXPECT_EQ(kHeartRateMeasurementUUID, characteristic->GetUUID());
696 characteristic->WriteRemoteCharacteristic(
697 write_value, base::Bind(&BluetoothGattBlueZTest::SuccessCallback,
698 base::Unretained(this)),
699 base::Bind(&BluetoothGattBlueZTest::ServiceErrorCallback,
700 base::Unretained(this)));
701 EXPECT_TRUE(observer.last_gatt_characteristic_id().empty());
702 EXPECT_FALSE(observer.last_gatt_characteristic_uuid().IsValid());
703 EXPECT_EQ(0, success_callback_count_);
704 EXPECT_EQ(1, error_callback_count_);
705 EXPECT_EQ(BluetoothGattService::GATT_ERROR_NOT_SUPPORTED,
706 last_service_error_);
707 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count());
708
709 characteristic = service->GetCharacteristic(
710 fake_bluetooth_gatt_characteristic_client_->GetBodySensorLocationPath()
711 .value());
712 ASSERT_TRUE(characteristic);
713 EXPECT_EQ(
714 fake_bluetooth_gatt_characteristic_client_->GetBodySensorLocationPath()
715 .value(),
716 characteristic->GetIdentifier());
717 EXPECT_EQ(kBodySensorLocationUUID, characteristic->GetUUID());
718 characteristic->WriteRemoteCharacteristic(
719 write_value, base::Bind(&BluetoothGattBlueZTest::SuccessCallback,
720 base::Unretained(this)),
721 base::Bind(&BluetoothGattBlueZTest::ServiceErrorCallback,
722 base::Unretained(this)));
723 EXPECT_TRUE(observer.last_gatt_characteristic_id().empty());
724 EXPECT_FALSE(observer.last_gatt_characteristic_uuid().IsValid());
725 EXPECT_EQ(0, success_callback_count_);
726 EXPECT_EQ(2, error_callback_count_);
727 EXPECT_EQ(BluetoothGattService::GATT_ERROR_NOT_PERMITTED,
728 last_service_error_);
729 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count());
730
731 // Issue write request to writable characteristic. The "Body Sensor Location"
732 // characteristic does not send notifications and WriteValue does not result
733 // in a CharacteristicValueChanged event, thus no such event should be
734 // received.
735 characteristic = service->GetCharacteristic(
736 fake_bluetooth_gatt_characteristic_client_->GetHeartRateControlPointPath()
737 .value());
738 ASSERT_TRUE(characteristic);
739 EXPECT_EQ(
740 fake_bluetooth_gatt_characteristic_client_->GetHeartRateControlPointPath()
741 .value(),
742 characteristic->GetIdentifier());
743 EXPECT_EQ(kHeartRateControlPointUUID, characteristic->GetUUID());
744 characteristic->WriteRemoteCharacteristic(
745 write_value, base::Bind(&BluetoothGattBlueZTest::SuccessCallback,
746 base::Unretained(this)),
747 base::Bind(&BluetoothGattBlueZTest::ServiceErrorCallback,
748 base::Unretained(this)));
749 EXPECT_TRUE(observer.last_gatt_characteristic_id().empty());
750 EXPECT_FALSE(observer.last_gatt_characteristic_uuid().IsValid());
751 EXPECT_EQ(1, success_callback_count_);
752 EXPECT_EQ(2, error_callback_count_);
753 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count());
754
755 // Issue some invalid write requests to the characteristic.
756 // The value should still not change.
757
758 std::vector<uint8_t> invalid_write_length;
759 invalid_write_length.push_back(0x01);
760 invalid_write_length.push_back(0x00);
761 characteristic->WriteRemoteCharacteristic(
762 invalid_write_length, base::Bind(&BluetoothGattBlueZTest::SuccessCallback,
763 base::Unretained(this)),
764 base::Bind(&BluetoothGattBlueZTest::ServiceErrorCallback,
765 base::Unretained(this)));
766 EXPECT_EQ(1, success_callback_count_);
767 EXPECT_EQ(3, error_callback_count_);
768 EXPECT_EQ(BluetoothGattService::GATT_ERROR_INVALID_LENGTH,
769 last_service_error_);
770 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count());
771
772 std::vector<uint8_t> invalid_write_value;
773 invalid_write_value.push_back(0x02);
774 characteristic->WriteRemoteCharacteristic(
775 invalid_write_value, base::Bind(&BluetoothGattBlueZTest::SuccessCallback,
776 base::Unretained(this)),
777 base::Bind(&BluetoothGattBlueZTest::ServiceErrorCallback,
778 base::Unretained(this)));
779 EXPECT_EQ(1, success_callback_count_);
780 EXPECT_EQ(4, error_callback_count_);
781 EXPECT_EQ(BluetoothGattService::GATT_ERROR_FAILED, last_service_error_);
782 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count());
783
784 // Issue a read request. A successful read results in a
785 // CharacteristicValueChanged notification.
786 characteristic = service->GetCharacteristic(
787 fake_bluetooth_gatt_characteristic_client_->GetBodySensorLocationPath()
788 .value());
789 ASSERT_TRUE(characteristic);
790 EXPECT_EQ(
791 fake_bluetooth_gatt_characteristic_client_->GetBodySensorLocationPath()
792 .value(),
793 characteristic->GetIdentifier());
794 EXPECT_EQ(kBodySensorLocationUUID, characteristic->GetUUID());
795 characteristic->ReadRemoteCharacteristic(
796 base::Bind(&BluetoothGattBlueZTest::ValueCallback,
797 base::Unretained(this)),
798 base::Bind(&BluetoothGattBlueZTest::ServiceErrorCallback,
799 base::Unretained(this)));
800 EXPECT_EQ(2, success_callback_count_);
801 EXPECT_EQ(4, error_callback_count_);
802 EXPECT_EQ(1, observer.gatt_characteristic_value_changed_count());
803 EXPECT_TRUE(ValuesEqual(characteristic->GetValue(), last_read_value_));
804
805 // Test long-running actions.
806 fake_bluetooth_gatt_characteristic_client_->SetExtraProcessing(1);
807 characteristic = service->GetCharacteristic(
808 fake_bluetooth_gatt_characteristic_client_->GetBodySensorLocationPath()
809 .value());
810 ASSERT_TRUE(characteristic);
811 EXPECT_EQ(
812 fake_bluetooth_gatt_characteristic_client_->GetBodySensorLocationPath()
813 .value(),
814 characteristic->GetIdentifier());
815 EXPECT_EQ(kBodySensorLocationUUID, characteristic->GetUUID());
816 characteristic->ReadRemoteCharacteristic(
817 base::Bind(&BluetoothGattBlueZTest::ValueCallback,
818 base::Unretained(this)),
819 base::Bind(&BluetoothGattBlueZTest::ServiceErrorCallback,
820 base::Unretained(this)));
821
822 // Callback counts shouldn't change, this one will be delayed until after
823 // tne next one.
824 EXPECT_EQ(2, success_callback_count_);
825 EXPECT_EQ(4, error_callback_count_);
826 EXPECT_EQ(1, observer.gatt_characteristic_value_changed_count());
827
828 // Next read should error because IN_PROGRESS
829 characteristic->ReadRemoteCharacteristic(
830 base::Bind(&BluetoothGattBlueZTest::ValueCallback,
831 base::Unretained(this)),
832 base::Bind(&BluetoothGattBlueZTest::ServiceErrorCallback,
833 base::Unretained(this)));
834 EXPECT_EQ(5, error_callback_count_);
835 EXPECT_EQ(BluetoothGattService::GATT_ERROR_IN_PROGRESS, last_service_error_);
836
837 // But previous call finished.
838 EXPECT_EQ(3, success_callback_count_);
839 EXPECT_EQ(2, observer.gatt_characteristic_value_changed_count());
840 EXPECT_TRUE(ValuesEqual(characteristic->GetValue(), last_read_value_));
841 fake_bluetooth_gatt_characteristic_client_->SetExtraProcessing(0);
842
843 // Test unauthorized actions.
844 fake_bluetooth_gatt_characteristic_client_->SetAuthorized(false);
845 characteristic->ReadRemoteCharacteristic(
846 base::Bind(&BluetoothGattBlueZTest::ValueCallback,
847 base::Unretained(this)),
848 base::Bind(&BluetoothGattBlueZTest::ServiceErrorCallback,
849 base::Unretained(this)));
850 EXPECT_EQ(3, success_callback_count_);
851 EXPECT_EQ(6, error_callback_count_);
852 EXPECT_EQ(BluetoothGattService::GATT_ERROR_NOT_AUTHORIZED,
853 last_service_error_);
854 EXPECT_EQ(2, observer.gatt_characteristic_value_changed_count());
855 fake_bluetooth_gatt_characteristic_client_->SetAuthorized(true);
856
857 // Test unauthenticated / needs login.
858 fake_bluetooth_gatt_characteristic_client_->SetAuthenticated(false);
859 characteristic->ReadRemoteCharacteristic(
860 base::Bind(&BluetoothGattBlueZTest::ValueCallback,
861 base::Unretained(this)),
862 base::Bind(&BluetoothGattBlueZTest::ServiceErrorCallback,
863 base::Unretained(this)));
864 EXPECT_EQ(3, success_callback_count_);
865 EXPECT_EQ(7, error_callback_count_);
866 EXPECT_EQ(BluetoothGattService::GATT_ERROR_NOT_PAIRED, last_service_error_);
867 EXPECT_EQ(2, observer.gatt_characteristic_value_changed_count());
868 fake_bluetooth_gatt_characteristic_client_->SetAuthenticated(true);
869 }
870
871 TEST_F(BluetoothGattBlueZTest, GattCharacteristicProperties) {
872 fake_bluetooth_device_client_->CreateDevice(
873 dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
874 dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
875 BluetoothDevice* device =
876 adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress);
877 ASSERT_TRUE(device);
878
879 TestBluetoothAdapterObserver observer(adapter_);
880
881 // Expose the fake Heart Rate service. This will asynchronously expose
882 // characteristics.
883 fake_bluetooth_gatt_service_client_->ExposeHeartRateService(
884 dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
885
886 BluetoothGattService* service =
887 device->GetGattService(observer.last_gatt_service_id());
888
889 EXPECT_TRUE(service->GetCharacteristics().empty());
890
891 // Run the message loop so that the characteristics appear.
892 base::MessageLoop::current()->Run();
893
894 BluetoothGattCharacteristic* characteristic = service->GetCharacteristic(
895 fake_bluetooth_gatt_characteristic_client_->GetBodySensorLocationPath()
896 .value());
897 EXPECT_EQ(BluetoothGattCharacteristic::PROPERTY_READ,
898 characteristic->GetProperties());
899
900 characteristic = service->GetCharacteristic(
901 fake_bluetooth_gatt_characteristic_client_->GetHeartRateControlPointPath()
902 .value());
903 EXPECT_EQ(BluetoothGattCharacteristic::PROPERTY_WRITE,
904 characteristic->GetProperties());
905
906 characteristic = service->GetCharacteristic(
907 fake_bluetooth_gatt_characteristic_client_->GetHeartRateMeasurementPath()
908 .value());
909 EXPECT_EQ(BluetoothGattCharacteristic::PROPERTY_NOTIFY,
910 characteristic->GetProperties());
911 }
912
913 TEST_F(BluetoothGattBlueZTest, GattDescriptorValue) {
914 fake_bluetooth_device_client_->CreateDevice(
915 dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
916 dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
917 BluetoothDevice* device =
918 adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress);
919 ASSERT_TRUE(device);
920
921 TestBluetoothAdapterObserver observer(adapter_);
922
923 // Expose the fake Heart Rate service. This will asynchronously expose
924 // characteristics.
925 fake_bluetooth_gatt_service_client_->ExposeHeartRateService(
926 dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
927 ASSERT_EQ(1, observer.gatt_service_added_count());
928
929 BluetoothGattService* service =
930 device->GetGattService(observer.last_gatt_service_id());
931
932 EXPECT_EQ(0, observer.gatt_service_changed_count());
933 EXPECT_EQ(0, observer.gatt_discovery_complete_count());
934 EXPECT_EQ(0, observer.gatt_descriptor_value_changed_count());
935 EXPECT_TRUE(service->GetCharacteristics().empty());
936
937 // Run the message loop so that the characteristics appear.
938 base::MessageLoop::current()->Run();
939 EXPECT_EQ(0, observer.gatt_service_changed_count());
940 EXPECT_EQ(1, observer.gatt_discovery_complete_count());
941
942 // Only the Heart Rate Measurement characteristic has a descriptor.
943 BluetoothGattCharacteristic* characteristic = service->GetCharacteristic(
944 fake_bluetooth_gatt_characteristic_client_->GetHeartRateMeasurementPath()
945 .value());
946 ASSERT_TRUE(characteristic);
947 EXPECT_EQ(1U, characteristic->GetDescriptors().size());
948 EXPECT_FALSE(characteristic->IsNotifying());
949
950 BluetoothGattDescriptor* descriptor = characteristic->GetDescriptors()[0];
951 EXPECT_FALSE(descriptor->IsLocal());
952 EXPECT_EQ(BluetoothGattDescriptor::ClientCharacteristicConfigurationUuid(),
953 descriptor->GetUUID());
954
955 std::vector<uint8_t> desc_value = {0x00, 0x00};
956
957 /* The cached value will be empty until the first read request */
958 EXPECT_FALSE(ValuesEqual(desc_value, descriptor->GetValue()));
959 EXPECT_TRUE(descriptor->GetValue().empty());
960
961 EXPECT_EQ(0, success_callback_count_);
962 EXPECT_EQ(0, error_callback_count_);
963 EXPECT_TRUE(last_read_value_.empty());
964
965 // Read value. GattDescriptorValueChanged event will be sent after a
966 // successful read.
967 descriptor->ReadRemoteDescriptor(
968 base::Bind(&BluetoothGattBlueZTest::ValueCallback,
969 base::Unretained(this)),
970 base::Bind(&BluetoothGattBlueZTest::ServiceErrorCallback,
971 base::Unretained(this)));
972 EXPECT_EQ(1, success_callback_count_);
973 EXPECT_EQ(0, error_callback_count_);
974 EXPECT_TRUE(ValuesEqual(last_read_value_, descriptor->GetValue()));
975 EXPECT_TRUE(ValuesEqual(desc_value, descriptor->GetValue()));
976 EXPECT_EQ(0, observer.gatt_service_changed_count());
977 EXPECT_EQ(1, observer.gatt_descriptor_value_changed_count());
978
979 // Write value. Writes to this descriptor will fail.
980 desc_value[0] = 0x03;
981 descriptor->WriteRemoteDescriptor(
982 desc_value, base::Bind(&BluetoothGattBlueZTest::SuccessCallback,
983 base::Unretained(this)),
984 base::Bind(&BluetoothGattBlueZTest::ServiceErrorCallback,
985 base::Unretained(this)));
986 EXPECT_EQ(1, success_callback_count_);
987 EXPECT_EQ(1, error_callback_count_);
988 EXPECT_EQ(BluetoothGattService::GATT_ERROR_NOT_PERMITTED,
989 last_service_error_);
990 EXPECT_TRUE(ValuesEqual(last_read_value_, descriptor->GetValue()));
991 EXPECT_FALSE(ValuesEqual(desc_value, descriptor->GetValue()));
992 EXPECT_EQ(0, observer.gatt_service_changed_count());
993 EXPECT_EQ(1, observer.gatt_descriptor_value_changed_count());
994
995 // Read value. The value should remain unchanged.
996 descriptor->ReadRemoteDescriptor(
997 base::Bind(&BluetoothGattBlueZTest::ValueCallback,
998 base::Unretained(this)),
999 base::Bind(&BluetoothGattBlueZTest::ServiceErrorCallback,
1000 base::Unretained(this)));
1001 EXPECT_EQ(2, success_callback_count_);
1002 EXPECT_EQ(1, error_callback_count_);
1003 EXPECT_TRUE(ValuesEqual(last_read_value_, descriptor->GetValue()));
1004 EXPECT_FALSE(ValuesEqual(desc_value, descriptor->GetValue()));
1005 EXPECT_EQ(0, observer.gatt_service_changed_count());
1006 EXPECT_EQ(1, observer.gatt_descriptor_value_changed_count());
1007
1008 // Start notifications on the descriptor's characteristic. The descriptor
1009 // value should change.
1010 characteristic->StartNotifySession(
1011 base::Bind(&BluetoothGattBlueZTest::NotifySessionCallback,
1012 base::Unretained(this)),
1013 base::Bind(&BluetoothGattBlueZTest::ServiceErrorCallback,
1014 base::Unretained(this)));
1015 base::MessageLoop::current()->Run();
1016 EXPECT_EQ(3, success_callback_count_);
1017 EXPECT_EQ(1, error_callback_count_);
1018 EXPECT_EQ(1U, update_sessions_.size());
1019 EXPECT_TRUE(characteristic->IsNotifying());
1020
1021 // Read the new descriptor value. We should receive a value updated event.
1022 descriptor->ReadRemoteDescriptor(
1023 base::Bind(&BluetoothGattBlueZTest::ValueCallback,
1024 base::Unretained(this)),
1025 base::Bind(&BluetoothGattBlueZTest::ServiceErrorCallback,
1026 base::Unretained(this)));
1027 EXPECT_EQ(4, success_callback_count_);
1028 EXPECT_EQ(1, error_callback_count_);
1029 EXPECT_TRUE(ValuesEqual(last_read_value_, descriptor->GetValue()));
1030 EXPECT_FALSE(ValuesEqual(desc_value, descriptor->GetValue()));
1031 EXPECT_EQ(0, observer.gatt_service_changed_count());
1032 EXPECT_EQ(2, observer.gatt_descriptor_value_changed_count());
1033 }
1034
1035 TEST_F(BluetoothGattBlueZTest, NotifySessions) {
1036 fake_bluetooth_device_client_->CreateDevice(
1037 dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
1038 dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
1039 BluetoothDevice* device =
1040 adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress);
1041 ASSERT_TRUE(device);
1042
1043 TestBluetoothAdapterObserver observer(adapter_);
1044
1045 // Expose the fake Heart Rate service. This will asynchronously expose
1046 // characteristics.
1047 fake_bluetooth_gatt_service_client_->ExposeHeartRateService(
1048 dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
1049 ASSERT_EQ(1, observer.gatt_service_added_count());
1050
1051 BluetoothGattService* service =
1052 device->GetGattService(observer.last_gatt_service_id());
1053
1054 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count());
1055
1056 // Run the message loop so that the characteristics appear.
1057 base::MessageLoop::current()->Run();
1058
1059 BluetoothGattCharacteristic* characteristic = service->GetCharacteristic(
1060 fake_bluetooth_gatt_characteristic_client_->GetHeartRateMeasurementPath()
1061 .value());
1062 ASSERT_TRUE(characteristic);
1063 EXPECT_FALSE(characteristic->IsNotifying());
1064 EXPECT_TRUE(update_sessions_.empty());
1065
1066 // Request to start notifications.
1067 characteristic->StartNotifySession(
1068 base::Bind(&BluetoothGattBlueZTest::NotifySessionCallback,
1069 base::Unretained(this)),
1070 base::Bind(&BluetoothGattBlueZTest::ServiceErrorCallback,
1071 base::Unretained(this)));
1072
1073 // The operation still hasn't completed but we should have received the first
1074 // notification.
1075 EXPECT_EQ(0, success_callback_count_);
1076 EXPECT_EQ(0, error_callback_count_);
1077 EXPECT_EQ(1, observer.gatt_characteristic_value_changed_count());
1078 EXPECT_TRUE(update_sessions_.empty());
1079
1080 // Send a two more requests, which should get queued.
1081 characteristic->StartNotifySession(
1082 base::Bind(&BluetoothGattBlueZTest::NotifySessionCallback,
1083 base::Unretained(this)),
1084 base::Bind(&BluetoothGattBlueZTest::ServiceErrorCallback,
1085 base::Unretained(this)));
1086 characteristic->StartNotifySession(
1087 base::Bind(&BluetoothGattBlueZTest::NotifySessionCallback,
1088 base::Unretained(this)),
1089 base::Bind(&BluetoothGattBlueZTest::ServiceErrorCallback,
1090 base::Unretained(this)));
1091 EXPECT_EQ(0, success_callback_count_);
1092 EXPECT_EQ(0, error_callback_count_);
1093 EXPECT_EQ(1, observer.gatt_characteristic_value_changed_count());
1094 EXPECT_TRUE(update_sessions_.empty());
1095 EXPECT_TRUE(characteristic->IsNotifying());
1096
1097 // Run the main loop. The initial call should complete. The queued call should
1098 // succeed immediately.
1099 base::MessageLoop::current()->Run();
1100
1101 EXPECT_EQ(3, success_callback_count_);
1102 EXPECT_EQ(0, error_callback_count_);
1103 EXPECT_EQ(1, observer.gatt_characteristic_value_changed_count());
1104 EXPECT_EQ(3U, update_sessions_.size());
1105
1106 // Notifications should be getting sent regularly now.
1107 base::MessageLoop::current()->Run();
1108 EXPECT_GT(observer.gatt_characteristic_value_changed_count(), 1);
1109
1110 // Stop one of the sessions. The session should become inactive but the
1111 // characteristic should still be notifying.
1112 BluetoothGattNotifySession* session = update_sessions_[0];
1113 EXPECT_TRUE(session->IsActive());
1114 session->Stop(base::Bind(&BluetoothGattBlueZTest::SuccessCallback,
1115 base::Unretained(this)));
1116 EXPECT_EQ(4, success_callback_count_);
1117 EXPECT_EQ(0, error_callback_count_);
1118 EXPECT_FALSE(session->IsActive());
1119 EXPECT_EQ(characteristic->GetIdentifier(),
1120 session->GetCharacteristicIdentifier());
1121 EXPECT_TRUE(characteristic->IsNotifying());
1122
1123 // Delete another session. Characteristic should still be notifying.
1124 update_sessions_.pop_back();
1125 EXPECT_EQ(2U, update_sessions_.size());
1126 EXPECT_TRUE(characteristic->IsNotifying());
1127 EXPECT_FALSE(update_sessions_[0]->IsActive());
1128 EXPECT_TRUE(update_sessions_[1]->IsActive());
1129
1130 // Clear the last session.
1131 update_sessions_.clear();
1132 EXPECT_TRUE(update_sessions_.empty());
1133 EXPECT_FALSE(characteristic->IsNotifying());
1134
1135 success_callback_count_ = 0;
1136 observer.Reset();
1137
1138 // Enable notifications again.
1139 characteristic->StartNotifySession(
1140 base::Bind(&BluetoothGattBlueZTest::NotifySessionCallback,
1141 base::Unretained(this)),
1142 base::Bind(&BluetoothGattBlueZTest::ServiceErrorCallback,
1143 base::Unretained(this)));
1144 EXPECT_EQ(0, success_callback_count_);
1145 EXPECT_EQ(0, error_callback_count_);
1146 EXPECT_EQ(1, observer.gatt_characteristic_value_changed_count());
1147 EXPECT_TRUE(update_sessions_.empty());
1148 EXPECT_TRUE(characteristic->IsNotifying());
1149
1150 // Run the message loop. Notifications should begin.
1151 base::MessageLoop::current()->Run();
1152
1153 EXPECT_EQ(1, success_callback_count_);
1154 EXPECT_EQ(0, error_callback_count_);
1155 EXPECT_EQ(1, observer.gatt_characteristic_value_changed_count());
1156 EXPECT_EQ(1U, update_sessions_.size());
1157 EXPECT_TRUE(update_sessions_[0]->IsActive());
1158 EXPECT_TRUE(characteristic->IsNotifying());
1159
1160 // Check that notifications are happening.
1161 base::MessageLoop::current()->Run();
1162 EXPECT_GT(observer.gatt_characteristic_value_changed_count(), 1);
1163
1164 // Request another session. This should return immediately.
1165 characteristic->StartNotifySession(
1166 base::Bind(&BluetoothGattBlueZTest::NotifySessionCallback,
1167 base::Unretained(this)),
1168 base::Bind(&BluetoothGattBlueZTest::ServiceErrorCallback,
1169 base::Unretained(this)));
1170 EXPECT_EQ(2, success_callback_count_);
1171 EXPECT_EQ(0, error_callback_count_);
1172 EXPECT_EQ(2U, update_sessions_.size());
1173 EXPECT_TRUE(update_sessions_[0]->IsActive());
1174 EXPECT_TRUE(update_sessions_[1]->IsActive());
1175 EXPECT_TRUE(characteristic->IsNotifying());
1176
1177 // Hide the characteristic. The sessions should become inactive.
1178 fake_bluetooth_gatt_characteristic_client_->HideHeartRateCharacteristics();
1179 EXPECT_EQ(2U, update_sessions_.size());
1180 EXPECT_FALSE(update_sessions_[0]->IsActive());
1181 EXPECT_FALSE(update_sessions_[1]->IsActive());
1182 }
1183
1184 TEST_F(BluetoothGattBlueZTest, NotifySessionsMadeInactive) {
1185 fake_bluetooth_device_client_->CreateDevice(
1186 dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
1187 dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
1188 BluetoothDevice* device =
1189 adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress);
1190 ASSERT_TRUE(device);
1191
1192 TestBluetoothAdapterObserver observer(adapter_);
1193
1194 // Expose the fake Heart Rate service. This will asynchronously expose
1195 // characteristics.
1196 fake_bluetooth_gatt_service_client_->ExposeHeartRateService(
1197 dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
1198 ASSERT_EQ(1, observer.gatt_service_added_count());
1199
1200 BluetoothGattService* service =
1201 device->GetGattService(observer.last_gatt_service_id());
1202
1203 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count());
1204
1205 // Run the message loop so that the characteristics appear.
1206 base::MessageLoop::current()->Run();
1207
1208 BluetoothGattCharacteristic* characteristic = service->GetCharacteristic(
1209 fake_bluetooth_gatt_characteristic_client_->GetHeartRateMeasurementPath()
1210 .value());
1211 ASSERT_TRUE(characteristic);
1212 EXPECT_FALSE(characteristic->IsNotifying());
1213 EXPECT_TRUE(update_sessions_.empty());
1214
1215 // Send several requests to start notifications.
1216 characteristic->StartNotifySession(
1217 base::Bind(&BluetoothGattBlueZTest::NotifySessionCallback,
1218 base::Unretained(this)),
1219 base::Bind(&BluetoothGattBlueZTest::ServiceErrorCallback,
1220 base::Unretained(this)));
1221 characteristic->StartNotifySession(
1222 base::Bind(&BluetoothGattBlueZTest::NotifySessionCallback,
1223 base::Unretained(this)),
1224 base::Bind(&BluetoothGattBlueZTest::ServiceErrorCallback,
1225 base::Unretained(this)));
1226 characteristic->StartNotifySession(
1227 base::Bind(&BluetoothGattBlueZTest::NotifySessionCallback,
1228 base::Unretained(this)),
1229 base::Bind(&BluetoothGattBlueZTest::ServiceErrorCallback,
1230 base::Unretained(this)));
1231 characteristic->StartNotifySession(
1232 base::Bind(&BluetoothGattBlueZTest::NotifySessionCallback,
1233 base::Unretained(this)),
1234 base::Bind(&BluetoothGattBlueZTest::ServiceErrorCallback,
1235 base::Unretained(this)));
1236
1237 // The operation still hasn't completed but we should have received the first
1238 // notification.
1239 EXPECT_EQ(0, success_callback_count_);
1240 EXPECT_EQ(0, error_callback_count_);
1241 EXPECT_EQ(1, observer.gatt_characteristic_value_changed_count());
1242 EXPECT_TRUE(characteristic->IsNotifying());
1243 EXPECT_TRUE(update_sessions_.empty());
1244
1245 // Run the main loop. The initial call should complete. The queued calls
1246 // should succeed immediately.
1247 base::MessageLoop::current()->Run();
1248
1249 EXPECT_EQ(4, success_callback_count_);
1250 EXPECT_EQ(0, error_callback_count_);
1251 EXPECT_EQ(1, observer.gatt_characteristic_value_changed_count());
1252 EXPECT_TRUE(characteristic->IsNotifying());
1253 EXPECT_EQ(4U, update_sessions_.size());
1254
1255 for (int i = 0; i < 4; i++)
1256 EXPECT_TRUE(update_sessions_[0]->IsActive());
1257
1258 // Stop notifications directly through the client. The sessions should get
1259 // marked as inactive.
1260 fake_bluetooth_gatt_characteristic_client_->StopNotify(
1261 fake_bluetooth_gatt_characteristic_client_->GetHeartRateMeasurementPath(),
1262 base::Bind(&BluetoothGattBlueZTest::SuccessCallback,
1263 base::Unretained(this)),
1264 base::Bind(&BluetoothGattBlueZTest::DBusErrorCallback,
1265 base::Unretained(this)));
1266 EXPECT_EQ(5, success_callback_count_);
1267 EXPECT_EQ(0, error_callback_count_);
1268 EXPECT_FALSE(characteristic->IsNotifying());
1269 EXPECT_EQ(4U, update_sessions_.size());
1270
1271 for (int i = 0; i < 4; i++)
1272 EXPECT_FALSE(update_sessions_[0]->IsActive());
1273
1274 // It should be possible to restart notifications and the call should reset
1275 // the session count and make a request through the client.
1276 update_sessions_.clear();
1277 success_callback_count_ = 0;
1278 observer.Reset();
1279 characteristic->StartNotifySession(
1280 base::Bind(&BluetoothGattBlueZTest::NotifySessionCallback,
1281 base::Unretained(this)),
1282 base::Bind(&BluetoothGattBlueZTest::ServiceErrorCallback,
1283 base::Unretained(this)));
1284
1285 EXPECT_EQ(0, success_callback_count_);
1286 EXPECT_EQ(0, error_callback_count_);
1287 EXPECT_EQ(1, observer.gatt_characteristic_value_changed_count());
1288 EXPECT_TRUE(characteristic->IsNotifying());
1289 EXPECT_TRUE(update_sessions_.empty());
1290
1291 base::MessageLoop::current()->Run();
1292
1293 EXPECT_EQ(1, success_callback_count_);
1294 EXPECT_EQ(0, error_callback_count_);
1295 EXPECT_EQ(1, observer.gatt_characteristic_value_changed_count());
1296 EXPECT_TRUE(characteristic->IsNotifying());
1297 EXPECT_EQ(1U, update_sessions_.size());
1298 EXPECT_TRUE(update_sessions_[0]->IsActive());
1299 }
1300
1301 } // namespace bluez
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698