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 // Method names of Media Transport interface.
24 const char kAcquire
[] = "Acquire";
25 const char kTryAcquire
[] = "TryAcquire";
26 const char kRelease
[] = "Release";
28 // Property names of Media Transport interface.
29 const char kDeviceProperty
[] = "Device";
30 const char kUUIDProperty
[] = "UUID";
31 const char kCodecProperty
[] = "Codec";
32 const char kConfigurationProperty
[] = "Configuration";
33 const char kStateProperty
[] = "State";
34 const char kDelayProperty
[] = "Delay";
35 const char kVolumeProperty
[] = "Volume";
41 const char BluetoothMediaTransportClient::kNoResponseError
[] =
42 "org.chromium.Error.NoResponse";
43 const char BluetoothMediaTransportClient::kUnexpectedResponse
[] =
44 "org.chromium.Error.UnexpectedResponse";
46 BluetoothMediaTransportClient::Properties::Properties(
47 dbus::ObjectProxy
* object_proxy
,
48 const std::string
& interface_name
,
49 const PropertyChangedCallback
& callback
)
50 : dbus::PropertySet(object_proxy
, interface_name
, callback
) {
51 RegisterProperty(kDeviceProperty
, &device
);
52 RegisterProperty(kUUIDProperty
, &uuid
);
53 RegisterProperty(kCodecProperty
, &codec
);
54 RegisterProperty(kConfigurationProperty
, &configuration
);
55 RegisterProperty(kStateProperty
, &state
);
56 RegisterProperty(kDelayProperty
, &delay
);
57 RegisterProperty(kVolumeProperty
, &volume
);
60 BluetoothMediaTransportClient::Properties::~Properties() {
63 class BluetoothMediaTransportClientImpl
64 : public BluetoothMediaTransportClient
,
65 public dbus::ObjectManager::Interface
{
67 BluetoothMediaTransportClientImpl()
68 : object_manager_(nullptr), weak_ptr_factory_(this) {}
70 ~BluetoothMediaTransportClientImpl() override
{
71 object_manager_
->UnregisterInterface(kBluetoothMediaTransportInterface
);
74 // dbus::ObjectManager::Interface overrides.
76 dbus::PropertySet
* CreateProperties(
77 dbus::ObjectProxy
* object_proxy
,
78 const dbus::ObjectPath
& object_path
,
79 const std::string
& interface_name
) override
{
80 Properties
* properties
= new Properties(
83 base::Bind(&BluetoothMediaTransportClientImpl::OnPropertyChanged
,
84 weak_ptr_factory_
.GetWeakPtr(), object_path
));
88 void ObjectAdded(const dbus::ObjectPath
& object_path
,
89 const std::string
& interface_name
) override
{
90 VLOG(1) << "Remote Media Transport added: " << object_path
.value();
91 FOR_EACH_OBSERVER(BluetoothMediaTransportClient::Observer
,
93 MediaTransportAdded(object_path
));
96 void ObjectRemoved(const dbus::ObjectPath
& object_path
,
97 const std::string
& interface_name
) override
{
98 VLOG(1) << "Remote Media Transport removed: " << object_path
.value();
99 FOR_EACH_OBSERVER(BluetoothMediaTransportClient::Observer
,
101 MediaTransportRemoved(object_path
));
104 // BluetoothMediaTransportClient overrides.
106 void AddObserver(BluetoothMediaTransportClient::Observer
* observer
) override
{
108 observers_
.AddObserver(observer
);
112 BluetoothMediaTransportClient::Observer
* observer
) override
{
114 observers_
.RemoveObserver(observer
);
117 Properties
* GetProperties(const dbus::ObjectPath
& object_path
) override
{
118 DCHECK(object_manager_
);
119 return static_cast<Properties
*>(
120 object_manager_
->GetProperties(object_path
,
121 kBluetoothMediaTransportInterface
));
124 void Acquire(const dbus::ObjectPath
& object_path
,
125 const AcquireCallback
& callback
,
126 const ErrorCallback
& error_callback
) override
{
127 DCHECK(object_manager_
);
129 dbus::MethodCall
method_call(kBluetoothMediaTransportInterface
, kAcquire
);
132 scoped_refptr
<dbus::ObjectProxy
> object_proxy(
133 object_manager_
->GetObjectProxy(object_path
));
135 // Call Acquire method of Media Transport interface.
136 object_proxy
->CallMethodWithErrorCallback(
138 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
139 base::Bind(&BluetoothMediaTransportClientImpl::OnAcquireSuccess
,
140 weak_ptr_factory_
.GetWeakPtr(), callback
, error_callback
),
141 base::Bind(&BluetoothMediaTransportClientImpl::OnError
,
142 weak_ptr_factory_
.GetWeakPtr(), error_callback
));
145 void TryAcquire(const dbus::ObjectPath
& object_path
,
146 const AcquireCallback
& callback
,
147 const ErrorCallback
& error_callback
) override
{
148 DCHECK(object_manager_
);
150 dbus::MethodCall
method_call(kBluetoothMediaTransportInterface
,
154 scoped_refptr
<dbus::ObjectProxy
> object_proxy(
155 object_manager_
->GetObjectProxy(object_path
));
157 // Call TryAcquire method of Media Transport interface.
158 object_proxy
->CallMethodWithErrorCallback(
160 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
161 base::Bind(&BluetoothMediaTransportClientImpl::OnAcquireSuccess
,
162 weak_ptr_factory_
.GetWeakPtr(), callback
, error_callback
),
163 base::Bind(&BluetoothMediaTransportClientImpl::OnError
,
164 weak_ptr_factory_
.GetWeakPtr(), error_callback
));
167 void Release(const dbus::ObjectPath
& object_path
,
168 const base::Closure
& callback
,
169 const ErrorCallback
& error_callback
) override
{
170 DCHECK(object_manager_
);
172 dbus::MethodCall
method_call(kBluetoothMediaTransportInterface
, kRelease
);
175 scoped_refptr
<dbus::ObjectProxy
> object_proxy(
176 object_manager_
->GetObjectProxy(object_path
));
178 // Call TryAcquire method of Media Transport interface.
179 object_proxy
->CallMethodWithErrorCallback(
181 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
182 base::Bind(&BluetoothMediaTransportClientImpl::OnSuccess
,
183 weak_ptr_factory_
.GetWeakPtr(), callback
),
184 base::Bind(&BluetoothMediaTransportClientImpl::OnError
,
185 weak_ptr_factory_
.GetWeakPtr(), error_callback
));
189 void Init(dbus::Bus
* bus
) override
{
191 object_manager_
= bus
->GetObjectManager(
192 bluetooth_object_manager::kBluetoothObjectManagerServiceName
,
194 bluetooth_object_manager::kBluetoothObjectManagerServicePath
));
195 object_manager_
->RegisterInterface(kBluetoothMediaTransportInterface
,
200 // Called by dbus::PropertySet when a property value is changed.
201 void OnPropertyChanged(const dbus::ObjectPath
& object_path
,
202 const std::string
& property_name
) {
203 VLOG(1) << "Name of the changed property: " << property_name
;
205 // Dispatches the change to the corresponding property-changed handler.
207 BluetoothMediaTransportClient::Observer
, observers_
,
208 MediaTransportPropertyChanged(object_path
, property_name
));
211 // Called when a response for successful method call is received.
212 void OnSuccess(const base::Closure
& callback
,
213 dbus::Response
* response
) {
218 // Called when a response for |Acquire|/|TryAcquire| method call is received.
219 void OnAcquireSuccess(const AcquireCallback
& callback
,
220 const ErrorCallback
& error_callback
,
221 dbus::Response
* response
) {
224 dbus::FileDescriptor fd
;
228 // Parse the response.
229 dbus::MessageReader
reader(response
);
230 if (reader
.PopFileDescriptor(&fd
) &&
231 reader
.PopUint16(&read_mtu
) &&
232 reader
.PopUint16(&write_mtu
)) {
233 callback
.Run(fd
, read_mtu
, write_mtu
);
239 "Failed to retrieve file descriptor, read MTU and write MTU.");
242 // Called when a response for a failed method call is received.
243 void OnError(const ErrorCallback
& error_callback
,
244 dbus::ErrorResponse
* response
) {
247 // Error response has optional error message argument.
248 std::string error_name
;
249 std::string error_message
;
251 dbus::MessageReader
reader(response
);
252 error_name
= response
->GetErrorName();
253 reader
.PopString(&error_message
);
255 error_name
= kNoResponseError
;
257 error_callback
.Run(error_name
, error_message
);
260 dbus::ObjectManager
* object_manager_
;
262 // List of observers interested in event notifications from us.
263 ObserverList
<BluetoothMediaTransportClient::Observer
> observers_
;
265 base::WeakPtrFactory
<BluetoothMediaTransportClientImpl
> weak_ptr_factory_
;
267 DISALLOW_COPY_AND_ASSIGN(BluetoothMediaTransportClientImpl
);
270 BluetoothMediaTransportClient::BluetoothMediaTransportClient() {
273 BluetoothMediaTransportClient::~BluetoothMediaTransportClient() {
276 BluetoothMediaTransportClient
* BluetoothMediaTransportClient::Create() {
277 return new BluetoothMediaTransportClientImpl();
280 } // namespace chromeos