| OLD | NEW |
| (Empty) |
| 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_media_transport_client.h" | |
| 6 | |
| 7 #include "base/bind.h" | |
| 8 #include "base/logging.h" | |
| 9 #include "base/memory/ref_counted.h" | |
| 10 #include "base/observer_list.h" | |
| 11 #include "dbus/bus.h" | |
| 12 #include "dbus/message.h" | |
| 13 #include "dbus/object_manager.h" | |
| 14 #include "dbus/object_proxy.h" | |
| 15 #include "third_party/cros_system_api/dbus/service_constants.h" | |
| 16 | |
| 17 namespace { | |
| 18 | |
| 19 // TODO(mcchou): Add these service constants into dbus/service_constants.h | |
| 20 // later. | |
| 21 const char kBluetoothMediaTransportInterface[] = "org.bluez.MediaTransport1"; | |
| 22 | |
| 23 // Constants used to indicate exceptional error conditions. | |
| 24 const char kNoResponseError[] = "org.chromium.Error.NoResponse"; | |
| 25 const char kUnexpectedResponse[] = "org.chromium.Error.UnexpectedResponse"; | |
| 26 | |
| 27 // Method names of Media Transport interface. | |
| 28 const char kAcquire[] = "Acquire"; | |
| 29 const char kTryAcquire[] = "TryAcquire"; | |
| 30 const char kRelease[] = "Release"; | |
| 31 | |
| 32 } // namespace | |
| 33 | |
| 34 namespace chromeos { | |
| 35 | |
| 36 // static | |
| 37 const char BluetoothMediaTransportClient::kDeviceProperty[] = "Device"; | |
| 38 const char BluetoothMediaTransportClient::kUUIDProperty[] = "UUID"; | |
| 39 const char BluetoothMediaTransportClient::kCodecProperty[] = "Codec"; | |
| 40 const char BluetoothMediaTransportClient::kConfigurationProperty[] = | |
| 41 "Configuration"; | |
| 42 const char BluetoothMediaTransportClient::kStateProperty[] = "State"; | |
| 43 const char BluetoothMediaTransportClient::kDelayProperty[] = "Delay"; | |
| 44 const char BluetoothMediaTransportClient::kVolumeProperty[] = "Volume"; | |
| 45 | |
| 46 // static | |
| 47 const char BluetoothMediaTransportClient::kStateIdle[] = "idle"; | |
| 48 const char BluetoothMediaTransportClient::kStatePending[] = "pending"; | |
| 49 const char BluetoothMediaTransportClient::kStateActive[] = "active"; | |
| 50 | |
| 51 BluetoothMediaTransportClient::Properties::Properties( | |
| 52 dbus::ObjectProxy* object_proxy, | |
| 53 const std::string& interface_name, | |
| 54 const PropertyChangedCallback& callback) | |
| 55 : dbus::PropertySet(object_proxy, interface_name, callback) { | |
| 56 RegisterProperty(kDeviceProperty, &device); | |
| 57 RegisterProperty(kUUIDProperty, &uuid); | |
| 58 RegisterProperty(kCodecProperty, &codec); | |
| 59 RegisterProperty(kConfigurationProperty, &configuration); | |
| 60 RegisterProperty(kStateProperty, &state); | |
| 61 RegisterProperty(kDelayProperty, &delay); | |
| 62 RegisterProperty(kVolumeProperty, &volume); | |
| 63 } | |
| 64 | |
| 65 BluetoothMediaTransportClient::Properties::~Properties() { | |
| 66 } | |
| 67 | |
| 68 class BluetoothMediaTransportClientImpl | |
| 69 : public BluetoothMediaTransportClient, | |
| 70 public dbus::ObjectManager::Interface { | |
| 71 public: | |
| 72 BluetoothMediaTransportClientImpl() | |
| 73 : object_manager_(nullptr), weak_ptr_factory_(this) {} | |
| 74 | |
| 75 ~BluetoothMediaTransportClientImpl() override { | |
| 76 object_manager_->UnregisterInterface(kBluetoothMediaTransportInterface); | |
| 77 } | |
| 78 | |
| 79 // dbus::ObjectManager::Interface overrides. | |
| 80 | |
| 81 dbus::PropertySet* CreateProperties( | |
| 82 dbus::ObjectProxy* object_proxy, | |
| 83 const dbus::ObjectPath& object_path, | |
| 84 const std::string& interface_name) override { | |
| 85 Properties* properties = new Properties( | |
| 86 object_proxy, | |
| 87 interface_name, | |
| 88 base::Bind(&BluetoothMediaTransportClientImpl::OnPropertyChanged, | |
| 89 weak_ptr_factory_.GetWeakPtr(), object_path)); | |
| 90 return properties; | |
| 91 } | |
| 92 | |
| 93 void ObjectAdded(const dbus::ObjectPath& object_path, | |
| 94 const std::string& interface_name) override { | |
| 95 VLOG(1) << "Remote Media Transport added: " << object_path.value(); | |
| 96 FOR_EACH_OBSERVER(BluetoothMediaTransportClient::Observer, | |
| 97 observers_, | |
| 98 MediaTransportAdded(object_path)); | |
| 99 } | |
| 100 | |
| 101 void ObjectRemoved(const dbus::ObjectPath& object_path, | |
| 102 const std::string& interface_name) override { | |
| 103 VLOG(1) << "Remote Media Transport removed: " << object_path.value(); | |
| 104 FOR_EACH_OBSERVER(BluetoothMediaTransportClient::Observer, | |
| 105 observers_, | |
| 106 MediaTransportRemoved(object_path)); | |
| 107 } | |
| 108 | |
| 109 // BluetoothMediaTransportClient overrides. | |
| 110 | |
| 111 void AddObserver(BluetoothMediaTransportClient::Observer* observer) override { | |
| 112 DCHECK(observer); | |
| 113 observers_.AddObserver(observer); | |
| 114 } | |
| 115 | |
| 116 void RemoveObserver( | |
| 117 BluetoothMediaTransportClient::Observer* observer) override { | |
| 118 DCHECK(observer); | |
| 119 observers_.RemoveObserver(observer); | |
| 120 } | |
| 121 | |
| 122 Properties* GetProperties(const dbus::ObjectPath& object_path) override { | |
| 123 DCHECK(object_manager_); | |
| 124 return static_cast<Properties*>( | |
| 125 object_manager_->GetProperties(object_path, | |
| 126 kBluetoothMediaTransportInterface)); | |
| 127 } | |
| 128 | |
| 129 void Acquire(const dbus::ObjectPath& object_path, | |
| 130 const AcquireCallback& callback, | |
| 131 const ErrorCallback& error_callback) override { | |
| 132 VLOG(1) << "Acquire - transport: " << object_path.value(); | |
| 133 | |
| 134 DCHECK(object_manager_); | |
| 135 | |
| 136 dbus::MethodCall method_call(kBluetoothMediaTransportInterface, kAcquire); | |
| 137 | |
| 138 // Get object proxy. | |
| 139 scoped_refptr<dbus::ObjectProxy> object_proxy( | |
| 140 object_manager_->GetObjectProxy(object_path)); | |
| 141 | |
| 142 // Call Acquire method of Media Transport interface. | |
| 143 object_proxy->CallMethodWithErrorCallback( | |
| 144 &method_call, | |
| 145 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, | |
| 146 base::Bind(&BluetoothMediaTransportClientImpl::OnAcquireSuccess, | |
| 147 weak_ptr_factory_.GetWeakPtr(), callback, error_callback), | |
| 148 base::Bind(&BluetoothMediaTransportClientImpl::OnError, | |
| 149 weak_ptr_factory_.GetWeakPtr(), error_callback)); | |
| 150 } | |
| 151 | |
| 152 void TryAcquire(const dbus::ObjectPath& object_path, | |
| 153 const AcquireCallback& callback, | |
| 154 const ErrorCallback& error_callback) override { | |
| 155 VLOG(1) << "TryAcquire - transport: " << object_path.value(); | |
| 156 | |
| 157 DCHECK(object_manager_); | |
| 158 | |
| 159 dbus::MethodCall method_call(kBluetoothMediaTransportInterface, | |
| 160 kTryAcquire); | |
| 161 | |
| 162 // Get object proxy. | |
| 163 scoped_refptr<dbus::ObjectProxy> object_proxy( | |
| 164 object_manager_->GetObjectProxy(object_path)); | |
| 165 | |
| 166 // Call TryAcquire method of Media Transport interface. | |
| 167 object_proxy->CallMethodWithErrorCallback( | |
| 168 &method_call, | |
| 169 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, | |
| 170 base::Bind(&BluetoothMediaTransportClientImpl::OnAcquireSuccess, | |
| 171 weak_ptr_factory_.GetWeakPtr(), callback, error_callback), | |
| 172 base::Bind(&BluetoothMediaTransportClientImpl::OnError, | |
| 173 weak_ptr_factory_.GetWeakPtr(), error_callback)); | |
| 174 } | |
| 175 | |
| 176 void Release(const dbus::ObjectPath& object_path, | |
| 177 const base::Closure& callback, | |
| 178 const ErrorCallback& error_callback) override { | |
| 179 VLOG(1) << "Release - transport: " << object_path.value(); | |
| 180 | |
| 181 DCHECK(object_manager_); | |
| 182 | |
| 183 dbus::MethodCall method_call(kBluetoothMediaTransportInterface, kRelease); | |
| 184 | |
| 185 // Get object proxy. | |
| 186 scoped_refptr<dbus::ObjectProxy> object_proxy( | |
| 187 object_manager_->GetObjectProxy(object_path)); | |
| 188 | |
| 189 // Call TryAcquire method of Media Transport interface. | |
| 190 object_proxy->CallMethodWithErrorCallback( | |
| 191 &method_call, | |
| 192 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, | |
| 193 base::Bind(&BluetoothMediaTransportClientImpl::OnSuccess, | |
| 194 weak_ptr_factory_.GetWeakPtr(), callback), | |
| 195 base::Bind(&BluetoothMediaTransportClientImpl::OnError, | |
| 196 weak_ptr_factory_.GetWeakPtr(), error_callback)); | |
| 197 } | |
| 198 | |
| 199 protected: | |
| 200 void Init(dbus::Bus* bus) override { | |
| 201 DCHECK(bus); | |
| 202 object_manager_ = bus->GetObjectManager( | |
| 203 bluetooth_object_manager::kBluetoothObjectManagerServiceName, | |
| 204 dbus::ObjectPath( | |
| 205 bluetooth_object_manager::kBluetoothObjectManagerServicePath)); | |
| 206 object_manager_->RegisterInterface(kBluetoothMediaTransportInterface, | |
| 207 this); | |
| 208 } | |
| 209 | |
| 210 private: | |
| 211 // Called by dbus::PropertySet when a property value is changed. | |
| 212 void OnPropertyChanged(const dbus::ObjectPath& object_path, | |
| 213 const std::string& property_name) { | |
| 214 VLOG(1) << "Name of the changed property: " << property_name; | |
| 215 | |
| 216 // Dispatches the change to the corresponding property-changed handler. | |
| 217 FOR_EACH_OBSERVER( | |
| 218 BluetoothMediaTransportClient::Observer, observers_, | |
| 219 MediaTransportPropertyChanged(object_path, property_name)); | |
| 220 } | |
| 221 | |
| 222 // Called when a response for successful method call is received. | |
| 223 void OnSuccess(const base::Closure& callback, | |
| 224 dbus::Response* response) { | |
| 225 DCHECK(response); | |
| 226 callback.Run(); | |
| 227 } | |
| 228 | |
| 229 // Called when a response for |Acquire|/|TryAcquire| method call is received. | |
| 230 void OnAcquireSuccess(const AcquireCallback& callback, | |
| 231 const ErrorCallback& error_callback, | |
| 232 dbus::Response* response) { | |
| 233 DCHECK(response); | |
| 234 | |
| 235 dbus::FileDescriptor fd; | |
| 236 uint16_t read_mtu; | |
| 237 uint16_t write_mtu; | |
| 238 | |
| 239 // Parse the response. | |
| 240 dbus::MessageReader reader(response); | |
| 241 if (reader.PopFileDescriptor(&fd) && | |
| 242 reader.PopUint16(&read_mtu) && | |
| 243 reader.PopUint16(&write_mtu)) { | |
| 244 fd.CheckValidity(); | |
| 245 DCHECK(fd.is_valid()); | |
| 246 | |
| 247 VLOG(1) << "OnAcquireSuccess - fd: "<< fd.value() | |
| 248 <<", read MTU: " << read_mtu | |
| 249 <<", write MTU: " << write_mtu; | |
| 250 | |
| 251 // The ownership of the file descriptor is transferred to the user | |
| 252 // application. | |
| 253 callback.Run(&fd, read_mtu, write_mtu); | |
| 254 return; | |
| 255 } | |
| 256 | |
| 257 error_callback.Run( | |
| 258 kUnexpectedResponse, | |
| 259 "Failed to retrieve file descriptor, read MTU and write MTU."); | |
| 260 } | |
| 261 | |
| 262 // Called when a response for a failed method call is received. | |
| 263 void OnError(const ErrorCallback& error_callback, | |
| 264 dbus::ErrorResponse* response) { | |
| 265 DCHECK(response); | |
| 266 | |
| 267 // Error response has optional error message argument. | |
| 268 std::string error_name; | |
| 269 std::string error_message; | |
| 270 if (response) { | |
| 271 dbus::MessageReader reader(response); | |
| 272 error_name = response->GetErrorName(); | |
| 273 reader.PopString(&error_message); | |
| 274 } else { | |
| 275 error_name = kNoResponseError; | |
| 276 } | |
| 277 error_callback.Run(error_name, error_message); | |
| 278 } | |
| 279 | |
| 280 dbus::ObjectManager* object_manager_; | |
| 281 | |
| 282 // List of observers interested in event notifications from us. | |
| 283 base::ObserverList<BluetoothMediaTransportClient::Observer> observers_; | |
| 284 | |
| 285 base::WeakPtrFactory<BluetoothMediaTransportClientImpl> weak_ptr_factory_; | |
| 286 | |
| 287 DISALLOW_COPY_AND_ASSIGN(BluetoothMediaTransportClientImpl); | |
| 288 }; | |
| 289 | |
| 290 BluetoothMediaTransportClient::BluetoothMediaTransportClient() { | |
| 291 } | |
| 292 | |
| 293 BluetoothMediaTransportClient::~BluetoothMediaTransportClient() { | |
| 294 } | |
| 295 | |
| 296 BluetoothMediaTransportClient* BluetoothMediaTransportClient::Create() { | |
| 297 return new BluetoothMediaTransportClientImpl(); | |
| 298 } | |
| 299 | |
| 300 } // namespace chromeos | |
| OLD | NEW |