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