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