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

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

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

Powered by Google App Engine
This is Rietveld 408576698