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

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

Issue 1415573014: Reland "Add Linux support for the Bluetooth API" (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: build fix. Created 5 years, 1 month 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()->QuitWhenIdle();
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, ServicesDiscovered) {
361 // Create a fake LE device. We store the device pointer here because this is a
362 // test. It's unsafe to do this in production as the device might get deleted.
363 fake_bluetooth_device_client_->CreateDevice(
364 dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
365 dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
366 BluetoothDevice* device =
367 adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress);
368 bluez::FakeBluetoothDeviceClient::Properties* properties =
369 fake_bluetooth_device_client_->GetProperties(
370 dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
371
372 ASSERT_TRUE(device);
373
374 TestBluetoothAdapterObserver observer(adapter_);
375
376 EXPECT_EQ(0, observer.gatt_services_discovered_count());
377
378 // Expose the fake Heart Rate Service.
379 fake_bluetooth_gatt_service_client_->ExposeHeartRateService(
380 dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
381 // Notify that all services have been discovered.
382 properties->gatt_services.ReplaceValue(
383 fake_bluetooth_gatt_service_client_->GetServices());
384
385 EXPECT_EQ(1, observer.gatt_services_discovered_count());
386 EXPECT_EQ(device, observer.last_device());
387 EXPECT_EQ(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress,
388 observer.last_device_address());
389 }
390
391 TEST_F(BluetoothGattChromeOSTest, GattCharacteristicAddedAndRemoved) {
392 fake_bluetooth_device_client_->CreateDevice(
393 dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
394 dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
395 BluetoothDevice* device =
396 adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress);
397 ASSERT_TRUE(device);
398
399 TestBluetoothAdapterObserver observer(adapter_);
400
401 // Expose the fake Heart Rate service. This will asynchronously expose
402 // characteristics.
403 fake_bluetooth_gatt_service_client_->ExposeHeartRateService(
404 dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
405 ASSERT_EQ(1, observer.gatt_service_added_count());
406
407 BluetoothGattService* service =
408 device->GetGattService(observer.last_gatt_service_id());
409
410 EXPECT_EQ(0, observer.gatt_service_changed_count());
411 EXPECT_EQ(0, observer.gatt_discovery_complete_count());
412 EXPECT_EQ(0, observer.gatt_characteristic_added_count());
413 EXPECT_EQ(0, observer.gatt_characteristic_removed_count());
414 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count());
415 EXPECT_TRUE(service->GetCharacteristics().empty());
416
417 // Run the message loop so that the characteristics appear.
418 base::MessageLoop::current()->Run();
419
420 // 3 characteristics should appear. Only 1 of the characteristics sends
421 // value changed signals. Service changed should be fired once for
422 // descriptor added.
423 EXPECT_EQ(0, observer.gatt_service_changed_count());
424 EXPECT_EQ(1, observer.gatt_discovery_complete_count());
425 EXPECT_EQ(3, observer.gatt_characteristic_added_count());
426 EXPECT_EQ(0, observer.gatt_characteristic_removed_count());
427 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count());
428 EXPECT_EQ(3U, service->GetCharacteristics().size());
429
430 // Hide the characteristics. 3 removed signals should be received.
431 fake_bluetooth_gatt_characteristic_client_->HideHeartRateCharacteristics();
432 EXPECT_EQ(0, observer.gatt_service_changed_count());
433 EXPECT_EQ(3, observer.gatt_characteristic_added_count());
434 EXPECT_EQ(3, observer.gatt_characteristic_removed_count());
435 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count());
436 EXPECT_TRUE(service->GetCharacteristics().empty());
437
438 // Re-expose the heart rate characteristics. We shouldn't get another
439 // GattDiscoveryCompleteForService call, since the service thinks that
440 // discovery is done. On the bluetoothd side, characteristics will be removed
441 // only if the service will also be subsequently removed.
442 fake_bluetooth_gatt_characteristic_client_->ExposeHeartRateCharacteristics(
443 fake_bluetooth_gatt_service_client_->GetHeartRateServicePath());
444 EXPECT_EQ(0, observer.gatt_service_changed_count());
445 EXPECT_EQ(1, observer.gatt_discovery_complete_count());
446 EXPECT_EQ(6, observer.gatt_characteristic_added_count());
447 EXPECT_EQ(3, observer.gatt_characteristic_removed_count());
448 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count());
449 EXPECT_EQ(3U, service->GetCharacteristics().size());
450
451 // Hide the service. All characteristics should disappear.
452 fake_bluetooth_gatt_service_client_->HideHeartRateService();
453 EXPECT_EQ(0, observer.gatt_service_changed_count());
454 EXPECT_EQ(6, observer.gatt_characteristic_added_count());
455 EXPECT_EQ(6, observer.gatt_characteristic_removed_count());
456 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count());
457 }
458
459 TEST_F(BluetoothGattChromeOSTest, GattDescriptorAddedAndRemoved) {
460 fake_bluetooth_device_client_->CreateDevice(
461 dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
462 dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
463 BluetoothDevice* device =
464 adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress);
465 ASSERT_TRUE(device);
466
467 TestBluetoothAdapterObserver observer(adapter_);
468
469 // Expose the fake Heart Rate service. This will asynchronously expose
470 // characteristics.
471 fake_bluetooth_gatt_service_client_->ExposeHeartRateService(
472 dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
473 ASSERT_EQ(1, observer.gatt_service_added_count());
474
475 BluetoothGattService* service =
476 device->GetGattService(observer.last_gatt_service_id());
477
478 EXPECT_EQ(0, observer.gatt_service_changed_count());
479 EXPECT_EQ(0, observer.gatt_descriptor_added_count());
480 EXPECT_EQ(0, observer.gatt_descriptor_removed_count());
481 EXPECT_EQ(0, observer.gatt_descriptor_value_changed_count());
482
483 EXPECT_TRUE(service->GetCharacteristics().empty());
484
485 // Run the message loop so that the characteristics appear.
486 base::MessageLoop::current()->Run();
487 EXPECT_EQ(0, observer.gatt_service_changed_count());
488
489 // Only the Heart Rate Measurement characteristic has a descriptor.
490 EXPECT_EQ(1, observer.gatt_descriptor_added_count());
491 EXPECT_EQ(0, observer.gatt_descriptor_removed_count());
492 EXPECT_EQ(0, observer.gatt_descriptor_value_changed_count());
493
494 BluetoothGattCharacteristic* characteristic = service->GetCharacteristic(
495 fake_bluetooth_gatt_characteristic_client_->
496 GetBodySensorLocationPath().value());
497 ASSERT_TRUE(characteristic);
498 EXPECT_TRUE(characteristic->GetDescriptors().empty());
499
500 characteristic = service->GetCharacteristic(
501 fake_bluetooth_gatt_characteristic_client_->
502 GetHeartRateControlPointPath().value());
503 ASSERT_TRUE(characteristic);
504 EXPECT_TRUE(characteristic->GetDescriptors().empty());
505
506 characteristic = service->GetCharacteristic(
507 fake_bluetooth_gatt_characteristic_client_->
508 GetHeartRateMeasurementPath().value());
509 ASSERT_TRUE(characteristic);
510 EXPECT_EQ(1U, characteristic->GetDescriptors().size());
511
512 BluetoothGattDescriptor* descriptor = characteristic->GetDescriptors()[0];
513 EXPECT_FALSE(descriptor->IsLocal());
514 EXPECT_EQ(BluetoothGattDescriptor::ClientCharacteristicConfigurationUuid(),
515 descriptor->GetUUID());
516 EXPECT_EQ(descriptor->GetUUID(), observer.last_gatt_descriptor_uuid());
517 EXPECT_EQ(descriptor->GetIdentifier(), observer.last_gatt_descriptor_id());
518
519 // Hide the descriptor.
520 fake_bluetooth_gatt_descriptor_client_->HideDescriptor(
521 dbus::ObjectPath(descriptor->GetIdentifier()));
522 EXPECT_TRUE(characteristic->GetDescriptors().empty());
523 EXPECT_EQ(0, observer.gatt_service_changed_count());
524 EXPECT_EQ(1, observer.gatt_descriptor_added_count());
525 EXPECT_EQ(1, observer.gatt_descriptor_removed_count());
526 EXPECT_EQ(0, observer.gatt_descriptor_value_changed_count());
527
528 // Expose the descriptor again.
529 observer.last_gatt_descriptor_id().clear();
530 observer.last_gatt_descriptor_uuid() = BluetoothUUID();
531 fake_bluetooth_gatt_descriptor_client_->ExposeDescriptor(
532 dbus::ObjectPath(characteristic->GetIdentifier()),
533 bluez::FakeBluetoothGattDescriptorClient::
534 kClientCharacteristicConfigurationUUID);
535 EXPECT_EQ(0, observer.gatt_service_changed_count());
536 EXPECT_EQ(1U, characteristic->GetDescriptors().size());
537 EXPECT_EQ(2, observer.gatt_descriptor_added_count());
538 EXPECT_EQ(1, observer.gatt_descriptor_removed_count());
539 EXPECT_EQ(0, observer.gatt_descriptor_value_changed_count());
540
541 descriptor = characteristic->GetDescriptors()[0];
542 EXPECT_FALSE(descriptor->IsLocal());
543 EXPECT_EQ(BluetoothGattDescriptor::ClientCharacteristicConfigurationUuid(),
544 descriptor->GetUUID());
545 EXPECT_EQ(descriptor->GetUUID(), observer.last_gatt_descriptor_uuid());
546 EXPECT_EQ(descriptor->GetIdentifier(), observer.last_gatt_descriptor_id());
547 }
548
549 TEST_F(BluetoothGattChromeOSTest, AdapterAddedAfterGattService) {
550 // This unit test tests that all remote GATT objects are created for D-Bus
551 // objects that were already exposed.
552 adapter_ = NULL;
553 ASSERT_FALSE(device::BluetoothAdapterFactory::HasSharedInstanceForTesting());
554
555 // Create the fake D-Bus objects.
556 fake_bluetooth_device_client_->CreateDevice(
557 dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
558 dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
559 fake_bluetooth_gatt_service_client_->ExposeHeartRateService(
560 dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
561 while (!fake_bluetooth_gatt_characteristic_client_->IsHeartRateVisible())
562 base::RunLoop().RunUntilIdle();
563 ASSERT_TRUE(fake_bluetooth_gatt_service_client_->IsHeartRateVisible());
564 ASSERT_TRUE(fake_bluetooth_gatt_characteristic_client_->IsHeartRateVisible());
565
566 // Create the adapter. This should create all the GATT objects.
567 GetAdapter();
568 BluetoothDevice* device =
569 adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress);
570 ASSERT_TRUE(device);
571 EXPECT_EQ(1U, device->GetGattServices().size());
572
573 BluetoothGattService* service = device->GetGattServices()[0];
574 ASSERT_TRUE(service);
575 EXPECT_FALSE(service->IsLocal());
576 EXPECT_TRUE(service->IsPrimary());
577 EXPECT_EQ(BluetoothUUID(
578 bluez::FakeBluetoothGattServiceClient::kHeartRateServiceUUID),
579 service->GetUUID());
580 EXPECT_EQ(service, device->GetGattServices()[0]);
581 EXPECT_EQ(service, device->GetGattService(service->GetIdentifier()));
582 EXPECT_FALSE(service->IsLocal());
583 EXPECT_EQ(3U, service->GetCharacteristics().size());
584
585 BluetoothGattCharacteristic* characteristic = service->GetCharacteristic(
586 fake_bluetooth_gatt_characteristic_client_->
587 GetBodySensorLocationPath().value());
588 ASSERT_TRUE(characteristic);
589 EXPECT_EQ(BluetoothUUID(bluez::FakeBluetoothGattCharacteristicClient::
590 kBodySensorLocationUUID),
591 characteristic->GetUUID());
592 EXPECT_FALSE(characteristic->IsLocal());
593 EXPECT_TRUE(characteristic->GetDescriptors().empty());
594
595 characteristic = service->GetCharacteristic(
596 fake_bluetooth_gatt_characteristic_client_->
597 GetHeartRateControlPointPath().value());
598 ASSERT_TRUE(characteristic);
599 EXPECT_EQ(BluetoothUUID(bluez::FakeBluetoothGattCharacteristicClient::
600 kHeartRateControlPointUUID),
601 characteristic->GetUUID());
602 EXPECT_FALSE(characteristic->IsLocal());
603 EXPECT_TRUE(characteristic->GetDescriptors().empty());
604
605 characteristic = service->GetCharacteristic(
606 fake_bluetooth_gatt_characteristic_client_->
607 GetHeartRateMeasurementPath().value());
608 ASSERT_TRUE(characteristic);
609 EXPECT_EQ(BluetoothUUID(bluez::FakeBluetoothGattCharacteristicClient::
610 kHeartRateMeasurementUUID),
611 characteristic->GetUUID());
612 EXPECT_FALSE(characteristic->IsLocal());
613 EXPECT_EQ(1U, characteristic->GetDescriptors().size());
614
615 BluetoothGattDescriptor* descriptor = characteristic->GetDescriptors()[0];
616 ASSERT_TRUE(descriptor);
617 EXPECT_EQ(BluetoothGattDescriptor::ClientCharacteristicConfigurationUuid(),
618 descriptor->GetUUID());
619 EXPECT_FALSE(descriptor->IsLocal());
620 }
621
622 TEST_F(BluetoothGattChromeOSTest, GattCharacteristicValue) {
623 fake_bluetooth_device_client_->CreateDevice(
624 dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
625 dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
626 BluetoothDevice* device =
627 adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress);
628 ASSERT_TRUE(device);
629
630 TestBluetoothAdapterObserver observer(adapter_);
631
632 // Expose the fake Heart Rate service. This will asynchronously expose
633 // characteristics.
634 fake_bluetooth_gatt_service_client_->ExposeHeartRateService(
635 dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
636 ASSERT_EQ(1, observer.gatt_service_added_count());
637
638 BluetoothGattService* service =
639 device->GetGattService(observer.last_gatt_service_id());
640
641 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count());
642
643 // Run the message loop so that the characteristics appear.
644 base::MessageLoop::current()->Run();
645
646 // Issue write request to non-writable characteristics.
647 observer.Reset();
648
649 std::vector<uint8> write_value;
650 write_value.push_back(0x01);
651 BluetoothGattCharacteristic* characteristic =
652 service->GetCharacteristic(fake_bluetooth_gatt_characteristic_client_->
653 GetHeartRateMeasurementPath().value());
654 ASSERT_TRUE(characteristic);
655 EXPECT_FALSE(characteristic->IsNotifying());
656 EXPECT_EQ(fake_bluetooth_gatt_characteristic_client_->
657 GetHeartRateMeasurementPath().value(),
658 characteristic->GetIdentifier());
659 EXPECT_EQ(kHeartRateMeasurementUUID, characteristic->GetUUID());
660 characteristic->WriteRemoteCharacteristic(
661 write_value,
662 base::Bind(&BluetoothGattChromeOSTest::SuccessCallback,
663 base::Unretained(this)),
664 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
665 base::Unretained(this)));
666 EXPECT_TRUE(observer.last_gatt_characteristic_id().empty());
667 EXPECT_FALSE(observer.last_gatt_characteristic_uuid().IsValid());
668 EXPECT_EQ(0, success_callback_count_);
669 EXPECT_EQ(1, error_callback_count_);
670 EXPECT_EQ(BluetoothGattService::GATT_ERROR_NOT_SUPPORTED,
671 last_service_error_);
672 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count());
673
674 characteristic = service->GetCharacteristic(
675 fake_bluetooth_gatt_characteristic_client_->
676 GetBodySensorLocationPath().value());
677 ASSERT_TRUE(characteristic);
678 EXPECT_EQ(fake_bluetooth_gatt_characteristic_client_->
679 GetBodySensorLocationPath().value(),
680 characteristic->GetIdentifier());
681 EXPECT_EQ(kBodySensorLocationUUID, characteristic->GetUUID());
682 characteristic->WriteRemoteCharacteristic(
683 write_value,
684 base::Bind(&BluetoothGattChromeOSTest::SuccessCallback,
685 base::Unretained(this)),
686 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
687 base::Unretained(this)));
688 EXPECT_TRUE(observer.last_gatt_characteristic_id().empty());
689 EXPECT_FALSE(observer.last_gatt_characteristic_uuid().IsValid());
690 EXPECT_EQ(0, success_callback_count_);
691 EXPECT_EQ(2, error_callback_count_);
692 EXPECT_EQ(BluetoothGattService::GATT_ERROR_NOT_PERMITTED,
693 last_service_error_);
694 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count());
695
696 // Issue write request to writable characteristic. The "Body Sensor Location"
697 // characteristic does not send notifications and WriteValue does not result
698 // in a CharacteristicValueChanged event, thus no such event should be
699 // received.
700 characteristic = service->GetCharacteristic(
701 fake_bluetooth_gatt_characteristic_client_->
702 GetHeartRateControlPointPath().value());
703 ASSERT_TRUE(characteristic);
704 EXPECT_EQ(fake_bluetooth_gatt_characteristic_client_->
705 GetHeartRateControlPointPath().value(),
706 characteristic->GetIdentifier());
707 EXPECT_EQ(kHeartRateControlPointUUID, characteristic->GetUUID());
708 characteristic->WriteRemoteCharacteristic(
709 write_value,
710 base::Bind(&BluetoothGattChromeOSTest::SuccessCallback,
711 base::Unretained(this)),
712 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
713 base::Unretained(this)));
714 EXPECT_TRUE(observer.last_gatt_characteristic_id().empty());
715 EXPECT_FALSE(observer.last_gatt_characteristic_uuid().IsValid());
716 EXPECT_EQ(1, success_callback_count_);
717 EXPECT_EQ(2, error_callback_count_);
718 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count());
719
720 // Issue some invalid write requests to the characteristic.
721 // The value should still not change.
722
723 std::vector<uint8> invalid_write_length;
724 invalid_write_length.push_back(0x01);
725 invalid_write_length.push_back(0x00);
726 characteristic->WriteRemoteCharacteristic(
727 invalid_write_length,
728 base::Bind(&BluetoothGattChromeOSTest::SuccessCallback,
729 base::Unretained(this)),
730 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
731 base::Unretained(this)));
732 EXPECT_EQ(1, success_callback_count_);
733 EXPECT_EQ(3, error_callback_count_);
734 EXPECT_EQ(BluetoothGattService::GATT_ERROR_INVALID_LENGTH,
735 last_service_error_);
736 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count());
737
738 std::vector<uint8> invalid_write_value;
739 invalid_write_value.push_back(0x02);
740 characteristic->WriteRemoteCharacteristic(
741 invalid_write_value,
742 base::Bind(&BluetoothGattChromeOSTest::SuccessCallback,
743 base::Unretained(this)),
744 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
745 base::Unretained(this)));
746 EXPECT_EQ(1, success_callback_count_);
747 EXPECT_EQ(4, error_callback_count_);
748 EXPECT_EQ(BluetoothGattService::GATT_ERROR_FAILED, last_service_error_);
749 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count());
750
751 // Issue a read request. A successful read results in a
752 // CharacteristicValueChanged notification.
753 characteristic = service->GetCharacteristic(
754 fake_bluetooth_gatt_characteristic_client_->
755 GetBodySensorLocationPath().value());
756 ASSERT_TRUE(characteristic);
757 EXPECT_EQ(fake_bluetooth_gatt_characteristic_client_->
758 GetBodySensorLocationPath().value(),
759 characteristic->GetIdentifier());
760 EXPECT_EQ(kBodySensorLocationUUID, characteristic->GetUUID());
761 characteristic->ReadRemoteCharacteristic(
762 base::Bind(&BluetoothGattChromeOSTest::ValueCallback,
763 base::Unretained(this)),
764 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
765 base::Unretained(this)));
766 EXPECT_EQ(2, success_callback_count_);
767 EXPECT_EQ(4, error_callback_count_);
768 EXPECT_EQ(1, observer.gatt_characteristic_value_changed_count());
769 EXPECT_TRUE(ValuesEqual(characteristic->GetValue(), last_read_value_));
770
771 // Test long-running actions.
772 fake_bluetooth_gatt_characteristic_client_->SetExtraProcessing(1);
773 characteristic = service->GetCharacteristic(
774 fake_bluetooth_gatt_characteristic_client_->GetBodySensorLocationPath()
775 .value());
776 ASSERT_TRUE(characteristic);
777 EXPECT_EQ(
778 fake_bluetooth_gatt_characteristic_client_->GetBodySensorLocationPath()
779 .value(),
780 characteristic->GetIdentifier());
781 EXPECT_EQ(kBodySensorLocationUUID, characteristic->GetUUID());
782 characteristic->ReadRemoteCharacteristic(
783 base::Bind(&BluetoothGattChromeOSTest::ValueCallback,
784 base::Unretained(this)),
785 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
786 base::Unretained(this)));
787
788 // Callback counts shouldn't change, this one will be delayed until after
789 // tne next one.
790 EXPECT_EQ(2, success_callback_count_);
791 EXPECT_EQ(4, error_callback_count_);
792 EXPECT_EQ(1, observer.gatt_characteristic_value_changed_count());
793
794 // Next read should error because IN_PROGRESS
795 characteristic->ReadRemoteCharacteristic(
796 base::Bind(&BluetoothGattChromeOSTest::ValueCallback,
797 base::Unretained(this)),
798 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
799 base::Unretained(this)));
800 EXPECT_EQ(5, error_callback_count_);
801 EXPECT_EQ(BluetoothGattService::GATT_ERROR_IN_PROGRESS, last_service_error_);
802
803 // But previous call finished.
804 EXPECT_EQ(3, success_callback_count_);
805 EXPECT_EQ(2, observer.gatt_characteristic_value_changed_count());
806 EXPECT_TRUE(ValuesEqual(characteristic->GetValue(), last_read_value_));
807 fake_bluetooth_gatt_characteristic_client_->SetExtraProcessing(0);
808
809 // Test unauthorized actions.
810 fake_bluetooth_gatt_characteristic_client_->SetAuthorized(false);
811 characteristic->ReadRemoteCharacteristic(
812 base::Bind(&BluetoothGattChromeOSTest::ValueCallback,
813 base::Unretained(this)),
814 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
815 base::Unretained(this)));
816 EXPECT_EQ(3, success_callback_count_);
817 EXPECT_EQ(6, error_callback_count_);
818 EXPECT_EQ(BluetoothGattService::GATT_ERROR_NOT_AUTHORIZED,
819 last_service_error_);
820 EXPECT_EQ(2, observer.gatt_characteristic_value_changed_count());
821 fake_bluetooth_gatt_characteristic_client_->SetAuthorized(true);
822
823 // Test unauthenticated / needs login.
824 fake_bluetooth_gatt_characteristic_client_->SetAuthenticated(false);
825 characteristic->ReadRemoteCharacteristic(
826 base::Bind(&BluetoothGattChromeOSTest::ValueCallback,
827 base::Unretained(this)),
828 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
829 base::Unretained(this)));
830 EXPECT_EQ(3, success_callback_count_);
831 EXPECT_EQ(7, error_callback_count_);
832 EXPECT_EQ(BluetoothGattService::GATT_ERROR_NOT_PAIRED, last_service_error_);
833 EXPECT_EQ(2, observer.gatt_characteristic_value_changed_count());
834 fake_bluetooth_gatt_characteristic_client_->SetAuthenticated(true);
835 }
836
837 TEST_F(BluetoothGattChromeOSTest, GattCharacteristicProperties) {
838 fake_bluetooth_device_client_->CreateDevice(
839 dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
840 dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
841 BluetoothDevice* device =
842 adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress);
843 ASSERT_TRUE(device);
844
845 TestBluetoothAdapterObserver observer(adapter_);
846
847 // Expose the fake Heart Rate service. This will asynchronously expose
848 // characteristics.
849 fake_bluetooth_gatt_service_client_->ExposeHeartRateService(
850 dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
851
852 BluetoothGattService* service =
853 device->GetGattService(observer.last_gatt_service_id());
854
855 EXPECT_TRUE(service->GetCharacteristics().empty());
856
857 // Run the message loop so that the characteristics appear.
858 base::MessageLoop::current()->Run();
859
860 BluetoothGattCharacteristic *characteristic = service->GetCharacteristic(
861 fake_bluetooth_gatt_characteristic_client_->
862 GetBodySensorLocationPath().value());
863 EXPECT_EQ(BluetoothGattCharacteristic::PROPERTY_READ,
864 characteristic->GetProperties());
865
866 characteristic = service->GetCharacteristic(
867 fake_bluetooth_gatt_characteristic_client_->
868 GetHeartRateControlPointPath().value());
869 EXPECT_EQ(BluetoothGattCharacteristic::PROPERTY_WRITE,
870 characteristic->GetProperties());
871
872 characteristic = service->GetCharacteristic(
873 fake_bluetooth_gatt_characteristic_client_->
874 GetHeartRateMeasurementPath().value());
875 EXPECT_EQ(BluetoothGattCharacteristic::PROPERTY_NOTIFY,
876 characteristic->GetProperties());
877 }
878
879 TEST_F(BluetoothGattChromeOSTest, GattDescriptorValue) {
880 fake_bluetooth_device_client_->CreateDevice(
881 dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
882 dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
883 BluetoothDevice* device =
884 adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress);
885 ASSERT_TRUE(device);
886
887 TestBluetoothAdapterObserver observer(adapter_);
888
889 // Expose the fake Heart Rate service. This will asynchronously expose
890 // characteristics.
891 fake_bluetooth_gatt_service_client_->ExposeHeartRateService(
892 dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
893 ASSERT_EQ(1, observer.gatt_service_added_count());
894
895 BluetoothGattService* service =
896 device->GetGattService(observer.last_gatt_service_id());
897
898 EXPECT_EQ(0, observer.gatt_service_changed_count());
899 EXPECT_EQ(0, observer.gatt_discovery_complete_count());
900 EXPECT_EQ(0, observer.gatt_descriptor_value_changed_count());
901 EXPECT_TRUE(service->GetCharacteristics().empty());
902
903 // Run the message loop so that the characteristics appear.
904 base::MessageLoop::current()->Run();
905 EXPECT_EQ(0, observer.gatt_service_changed_count());
906 EXPECT_EQ(1, observer.gatt_discovery_complete_count());
907
908 // Only the Heart Rate Measurement characteristic has a descriptor.
909 BluetoothGattCharacteristic* characteristic = service->GetCharacteristic(
910 fake_bluetooth_gatt_characteristic_client_->
911 GetHeartRateMeasurementPath().value());
912 ASSERT_TRUE(characteristic);
913 EXPECT_EQ(1U, characteristic->GetDescriptors().size());
914 EXPECT_FALSE(characteristic->IsNotifying());
915
916 BluetoothGattDescriptor* descriptor = characteristic->GetDescriptors()[0];
917 EXPECT_FALSE(descriptor->IsLocal());
918 EXPECT_EQ(BluetoothGattDescriptor::ClientCharacteristicConfigurationUuid(),
919 descriptor->GetUUID());
920
921 std::vector<uint8_t> desc_value = {0x00, 0x00};
922
923 /* The cached value will be empty until the first read request */
924 EXPECT_FALSE(ValuesEqual(desc_value, descriptor->GetValue()));
925 EXPECT_TRUE(descriptor->GetValue().empty());
926
927 EXPECT_EQ(0, success_callback_count_);
928 EXPECT_EQ(0, error_callback_count_);
929 EXPECT_TRUE(last_read_value_.empty());
930
931 // Read value. GattDescriptorValueChanged event will be sent after a
932 // successful read.
933 descriptor->ReadRemoteDescriptor(
934 base::Bind(&BluetoothGattChromeOSTest::ValueCallback,
935 base::Unretained(this)),
936 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
937 base::Unretained(this)));
938 EXPECT_EQ(1, success_callback_count_);
939 EXPECT_EQ(0, error_callback_count_);
940 EXPECT_TRUE(ValuesEqual(last_read_value_, descriptor->GetValue()));
941 EXPECT_TRUE(ValuesEqual(desc_value, descriptor->GetValue()));
942 EXPECT_EQ(0, observer.gatt_service_changed_count());
943 EXPECT_EQ(1, observer.gatt_descriptor_value_changed_count());
944
945 // Write value. Writes to this descriptor will fail.
946 desc_value[0] = 0x03;
947 descriptor->WriteRemoteDescriptor(
948 desc_value,
949 base::Bind(&BluetoothGattChromeOSTest::SuccessCallback,
950 base::Unretained(this)),
951 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
952 base::Unretained(this)));
953 EXPECT_EQ(1, success_callback_count_);
954 EXPECT_EQ(1, error_callback_count_);
955 EXPECT_EQ(BluetoothGattService::GATT_ERROR_NOT_PERMITTED,
956 last_service_error_);
957 EXPECT_TRUE(ValuesEqual(last_read_value_, descriptor->GetValue()));
958 EXPECT_FALSE(ValuesEqual(desc_value, descriptor->GetValue()));
959 EXPECT_EQ(0, observer.gatt_service_changed_count());
960 EXPECT_EQ(1, observer.gatt_descriptor_value_changed_count());
961
962 // Read value. The value should remain unchanged.
963 descriptor->ReadRemoteDescriptor(
964 base::Bind(&BluetoothGattChromeOSTest::ValueCallback,
965 base::Unretained(this)),
966 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
967 base::Unretained(this)));
968 EXPECT_EQ(2, success_callback_count_);
969 EXPECT_EQ(1, error_callback_count_);
970 EXPECT_TRUE(ValuesEqual(last_read_value_, descriptor->GetValue()));
971 EXPECT_FALSE(ValuesEqual(desc_value, descriptor->GetValue()));
972 EXPECT_EQ(0, observer.gatt_service_changed_count());
973 EXPECT_EQ(1, observer.gatt_descriptor_value_changed_count());
974
975 // Start notifications on the descriptor's characteristic. The descriptor
976 // value should change.
977 characteristic->StartNotifySession(
978 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback,
979 base::Unretained(this)),
980 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
981 base::Unretained(this)));
982 base::MessageLoop::current()->Run();
983 EXPECT_EQ(3, success_callback_count_);
984 EXPECT_EQ(1, error_callback_count_);
985 EXPECT_EQ(1U, update_sessions_.size());
986 EXPECT_TRUE(characteristic->IsNotifying());
987
988 // Read the new descriptor value. We should receive a value updated event.
989 descriptor->ReadRemoteDescriptor(
990 base::Bind(&BluetoothGattChromeOSTest::ValueCallback,
991 base::Unretained(this)),
992 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
993 base::Unretained(this)));
994 EXPECT_EQ(4, success_callback_count_);
995 EXPECT_EQ(1, error_callback_count_);
996 EXPECT_TRUE(ValuesEqual(last_read_value_, descriptor->GetValue()));
997 EXPECT_FALSE(ValuesEqual(desc_value, descriptor->GetValue()));
998 EXPECT_EQ(0, observer.gatt_service_changed_count());
999 EXPECT_EQ(2, observer.gatt_descriptor_value_changed_count());
1000 }
1001
1002 TEST_F(BluetoothGattChromeOSTest, NotifySessions) {
1003 fake_bluetooth_device_client_->CreateDevice(
1004 dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
1005 dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
1006 BluetoothDevice* device =
1007 adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress);
1008 ASSERT_TRUE(device);
1009
1010 TestBluetoothAdapterObserver observer(adapter_);
1011
1012 // Expose the fake Heart Rate service. This will asynchronously expose
1013 // characteristics.
1014 fake_bluetooth_gatt_service_client_->ExposeHeartRateService(
1015 dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
1016 ASSERT_EQ(1, observer.gatt_service_added_count());
1017
1018 BluetoothGattService* service =
1019 device->GetGattService(observer.last_gatt_service_id());
1020
1021 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count());
1022
1023 // Run the message loop so that the characteristics appear.
1024 base::MessageLoop::current()->Run();
1025
1026 BluetoothGattCharacteristic* characteristic = service->GetCharacteristic(
1027 fake_bluetooth_gatt_characteristic_client_->GetHeartRateMeasurementPath()
1028 .value());
1029 ASSERT_TRUE(characteristic);
1030 EXPECT_FALSE(characteristic->IsNotifying());
1031 EXPECT_TRUE(update_sessions_.empty());
1032
1033 // Request to start notifications.
1034 characteristic->StartNotifySession(
1035 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback,
1036 base::Unretained(this)),
1037 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
1038 base::Unretained(this)));
1039
1040 // The operation still hasn't completed but we should have received the first
1041 // notification.
1042 EXPECT_EQ(0, success_callback_count_);
1043 EXPECT_EQ(0, error_callback_count_);
1044 EXPECT_EQ(1, observer.gatt_characteristic_value_changed_count());
1045 EXPECT_TRUE(update_sessions_.empty());
1046
1047 // Send a two more requests, which should get queued.
1048 characteristic->StartNotifySession(
1049 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback,
1050 base::Unretained(this)),
1051 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
1052 base::Unretained(this)));
1053 characteristic->StartNotifySession(
1054 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback,
1055 base::Unretained(this)),
1056 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
1057 base::Unretained(this)));
1058 EXPECT_EQ(0, success_callback_count_);
1059 EXPECT_EQ(0, error_callback_count_);
1060 EXPECT_EQ(1, observer.gatt_characteristic_value_changed_count());
1061 EXPECT_TRUE(update_sessions_.empty());
1062 EXPECT_TRUE(characteristic->IsNotifying());
1063
1064 // Run the main loop. The initial call should complete. The queued call should
1065 // succeed immediately.
1066 base::MessageLoop::current()->Run();
1067
1068 EXPECT_EQ(3, success_callback_count_);
1069 EXPECT_EQ(0, error_callback_count_);
1070 EXPECT_EQ(1, observer.gatt_characteristic_value_changed_count());
1071 EXPECT_EQ(3U, update_sessions_.size());
1072
1073 // Notifications should be getting sent regularly now.
1074 base::MessageLoop::current()->Run();
1075 EXPECT_GT(observer.gatt_characteristic_value_changed_count(), 1);
1076
1077 // Stop one of the sessions. The session should become inactive but the
1078 // characteristic should still be notifying.
1079 BluetoothGattNotifySession* session = update_sessions_[0];
1080 EXPECT_TRUE(session->IsActive());
1081 session->Stop(base::Bind(&BluetoothGattChromeOSTest::SuccessCallback,
1082 base::Unretained(this)));
1083 EXPECT_EQ(4, success_callback_count_);
1084 EXPECT_EQ(0, error_callback_count_);
1085 EXPECT_FALSE(session->IsActive());
1086 EXPECT_EQ(characteristic->GetIdentifier(),
1087 session->GetCharacteristicIdentifier());
1088 EXPECT_TRUE(characteristic->IsNotifying());
1089
1090 // Delete another session. Characteristic should still be notifying.
1091 update_sessions_.pop_back();
1092 EXPECT_EQ(2U, update_sessions_.size());
1093 EXPECT_TRUE(characteristic->IsNotifying());
1094 EXPECT_FALSE(update_sessions_[0]->IsActive());
1095 EXPECT_TRUE(update_sessions_[1]->IsActive());
1096
1097 // Clear the last session.
1098 update_sessions_.clear();
1099 EXPECT_TRUE(update_sessions_.empty());
1100 EXPECT_FALSE(characteristic->IsNotifying());
1101
1102 success_callback_count_ = 0;
1103 observer.Reset();
1104
1105 // Enable notifications again.
1106 characteristic->StartNotifySession(
1107 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback,
1108 base::Unretained(this)),
1109 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
1110 base::Unretained(this)));
1111 EXPECT_EQ(0, success_callback_count_);
1112 EXPECT_EQ(0, error_callback_count_);
1113 EXPECT_EQ(1, observer.gatt_characteristic_value_changed_count());
1114 EXPECT_TRUE(update_sessions_.empty());
1115 EXPECT_TRUE(characteristic->IsNotifying());
1116
1117 // Run the message loop. Notifications should begin.
1118 base::MessageLoop::current()->Run();
1119
1120 EXPECT_EQ(1, success_callback_count_);
1121 EXPECT_EQ(0, error_callback_count_);
1122 EXPECT_EQ(1, observer.gatt_characteristic_value_changed_count());
1123 EXPECT_EQ(1U, update_sessions_.size());
1124 EXPECT_TRUE(update_sessions_[0]->IsActive());
1125 EXPECT_TRUE(characteristic->IsNotifying());
1126
1127 // Check that notifications are happening.
1128 base::MessageLoop::current()->Run();
1129 EXPECT_GT(observer.gatt_characteristic_value_changed_count(), 1);
1130
1131 // Request another session. This should return immediately.
1132 characteristic->StartNotifySession(
1133 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback,
1134 base::Unretained(this)),
1135 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
1136 base::Unretained(this)));
1137 EXPECT_EQ(2, success_callback_count_);
1138 EXPECT_EQ(0, error_callback_count_);
1139 EXPECT_EQ(2U, update_sessions_.size());
1140 EXPECT_TRUE(update_sessions_[0]->IsActive());
1141 EXPECT_TRUE(update_sessions_[1]->IsActive());
1142 EXPECT_TRUE(characteristic->IsNotifying());
1143
1144 // Hide the characteristic. The sessions should become inactive.
1145 fake_bluetooth_gatt_characteristic_client_->HideHeartRateCharacteristics();
1146 EXPECT_EQ(2U, update_sessions_.size());
1147 EXPECT_FALSE(update_sessions_[0]->IsActive());
1148 EXPECT_FALSE(update_sessions_[1]->IsActive());
1149 }
1150
1151 TEST_F(BluetoothGattChromeOSTest, NotifySessionsMadeInactive) {
1152 fake_bluetooth_device_client_->CreateDevice(
1153 dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath),
1154 dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
1155 BluetoothDevice* device =
1156 adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress);
1157 ASSERT_TRUE(device);
1158
1159 TestBluetoothAdapterObserver observer(adapter_);
1160
1161 // Expose the fake Heart Rate service. This will asynchronously expose
1162 // characteristics.
1163 fake_bluetooth_gatt_service_client_->ExposeHeartRateService(
1164 dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath));
1165 ASSERT_EQ(1, observer.gatt_service_added_count());
1166
1167 BluetoothGattService* service =
1168 device->GetGattService(observer.last_gatt_service_id());
1169
1170 EXPECT_EQ(0, observer.gatt_characteristic_value_changed_count());
1171
1172 // Run the message loop so that the characteristics appear.
1173 base::MessageLoop::current()->Run();
1174
1175 BluetoothGattCharacteristic* characteristic = service->GetCharacteristic(
1176 fake_bluetooth_gatt_characteristic_client_->GetHeartRateMeasurementPath()
1177 .value());
1178 ASSERT_TRUE(characteristic);
1179 EXPECT_FALSE(characteristic->IsNotifying());
1180 EXPECT_TRUE(update_sessions_.empty());
1181
1182 // Send several requests to start notifications.
1183 characteristic->StartNotifySession(
1184 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback,
1185 base::Unretained(this)),
1186 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
1187 base::Unretained(this)));
1188 characteristic->StartNotifySession(
1189 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback,
1190 base::Unretained(this)),
1191 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
1192 base::Unretained(this)));
1193 characteristic->StartNotifySession(
1194 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback,
1195 base::Unretained(this)),
1196 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
1197 base::Unretained(this)));
1198 characteristic->StartNotifySession(
1199 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback,
1200 base::Unretained(this)),
1201 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
1202 base::Unretained(this)));
1203
1204 // The operation still hasn't completed but we should have received the first
1205 // notification.
1206 EXPECT_EQ(0, success_callback_count_);
1207 EXPECT_EQ(0, error_callback_count_);
1208 EXPECT_EQ(1, observer.gatt_characteristic_value_changed_count());
1209 EXPECT_TRUE(characteristic->IsNotifying());
1210 EXPECT_TRUE(update_sessions_.empty());
1211
1212 // Run the main loop. The initial call should complete. The queued calls
1213 // should succeed immediately.
1214 base::MessageLoop::current()->Run();
1215
1216 EXPECT_EQ(4, success_callback_count_);
1217 EXPECT_EQ(0, error_callback_count_);
1218 EXPECT_EQ(1, observer.gatt_characteristic_value_changed_count());
1219 EXPECT_TRUE(characteristic->IsNotifying());
1220 EXPECT_EQ(4U, update_sessions_.size());
1221
1222 for (int i = 0; i < 4; i++)
1223 EXPECT_TRUE(update_sessions_[0]->IsActive());
1224
1225 // Stop notifications directly through the client. The sessions should get
1226 // marked as inactive.
1227 fake_bluetooth_gatt_characteristic_client_->StopNotify(
1228 fake_bluetooth_gatt_characteristic_client_->GetHeartRateMeasurementPath(),
1229 base::Bind(&BluetoothGattChromeOSTest::SuccessCallback,
1230 base::Unretained(this)),
1231 base::Bind(&BluetoothGattChromeOSTest::DBusErrorCallback,
1232 base::Unretained(this)));
1233 EXPECT_EQ(5, success_callback_count_);
1234 EXPECT_EQ(0, error_callback_count_);
1235 EXPECT_FALSE(characteristic->IsNotifying());
1236 EXPECT_EQ(4U, update_sessions_.size());
1237
1238 for (int i = 0; i < 4; i++)
1239 EXPECT_FALSE(update_sessions_[0]->IsActive());
1240
1241 // It should be possible to restart notifications and the call should reset
1242 // the session count and make a request through the client.
1243 update_sessions_.clear();
1244 success_callback_count_ = 0;
1245 observer.Reset();
1246 characteristic->StartNotifySession(
1247 base::Bind(&BluetoothGattChromeOSTest::NotifySessionCallback,
1248 base::Unretained(this)),
1249 base::Bind(&BluetoothGattChromeOSTest::ServiceErrorCallback,
1250 base::Unretained(this)));
1251
1252 EXPECT_EQ(0, success_callback_count_);
1253 EXPECT_EQ(0, error_callback_count_);
1254 EXPECT_EQ(1, observer.gatt_characteristic_value_changed_count());
1255 EXPECT_TRUE(characteristic->IsNotifying());
1256 EXPECT_TRUE(update_sessions_.empty());
1257
1258 base::MessageLoop::current()->Run();
1259
1260 EXPECT_EQ(1, success_callback_count_);
1261 EXPECT_EQ(0, error_callback_count_);
1262 EXPECT_EQ(1, observer.gatt_characteristic_value_changed_count());
1263 EXPECT_TRUE(characteristic->IsNotifying());
1264 EXPECT_EQ(1U, update_sessions_.size());
1265 EXPECT_TRUE(update_sessions_[0]->IsActive());
1266 }
1267
1268 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698