Home | History | Annotate | Download | only in dbus
      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 "chromeos/dbus/fake_bluetooth_gatt_service_client.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/message_loop/message_loop.h"
      9 #include "base/time/time.h"
     10 #include "chromeos/dbus/dbus_thread_manager.h"
     11 #include "chromeos/dbus/fake_bluetooth_gatt_characteristic_client.h"
     12 #include "third_party/cros_system_api/dbus/service_constants.h"
     13 
     14 namespace chromeos {
     15 
     16 namespace {
     17 
     18 const int kExposeCharacteristicsDelayIntervalMs = 100;
     19 
     20 }  // namespace
     21 
     22 // static
     23 const char FakeBluetoothGattServiceClient::kHeartRateServicePathComponent[] =
     24     "service0000";
     25 const char FakeBluetoothGattServiceClient::kHeartRateServiceUUID[] =
     26     "0000180d-0000-1000-8000-00805f9b34fb";
     27 
     28 FakeBluetoothGattServiceClient::Properties::Properties(
     29     const PropertyChangedCallback& callback)
     30     : BluetoothGattServiceClient::Properties(
     31         NULL,
     32         bluetooth_gatt_service::kBluetoothGattServiceInterface,
     33         callback) {
     34 }
     35 
     36 FakeBluetoothGattServiceClient::Properties::~Properties() {
     37 }
     38 
     39 void FakeBluetoothGattServiceClient::Properties::Get(
     40     dbus::PropertyBase* property,
     41     dbus::PropertySet::GetCallback callback) {
     42   VLOG(1) << "Get " << property->name();
     43   callback.Run(false);
     44 }
     45 
     46 void FakeBluetoothGattServiceClient::Properties::GetAll() {
     47   VLOG(1) << "GetAll";
     48 }
     49 
     50 void FakeBluetoothGattServiceClient::Properties::Set(
     51     dbus::PropertyBase* property,
     52     dbus::PropertySet::GetCallback callback) {
     53   VLOG(1) << "Set " << property->name();
     54   callback.Run(false);
     55 }
     56 
     57 FakeBluetoothGattServiceClient::FakeBluetoothGattServiceClient()
     58     : weak_ptr_factory_(this) {
     59 }
     60 
     61 FakeBluetoothGattServiceClient::~FakeBluetoothGattServiceClient() {
     62 }
     63 
     64 void FakeBluetoothGattServiceClient::Init(dbus::Bus* bus) {
     65 }
     66 
     67 void FakeBluetoothGattServiceClient::AddObserver(Observer* observer) {
     68   observers_.AddObserver(observer);
     69 }
     70 
     71 void FakeBluetoothGattServiceClient::RemoveObserver(Observer* observer) {
     72   observers_.RemoveObserver(observer);
     73 }
     74 
     75 std::vector<dbus::ObjectPath> FakeBluetoothGattServiceClient::GetServices() {
     76   std::vector<dbus::ObjectPath> paths;
     77   if (heart_rate_service_properties_.get()) {
     78     DCHECK(!heart_rate_service_path_.empty());
     79     paths.push_back(dbus::ObjectPath(heart_rate_service_path_));
     80   }
     81   return paths;
     82 }
     83 
     84 FakeBluetoothGattServiceClient::Properties*
     85 FakeBluetoothGattServiceClient::GetProperties(
     86     const dbus::ObjectPath& object_path) {
     87   if (object_path.value() == heart_rate_service_path_)
     88     return heart_rate_service_properties_.get();
     89   return NULL;
     90 }
     91 
     92 void FakeBluetoothGattServiceClient::ExposeHeartRateService(
     93     const dbus::ObjectPath& device_path) {
     94   if (IsHeartRateVisible()) {
     95     DCHECK(!heart_rate_service_path_.empty());
     96     VLOG(1) << "Fake Heart Rate Service already exposed.";
     97     return;
     98   }
     99   VLOG(2) << "Exposing fake Heart Rate Service.";
    100   heart_rate_service_path_ =
    101       device_path.value() + "/" + kHeartRateServicePathComponent;
    102   heart_rate_service_properties_.reset(new Properties(base::Bind(
    103       &FakeBluetoothGattServiceClient::OnPropertyChanged,
    104       base::Unretained(this),
    105       dbus::ObjectPath(heart_rate_service_path_))));
    106   heart_rate_service_properties_->uuid.ReplaceValue(kHeartRateServiceUUID);
    107   heart_rate_service_properties_->device.ReplaceValue(device_path);
    108   heart_rate_service_properties_->primary.ReplaceValue(true);
    109 
    110   NotifyServiceAdded(dbus::ObjectPath(heart_rate_service_path_));
    111 
    112   base::MessageLoop::current()->PostDelayedTask(
    113       FROM_HERE,
    114       base::Bind(
    115           &FakeBluetoothGattServiceClient::ExposeHeartRateCharacteristics,
    116           weak_ptr_factory_.GetWeakPtr()),
    117           base::TimeDelta::FromMilliseconds(
    118               kExposeCharacteristicsDelayIntervalMs));
    119 }
    120 
    121 void FakeBluetoothGattServiceClient::HideHeartRateService() {
    122   if (!IsHeartRateVisible()) {
    123     DCHECK(heart_rate_service_path_.empty());
    124     VLOG(1) << "Fake Heart Rate Service already hidden.";
    125     return;
    126   }
    127   VLOG(2) << "Hiding fake Heart Rate Service.";
    128   FakeBluetoothGattCharacteristicClient* char_client =
    129       static_cast<FakeBluetoothGattCharacteristicClient*>(
    130           DBusThreadManager::Get()->GetBluetoothGattCharacteristicClient());
    131   char_client->HideHeartRateCharacteristics();
    132 
    133   // Notify observers before deleting the properties structure so that it
    134   // can be accessed from the observer method.
    135   NotifyServiceRemoved(dbus::ObjectPath(heart_rate_service_path_));
    136 
    137   heart_rate_service_properties_.reset();
    138   heart_rate_service_path_.clear();
    139 }
    140 
    141 bool FakeBluetoothGattServiceClient::IsHeartRateVisible() const {
    142   return !!heart_rate_service_properties_.get();
    143 }
    144 
    145 dbus::ObjectPath
    146 FakeBluetoothGattServiceClient::GetHeartRateServicePath() const {
    147   return dbus::ObjectPath(heart_rate_service_path_);
    148 }
    149 
    150 void FakeBluetoothGattServiceClient::OnPropertyChanged(
    151     const dbus::ObjectPath& object_path,
    152     const std::string& property_name) {
    153   VLOG(2) << "Fake GATT Service property changed: " << object_path.value()
    154           << ": " << property_name;
    155   FOR_EACH_OBSERVER(BluetoothGattServiceClient::Observer, observers_,
    156                     GattServicePropertyChanged(object_path, property_name));
    157 }
    158 
    159 void FakeBluetoothGattServiceClient::NotifyServiceAdded(
    160     const dbus::ObjectPath& object_path) {
    161   VLOG(2) << "GATT service added: " << object_path.value();
    162   FOR_EACH_OBSERVER(
    163       BluetoothGattServiceClient::Observer, observers_,
    164       GattServiceAdded(object_path));
    165 }
    166 
    167 void FakeBluetoothGattServiceClient::NotifyServiceRemoved(
    168     const dbus::ObjectPath& object_path) {
    169   VLOG(2) << "GATT service removed: " << object_path.value();
    170   FOR_EACH_OBSERVER(
    171       BluetoothGattServiceClient::Observer, observers_,
    172       GattServiceRemoved(object_path));
    173 }
    174 
    175 void FakeBluetoothGattServiceClient::ExposeHeartRateCharacteristics() {
    176   if (!IsHeartRateVisible()) {
    177     VLOG(2) << "Heart Rate service not visible. Not exposing characteristics.";
    178     return;
    179   }
    180   FakeBluetoothGattCharacteristicClient* char_client =
    181       static_cast<FakeBluetoothGattCharacteristicClient*>(
    182           DBusThreadManager::Get()->GetBluetoothGattCharacteristicClient());
    183   char_client->ExposeHeartRateCharacteristics(
    184       dbus::ObjectPath(heart_rate_service_path_));
    185 
    186   std::vector<dbus::ObjectPath> char_paths;
    187   char_paths.push_back(char_client->GetHeartRateMeasurementPath());
    188   char_paths.push_back(char_client->GetBodySensorLocationPath());
    189   char_paths.push_back(char_client->GetHeartRateControlPointPath());
    190 
    191   heart_rate_service_properties_->characteristics.ReplaceValue(char_paths);
    192 }
    193 
    194 }  // namespace chromeos
    195