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.
5 #include "chromeos/dbus/bluetooth_media_transport_client.h"
8 #include "base/logging.h"
9 #include "base/memory/ref_counted.h"
10 #include "base/observer_list.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"
19 // TODO(mcchou): Add these service constants into dbus/service_constants.h
21 const char kBluetoothMediaTransportInterface
[] = "org.bluez.MediaTransport1";
23 // Constants used to indicate exceptional error conditions.
24 const char kNoResponseError
[] = "org.chromium.Error.NoResponse";
25 const char kUnexpectedResponse
[] = "org.chromium.Error.UnexpectedResponse";
27 // Method names of Media Transport interface.
28 const char kAcquire
[] = "Acquire";
29 const char kTryAcquire
[] = "TryAcquire";
30 const char kRelease
[] = "Release";
37 const char BluetoothMediaTransportClient::kDeviceProperty
[] = "Device";
38 const char BluetoothMediaTransportClient::kUUIDProperty
[] = "UUID";
39 const char BluetoothMediaTransportClient::kCodecProperty
[] = "Codec";
40 const char BluetoothMediaTransportClient::kConfigurationProperty
[] =
42 const char BluetoothMediaTransportClient::kStateProperty
[] = "State";
43 const char BluetoothMediaTransportClient::kDelayProperty
[] = "Delay";
44 const char BluetoothMediaTransportClient::kVolumeProperty
[] = "Volume";
47 const char BluetoothMediaTransportClient::kStateIdle
[] = "idle";
48 const char BluetoothMediaTransportClient::kStatePending
[] = "pending";
49 const char BluetoothMediaTransportClient::kStateActive
[] = "active";
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
);
65 BluetoothMediaTransportClient::Properties::~Properties() {
68 class BluetoothMediaTransportClientImpl
69 : public BluetoothMediaTransportClient
,
70 public dbus::ObjectManager::Interface
{
72 BluetoothMediaTransportClientImpl()
73 : object_manager_(nullptr), weak_ptr_factory_(this) {}
75 ~BluetoothMediaTransportClientImpl() override
{
76 object_manager_
->UnregisterInterface(kBluetoothMediaTransportInterface
);
79 // dbus::ObjectManager::Interface overrides.
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(
88 base::Bind(&BluetoothMediaTransportClientImpl::OnPropertyChanged
,
89 weak_ptr_factory_
.GetWeakPtr(), object_path
));
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
,
98 MediaTransportAdded(object_path
));
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
,
106 MediaTransportRemoved(object_path
));
109 // BluetoothMediaTransportClient overrides.
111 void AddObserver(BluetoothMediaTransportClient::Observer
* observer
) override
{
113 observers_
.AddObserver(observer
);
117 BluetoothMediaTransportClient::Observer
* observer
) override
{
119 observers_
.RemoveObserver(observer
);
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
));
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();
134 DCHECK(object_manager_
);
136 dbus::MethodCall
method_call(kBluetoothMediaTransportInterface
, kAcquire
);
139 scoped_refptr
<dbus::ObjectProxy
> object_proxy(
140 object_manager_
->GetObjectProxy(object_path
));
142 // Call Acquire method of Media Transport interface.
143 object_proxy
->CallMethodWithErrorCallback(
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
));
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();
157 DCHECK(object_manager_
);
159 dbus::MethodCall
method_call(kBluetoothMediaTransportInterface
,
163 scoped_refptr
<dbus::ObjectProxy
> object_proxy(
164 object_manager_
->GetObjectProxy(object_path
));
166 // Call TryAcquire method of Media Transport interface.
167 object_proxy
->CallMethodWithErrorCallback(
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
));
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();
181 DCHECK(object_manager_
);
183 dbus::MethodCall
method_call(kBluetoothMediaTransportInterface
, kRelease
);
186 scoped_refptr
<dbus::ObjectProxy
> object_proxy(
187 object_manager_
->GetObjectProxy(object_path
));
189 // Call TryAcquire method of Media Transport interface.
190 object_proxy
->CallMethodWithErrorCallback(
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
));
200 void Init(dbus::Bus
* bus
) override
{
202 object_manager_
= bus
->GetObjectManager(
203 bluetooth_object_manager::kBluetoothObjectManagerServiceName
,
205 bluetooth_object_manager::kBluetoothObjectManagerServicePath
));
206 object_manager_
->RegisterInterface(kBluetoothMediaTransportInterface
,
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
;
216 // Dispatches the change to the corresponding property-changed handler.
218 BluetoothMediaTransportClient::Observer
, observers_
,
219 MediaTransportPropertyChanged(object_path
, property_name
));
222 // Called when a response for successful method call is received.
223 void OnSuccess(const base::Closure
& callback
,
224 dbus::Response
* response
) {
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
) {
235 dbus::FileDescriptor fd
;
239 // Parse the response.
240 dbus::MessageReader
reader(response
);
241 if (reader
.PopFileDescriptor(&fd
) &&
242 reader
.PopUint16(&read_mtu
) &&
243 reader
.PopUint16(&write_mtu
)) {
245 DCHECK(fd
.is_valid());
247 VLOG(1) << "OnAcquireSuccess - fd: "<< fd
.value()
248 <<", read MTU: " << read_mtu
249 <<", write MTU: " << write_mtu
;
251 // The ownership of the file descriptor is transferred to the user
253 callback
.Run(&fd
, read_mtu
, write_mtu
);
259 "Failed to retrieve file descriptor, read MTU and write MTU.");
262 // Called when a response for a failed method call is received.
263 void OnError(const ErrorCallback
& error_callback
,
264 dbus::ErrorResponse
* response
) {
267 // Error response has optional error message argument.
268 std::string error_name
;
269 std::string error_message
;
271 dbus::MessageReader
reader(response
);
272 error_name
= response
->GetErrorName();
273 reader
.PopString(&error_message
);
275 error_name
= kNoResponseError
;
277 error_callback
.Run(error_name
, error_message
);
280 dbus::ObjectManager
* object_manager_
;
282 // List of observers interested in event notifications from us.
283 ObserverList
<BluetoothMediaTransportClient::Observer
> observers_
;
285 base::WeakPtrFactory
<BluetoothMediaTransportClientImpl
> weak_ptr_factory_
;
287 DISALLOW_COPY_AND_ASSIGN(BluetoothMediaTransportClientImpl
);
290 BluetoothMediaTransportClient::BluetoothMediaTransportClient() {
293 BluetoothMediaTransportClient::~BluetoothMediaTransportClient() {
296 BluetoothMediaTransportClient
* BluetoothMediaTransportClient::Create() {
297 return new BluetoothMediaTransportClientImpl();
300 } // namespace chromeos