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/bluetooth_gatt_descriptor_client.h" 6 7 #include "base/bind.h" 8 #include "base/memory/weak_ptr.h" 9 #include "base/observer_list.h" 10 #include "dbus/bus.h" 11 #include "dbus/object_manager.h" 12 #include "third_party/cros_system_api/dbus/service_constants.h" 13 14 namespace chromeos { 15 16 // static 17 const char BluetoothGattDescriptorClient::kNoResponseError[] = 18 "org.chromium.Error.NoResponse"; 19 // static 20 const char BluetoothGattDescriptorClient::kUnknownDescriptorError[] = 21 "org.chromium.Error.UnknownDescriptor"; 22 23 BluetoothGattDescriptorClient::Properties::Properties( 24 dbus::ObjectProxy* object_proxy, 25 const std::string& interface_name, 26 const PropertyChangedCallback&callback) 27 : dbus::PropertySet(object_proxy, interface_name, callback) { 28 RegisterProperty(bluetooth_gatt_descriptor::kUUIDProperty, &uuid); 29 RegisterProperty(bluetooth_gatt_descriptor::kCharacteristicProperty, 30 &characteristic); 31 } 32 33 BluetoothGattDescriptorClient::Properties::~Properties() { 34 } 35 36 // The BluetoothGattDescriptorClient implementation used in production. 37 class BluetoothGattDescriptorClientImpl 38 : public BluetoothGattDescriptorClient, 39 public dbus::ObjectManager::Interface { 40 public: 41 BluetoothGattDescriptorClientImpl() 42 : object_manager_(NULL), 43 weak_ptr_factory_(this) { 44 } 45 46 virtual ~BluetoothGattDescriptorClientImpl() { 47 object_manager_->UnregisterInterface( 48 bluetooth_gatt_descriptor::kBluetoothGattDescriptorInterface); 49 } 50 51 // BluetoothGattDescriptorClientImpl override. 52 virtual void AddObserver( 53 BluetoothGattDescriptorClient::Observer* observer) OVERRIDE { 54 DCHECK(observer); 55 observers_.AddObserver(observer); 56 } 57 58 // BluetoothGattDescriptorClientImpl override. 59 virtual void RemoveObserver( 60 BluetoothGattDescriptorClient::Observer* observer) OVERRIDE { 61 DCHECK(observer); 62 observers_.RemoveObserver(observer); 63 } 64 65 // BluetoothGattDescriptorClientImpl override. 66 virtual std::vector<dbus::ObjectPath> GetDescriptors() OVERRIDE { 67 DCHECK(object_manager_); 68 return object_manager_->GetObjectsWithInterface( 69 bluetooth_gatt_descriptor::kBluetoothGattDescriptorInterface); 70 } 71 72 // BluetoothGattDescriptorClientImpl override. 73 virtual Properties* GetProperties( 74 const dbus::ObjectPath& object_path) OVERRIDE { 75 DCHECK(object_manager_); 76 return static_cast<Properties*>( 77 object_manager_->GetProperties( 78 object_path, 79 bluetooth_gatt_descriptor::kBluetoothGattDescriptorInterface)); 80 } 81 82 // BluetoothGattDescriptorClientImpl override. 83 virtual void ReadValue(const dbus::ObjectPath& object_path, 84 const ValueCallback& callback, 85 const ErrorCallback& error_callback) OVERRIDE { 86 dbus::ObjectProxy* object_proxy = 87 object_manager_->GetObjectProxy(object_path); 88 if (!object_proxy) { 89 error_callback.Run(kUnknownDescriptorError, ""); 90 return; 91 } 92 93 dbus::MethodCall method_call( 94 bluetooth_gatt_descriptor::kBluetoothGattDescriptorInterface, 95 bluetooth_gatt_descriptor::kReadValue); 96 97 object_proxy->CallMethodWithErrorCallback( 98 &method_call, 99 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 100 base::Bind(&BluetoothGattDescriptorClientImpl::OnValueSuccess, 101 weak_ptr_factory_.GetWeakPtr(), 102 callback), 103 base::Bind(&BluetoothGattDescriptorClientImpl::OnError, 104 weak_ptr_factory_.GetWeakPtr(), 105 error_callback)); 106 } 107 108 // BluetoothGattDescriptorClientImpl override. 109 virtual void WriteValue(const dbus::ObjectPath& object_path, 110 const std::vector<uint8>& value, 111 const base::Closure& callback, 112 const ErrorCallback& error_callback) OVERRIDE { 113 dbus::ObjectProxy* object_proxy = 114 object_manager_->GetObjectProxy(object_path); 115 if (!object_proxy) { 116 error_callback.Run(kUnknownDescriptorError, ""); 117 return; 118 } 119 120 dbus::MethodCall method_call( 121 bluetooth_gatt_descriptor::kBluetoothGattDescriptorInterface, 122 bluetooth_gatt_descriptor::kWriteValue); 123 dbus::MessageWriter writer(&method_call); 124 writer.AppendArrayOfBytes(value.data(), value.size()); 125 126 object_proxy->CallMethodWithErrorCallback( 127 &method_call, 128 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 129 base::Bind(&BluetoothGattDescriptorClientImpl::OnSuccess, 130 weak_ptr_factory_.GetWeakPtr(), 131 callback), 132 base::Bind(&BluetoothGattDescriptorClientImpl::OnError, 133 weak_ptr_factory_.GetWeakPtr(), 134 error_callback)); 135 } 136 137 // dbus::ObjectManager::Interface override. 138 virtual dbus::PropertySet* CreateProperties( 139 dbus::ObjectProxy *object_proxy, 140 const dbus::ObjectPath& object_path, 141 const std::string& interface_name) OVERRIDE { 142 Properties* properties = new Properties( 143 object_proxy, 144 interface_name, 145 base::Bind(&BluetoothGattDescriptorClientImpl::OnPropertyChanged, 146 weak_ptr_factory_.GetWeakPtr(), 147 object_path)); 148 return static_cast<dbus::PropertySet*>(properties); 149 } 150 151 // dbus::ObjectManager::Interface override. 152 virtual void ObjectAdded(const dbus::ObjectPath& object_path, 153 const std::string& interface_name) OVERRIDE { 154 VLOG(2) << "Remote GATT descriptor added: " << object_path.value(); 155 FOR_EACH_OBSERVER(BluetoothGattDescriptorClient::Observer, observers_, 156 GattDescriptorAdded(object_path)); 157 } 158 159 // dbus::ObjectManager::Interface override. 160 virtual void ObjectRemoved(const dbus::ObjectPath& object_path, 161 const std::string& interface_name) OVERRIDE { 162 VLOG(2) << "Remote GATT descriptor removed: " << object_path.value(); 163 FOR_EACH_OBSERVER(BluetoothGattDescriptorClient::Observer, observers_, 164 GattDescriptorRemoved(object_path)); 165 } 166 167 protected: 168 // chromeos::DBusClient override. 169 virtual void Init(dbus::Bus* bus) OVERRIDE { 170 object_manager_ = bus->GetObjectManager( 171 bluetooth_object_manager::kBluetoothObjectManagerServiceName, 172 dbus::ObjectPath( 173 bluetooth_object_manager::kBluetoothObjectManagerServicePath)); 174 object_manager_->RegisterInterface( 175 bluetooth_gatt_descriptor::kBluetoothGattDescriptorInterface, 176 this); 177 } 178 179 private: 180 // Called by dbus::PropertySet when a property value is changed, either by 181 // result of a signal or response to a GetAll() or Get() call. Informs 182 // observers. 183 virtual void OnPropertyChanged(const dbus::ObjectPath& object_path, 184 const std::string& property_name) { 185 VLOG(2) << "Remote GATT descriptor property changed: " 186 << object_path.value() << ": " << property_name; 187 FOR_EACH_OBSERVER(BluetoothGattDescriptorClient::Observer, observers_, 188 GattDescriptorPropertyChanged(object_path, 189 property_name)); 190 } 191 192 // Called when a response for a successful method call is received. 193 void OnSuccess(const base::Closure& callback, dbus::Response* response) { 194 DCHECK(response); 195 callback.Run(); 196 } 197 198 // Called when a descriptor value response for a successful method call is 199 // received. 200 void OnValueSuccess(const ValueCallback& callback, dbus::Response* response) { 201 DCHECK(response); 202 dbus::MessageReader reader(response); 203 204 const uint8* bytes = NULL; 205 size_t length = 0; 206 207 if (!reader.PopArrayOfBytes(&bytes, &length)) 208 VLOG(2) << "Error reading array of bytes in ValueCallback"; 209 210 std::vector<uint8> value; 211 212 if (bytes) 213 value.assign(bytes, bytes + length); 214 215 callback.Run(value); 216 } 217 218 // Called when a response for a failed method call is received. 219 void OnError(const ErrorCallback& error_callback, 220 dbus::ErrorResponse* response) { 221 // Error response has optional error message argument. 222 std::string error_name; 223 std::string error_message; 224 if (response) { 225 dbus::MessageReader reader(response); 226 error_name = response->GetErrorName(); 227 reader.PopString(&error_message); 228 } else { 229 error_name = kNoResponseError; 230 error_message = ""; 231 } 232 error_callback.Run(error_name, error_message); 233 } 234 235 dbus::ObjectManager* object_manager_; 236 237 // List of observers interested in event notifications from us. 238 ObserverList<BluetoothGattDescriptorClient::Observer> observers_; 239 240 // Weak pointer factory for generating 'this' pointers that might live longer 241 // than we do. 242 // Note: This should remain the last member so it'll be destroyed and 243 // invalidate its weak pointers before any other members are destroyed. 244 base::WeakPtrFactory<BluetoothGattDescriptorClientImpl> weak_ptr_factory_; 245 246 DISALLOW_COPY_AND_ASSIGN(BluetoothGattDescriptorClientImpl); 247 }; 248 249 BluetoothGattDescriptorClient::BluetoothGattDescriptorClient() { 250 } 251 252 BluetoothGattDescriptorClient::~BluetoothGattDescriptorClient() { 253 } 254 255 // static 256 BluetoothGattDescriptorClient* BluetoothGattDescriptorClient::Create() { 257 return new BluetoothGattDescriptorClientImpl(); 258 } 259 260 } // namespace chromeos 261