Home | History | Annotate | Download | only in bluetooth
      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
   1321