Roll src/third_party/WebKit 91e6b24:ff1dc5b (svn 201012:201013)
[chromium-blink-merge.git] / chromeos / dbus / bluetooth_media_transport_client.cc
blob5639930e6679340dd3a460a8a2f49cc9ebcd468d
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"
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"
17 namespace {
19 // TODO(mcchou): Add these service constants into dbus/service_constants.h
20 // later.
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";
32 } // namespace
34 namespace chromeos {
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";
46 // static
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 {
71 public:
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(
86 object_proxy,
87 interface_name,
88 base::Bind(&BluetoothMediaTransportClientImpl::OnPropertyChanged,
89 weak_ptr_factory_.GetWeakPtr(), object_path));
90 return properties;
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));
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));
109 // BluetoothMediaTransportClient overrides.
111 void AddObserver(BluetoothMediaTransportClient::Observer* observer) override {
112 DCHECK(observer);
113 observers_.AddObserver(observer);
116 void RemoveObserver(
117 BluetoothMediaTransportClient::Observer* observer) override {
118 DCHECK(observer);
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);
138 // Get object proxy.
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(
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));
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,
160 kTryAcquire);
162 // Get object proxy.
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(
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));
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);
185 // Get object proxy.
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(
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));
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);
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;
216 // Dispatches the change to the corresponding property-changed handler.
217 FOR_EACH_OBSERVER(
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) {
225 DCHECK(response);
226 callback.Run();
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);
235 dbus::FileDescriptor fd;
236 uint16_t read_mtu;
237 uint16_t write_mtu;
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());
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
252 // application.
253 callback.Run(&fd, read_mtu, write_mtu);
254 return;
257 error_callback.Run(
258 kUnexpectedResponse,
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) {
265 DCHECK(response);
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;
277 error_callback.Run(error_name, error_message);
280 dbus::ObjectManager* object_manager_;
282 // List of observers interested in event notifications from us.
283 base::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