Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / chromeos / dbus / bluetooth_device_client.cc
1 // Copyright 2013 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_device_client.h"
6
7 #include "base/bind.h"
8 #include "base/logging.h"
9 #include "base/stl_util.h"
10 #include "dbus/bus.h"
11 #include "dbus/message.h"
12 #include "dbus/object_manager.h"
13 #include "dbus/object_path.h"
14 #include "dbus/object_proxy.h"
15 #include "third_party/cros_system_api/dbus/service_constants.h"
16
17 namespace chromeos {
18
19 const char BluetoothDeviceClient::kNoResponseError[] =
20     "org.chromium.Error.NoResponse";
21 const char BluetoothDeviceClient::kUnknownDeviceError[] =
22     "org.chromium.Error.UnknownDevice";
23
24 BluetoothDeviceClient::Properties::Properties(
25     dbus::ObjectProxy* object_proxy,
26     const std::string& interface_name,
27     const PropertyChangedCallback& callback)
28     : dbus::PropertySet(object_proxy, interface_name, callback) {
29   RegisterProperty(bluetooth_device::kAddressProperty, &address);
30   RegisterProperty(bluetooth_device::kNameProperty, &name);
31   RegisterProperty(bluetooth_device::kIconProperty, &icon);
32   RegisterProperty(bluetooth_device::kClassProperty, &bluetooth_class);
33   RegisterProperty(bluetooth_device::kAppearanceProperty, &appearance);
34   RegisterProperty(bluetooth_device::kUUIDsProperty, &uuids);
35   RegisterProperty(bluetooth_device::kPairedProperty, &paired);
36   RegisterProperty(bluetooth_device::kConnectedProperty, &connected);
37   RegisterProperty(bluetooth_device::kTrustedProperty, &trusted);
38   RegisterProperty(bluetooth_device::kBlockedProperty, &blocked);
39   RegisterProperty(bluetooth_device::kAliasProperty, &alias);
40   RegisterProperty(bluetooth_device::kAdapterProperty, &adapter);
41   RegisterProperty(bluetooth_device::kLegacyPairingProperty, &legacy_pairing);
42   RegisterProperty(bluetooth_device::kModaliasProperty, &modalias);
43   RegisterProperty(bluetooth_device::kRSSIProperty, &rssi);
44   RegisterProperty(bluetooth_device::kConnectionRSSI, &connection_rssi);
45   RegisterProperty(bluetooth_device::kConnectionTXPower, &connection_tx_power);
46   RegisterProperty(bluetooth_device::kConnectionTXPowerMax,
47                    &connection_tx_power_max);
48 }
49
50 BluetoothDeviceClient::Properties::~Properties() {
51 }
52
53
54 // The BluetoothDeviceClient implementation used in production.
55 class BluetoothDeviceClientImpl
56     : public BluetoothDeviceClient,
57       public dbus::ObjectManager::Interface {
58  public:
59   BluetoothDeviceClientImpl() : weak_ptr_factory_(this) {}
60
61   virtual ~BluetoothDeviceClientImpl() {
62     object_manager_->UnregisterInterface(
63         bluetooth_device::kBluetoothDeviceInterface);
64   }
65
66   // BluetoothDeviceClient override.
67   virtual void AddObserver(BluetoothDeviceClient::Observer* observer)
68       OVERRIDE {
69     DCHECK(observer);
70     observers_.AddObserver(observer);
71   }
72
73   // BluetoothDeviceClient override.
74   virtual void RemoveObserver(BluetoothDeviceClient::Observer* observer)
75       OVERRIDE {
76     DCHECK(observer);
77     observers_.RemoveObserver(observer);
78   }
79
80   // dbus::ObjectManager::Interface override.
81   virtual 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(&BluetoothDeviceClientImpl::OnPropertyChanged,
89                    weak_ptr_factory_.GetWeakPtr(),
90                    object_path));
91     return static_cast<dbus::PropertySet*>(properties);
92   }
93
94   // BluetoothDeviceClient override.
95   virtual std::vector<dbus::ObjectPath> GetDevicesForAdapter(
96       const dbus::ObjectPath& adapter_path) OVERRIDE {
97     std::vector<dbus::ObjectPath> object_paths, device_paths;
98     device_paths = object_manager_->GetObjectsWithInterface(
99         bluetooth_device::kBluetoothDeviceInterface);
100     for (std::vector<dbus::ObjectPath>::iterator iter = device_paths.begin();
101          iter != device_paths.end(); ++iter) {
102       Properties* properties = GetProperties(*iter);
103       if (properties->adapter.value() == adapter_path)
104         object_paths.push_back(*iter);
105     }
106     return object_paths;
107   }
108
109   // BluetoothDeviceClient override.
110   virtual Properties* GetProperties(const dbus::ObjectPath& object_path)
111       OVERRIDE {
112     return static_cast<Properties*>(
113         object_manager_->GetProperties(
114             object_path,
115             bluetooth_device::kBluetoothDeviceInterface));
116   }
117
118   // BluetoothDeviceClient override.
119   virtual void Connect(const dbus::ObjectPath& object_path,
120                        const base::Closure& callback,
121                        const ErrorCallback& error_callback) OVERRIDE {
122     dbus::MethodCall method_call(
123         bluetooth_device::kBluetoothDeviceInterface,
124         bluetooth_device::kConnect);
125
126     dbus::ObjectProxy* object_proxy =
127         object_manager_->GetObjectProxy(object_path);
128     if (!object_proxy) {
129       error_callback.Run(kUnknownDeviceError, "");
130       return;
131     }
132
133     // Connect may take an arbitrary length of time, so use no timeout.
134     object_proxy->CallMethodWithErrorCallback(
135         &method_call,
136         dbus::ObjectProxy::TIMEOUT_INFINITE,
137         base::Bind(&BluetoothDeviceClientImpl::OnSuccess,
138                    weak_ptr_factory_.GetWeakPtr(), callback),
139         base::Bind(&BluetoothDeviceClientImpl::OnError,
140                    weak_ptr_factory_.GetWeakPtr(), error_callback));
141   }
142
143   // BluetoothDeviceClient override.
144   virtual void Disconnect(const dbus::ObjectPath& object_path,
145                           const base::Closure& callback,
146                           const ErrorCallback& error_callback) OVERRIDE {
147     dbus::MethodCall method_call(
148         bluetooth_device::kBluetoothDeviceInterface,
149         bluetooth_device::kDisconnect);
150
151     dbus::ObjectProxy* object_proxy =
152         object_manager_->GetObjectProxy(object_path);
153     if (!object_proxy) {
154       error_callback.Run(kUnknownDeviceError, "");
155       return;
156     }
157
158     object_proxy->CallMethodWithErrorCallback(
159         &method_call,
160         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
161         base::Bind(&BluetoothDeviceClientImpl::OnSuccess,
162                    weak_ptr_factory_.GetWeakPtr(), callback),
163         base::Bind(&BluetoothDeviceClientImpl::OnError,
164                    weak_ptr_factory_.GetWeakPtr(), error_callback));
165   }
166
167   // BluetoothDeviceClient override.
168   virtual void ConnectProfile(const dbus::ObjectPath& object_path,
169                               const std::string& uuid,
170                               const base::Closure& callback,
171                               const ErrorCallback& error_callback) OVERRIDE {
172     dbus::MethodCall method_call(
173         bluetooth_device::kBluetoothDeviceInterface,
174         bluetooth_device::kConnectProfile);
175
176     dbus::MessageWriter writer(&method_call);
177     writer.AppendString(uuid);
178
179     dbus::ObjectProxy* object_proxy =
180         object_manager_->GetObjectProxy(object_path);
181     if (!object_proxy) {
182       error_callback.Run(kUnknownDeviceError, "");
183       return;
184     }
185
186     // Connect may take an arbitrary length of time, so use no timeout.
187     object_proxy->CallMethodWithErrorCallback(
188         &method_call,
189         dbus::ObjectProxy::TIMEOUT_INFINITE,
190         base::Bind(&BluetoothDeviceClientImpl::OnSuccess,
191                    weak_ptr_factory_.GetWeakPtr(), callback),
192         base::Bind(&BluetoothDeviceClientImpl::OnError,
193                    weak_ptr_factory_.GetWeakPtr(), error_callback));
194   }
195
196   // BluetoothDeviceClient override.
197   virtual void DisconnectProfile(const dbus::ObjectPath& object_path,
198                                  const std::string& uuid,
199                                  const base::Closure& callback,
200                                  const ErrorCallback& error_callback)
201         OVERRIDE {
202     dbus::MethodCall method_call(
203         bluetooth_device::kBluetoothDeviceInterface,
204         bluetooth_device::kDisconnectProfile);
205
206     dbus::MessageWriter writer(&method_call);
207     writer.AppendString(uuid);
208
209     dbus::ObjectProxy* object_proxy =
210         object_manager_->GetObjectProxy(object_path);
211     if (!object_proxy) {
212       error_callback.Run(kUnknownDeviceError, "");
213       return;
214     }
215
216     object_proxy->CallMethodWithErrorCallback(
217         &method_call,
218         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
219         base::Bind(&BluetoothDeviceClientImpl::OnSuccess,
220                    weak_ptr_factory_.GetWeakPtr(), callback),
221         base::Bind(&BluetoothDeviceClientImpl::OnError,
222                    weak_ptr_factory_.GetWeakPtr(), error_callback));
223   }
224
225   // BluetoothDeviceClient override.
226   virtual void Pair(const dbus::ObjectPath& object_path,
227                     const base::Closure& callback,
228                     const ErrorCallback& error_callback) OVERRIDE {
229     dbus::MethodCall method_call(
230         bluetooth_device::kBluetoothDeviceInterface,
231         bluetooth_device::kPair);
232
233     dbus::ObjectProxy* object_proxy =
234         object_manager_->GetObjectProxy(object_path);
235     if (!object_proxy) {
236       error_callback.Run(kUnknownDeviceError, "");
237       return;
238     }
239
240     // Pairing may take an arbitrary length of time, so use no timeout.
241     object_proxy->CallMethodWithErrorCallback(
242         &method_call,
243         dbus::ObjectProxy::TIMEOUT_INFINITE,
244         base::Bind(&BluetoothDeviceClientImpl::OnSuccess,
245                    weak_ptr_factory_.GetWeakPtr(), callback),
246         base::Bind(&BluetoothDeviceClientImpl::OnError,
247                    weak_ptr_factory_.GetWeakPtr(), error_callback));
248   }
249
250   // BluetoothDeviceClient override.
251   virtual void CancelPairing(const dbus::ObjectPath& object_path,
252                              const base::Closure& callback,
253                              const ErrorCallback& error_callback)
254         OVERRIDE {
255     dbus::MethodCall method_call(
256         bluetooth_device::kBluetoothDeviceInterface,
257         bluetooth_device::kCancelPairing);
258
259     dbus::ObjectProxy* object_proxy =
260         object_manager_->GetObjectProxy(object_path);
261     if (!object_proxy) {
262       error_callback.Run(kUnknownDeviceError, "");
263       return;
264     }
265     object_proxy->CallMethodWithErrorCallback(
266         &method_call,
267         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
268         base::Bind(&BluetoothDeviceClientImpl::OnSuccess,
269                    weak_ptr_factory_.GetWeakPtr(), callback),
270         base::Bind(&BluetoothDeviceClientImpl::OnError,
271                    weak_ptr_factory_.GetWeakPtr(), error_callback));
272   }
273
274   // BluetoothDeviceClient override.
275   virtual void StartConnectionMonitor(
276       const dbus::ObjectPath& object_path,
277       const base::Closure& callback,
278       const ErrorCallback& error_callback) OVERRIDE {
279     dbus::MethodCall method_call(bluetooth_device::kBluetoothDeviceInterface,
280                                  bluetooth_device::kStartConnectionMonitor);
281
282     dbus::ObjectProxy* object_proxy =
283         object_manager_->GetObjectProxy(object_path);
284     if (!object_proxy) {
285       error_callback.Run(kUnknownDeviceError, "");
286       return;
287     }
288     object_proxy->CallMethodWithErrorCallback(
289         &method_call,
290         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
291         base::Bind(&BluetoothDeviceClientImpl::OnSuccess,
292                    weak_ptr_factory_.GetWeakPtr(),
293                    callback),
294         base::Bind(&BluetoothDeviceClientImpl::OnError,
295                    weak_ptr_factory_.GetWeakPtr(),
296                    error_callback));
297   }
298
299   // BluetoothDeviceClient override.
300   virtual void StopConnectionMonitor(
301       const dbus::ObjectPath& object_path,
302       const base::Closure& callback,
303       const ErrorCallback& error_callback) OVERRIDE {
304     dbus::MethodCall method_call(bluetooth_device::kBluetoothDeviceInterface,
305                                  bluetooth_device::kStopConnectionMonitor);
306
307     dbus::ObjectProxy* object_proxy =
308         object_manager_->GetObjectProxy(object_path);
309     if (!object_proxy) {
310       error_callback.Run(kUnknownDeviceError, "");
311       return;
312     }
313     object_proxy->CallMethodWithErrorCallback(
314         &method_call,
315         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
316         base::Bind(&BluetoothDeviceClientImpl::OnSuccess,
317                    weak_ptr_factory_.GetWeakPtr(),
318                    callback),
319         base::Bind(&BluetoothDeviceClientImpl::OnError,
320                    weak_ptr_factory_.GetWeakPtr(),
321                    error_callback));
322   }
323
324  protected:
325   virtual void Init(dbus::Bus* bus) OVERRIDE {
326     object_manager_ = bus->GetObjectManager(
327         bluetooth_object_manager::kBluetoothObjectManagerServiceName,
328         dbus::ObjectPath(
329             bluetooth_object_manager::kBluetoothObjectManagerServicePath));
330     object_manager_->RegisterInterface(
331         bluetooth_device::kBluetoothDeviceInterface, this);
332   }
333
334  private:
335   // Called by dbus::ObjectManager when an object with the device interface
336   // is created. Informs observers.
337   virtual void ObjectAdded(const dbus::ObjectPath& object_path,
338                            const std::string& interface_name) OVERRIDE {
339     FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer, observers_,
340                       DeviceAdded(object_path));
341   }
342
343   // Called by dbus::ObjectManager when an object with the device interface
344   // is removed. Informs observers.
345   virtual void ObjectRemoved(const dbus::ObjectPath& object_path,
346                              const std::string& interface_name) OVERRIDE {
347     FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer, observers_,
348                       DeviceRemoved(object_path));
349   }
350
351   // Called by BluetoothPropertySet when a property value is changed,
352   // either by result of a signal or response to a GetAll() or Get()
353   // call. Informs observers.
354   void OnPropertyChanged(const dbus::ObjectPath& object_path,
355                          const std::string& property_name) {
356     FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer, observers_,
357                       DevicePropertyChanged(object_path, property_name));
358   }
359
360   // Called when a response for successful method call is received.
361   void OnSuccess(const base::Closure& callback,
362                  dbus::Response* response) {
363     DCHECK(response);
364     callback.Run();
365   }
366
367   // Called when a response for a failed method call is received.
368   void OnError(const ErrorCallback& error_callback,
369                dbus::ErrorResponse* response) {
370     // Error response has optional error message argument.
371     std::string error_name;
372     std::string error_message;
373     if (response) {
374       dbus::MessageReader reader(response);
375       error_name = response->GetErrorName();
376       reader.PopString(&error_message);
377     } else {
378       error_name = kNoResponseError;
379       error_message = "";
380     }
381     error_callback.Run(error_name, error_message);
382   }
383
384   dbus::ObjectManager* object_manager_;
385
386   // List of observers interested in event notifications from us.
387   ObserverList<BluetoothDeviceClient::Observer> observers_;
388
389   // Weak pointer factory for generating 'this' pointers that might live longer
390   // than we do.
391   // Note: This should remain the last member so it'll be destroyed and
392   // invalidate its weak pointers before any other members are destroyed.
393   base::WeakPtrFactory<BluetoothDeviceClientImpl> weak_ptr_factory_;
394
395   DISALLOW_COPY_AND_ASSIGN(BluetoothDeviceClientImpl);
396 };
397
398 BluetoothDeviceClient::BluetoothDeviceClient() {
399 }
400
401 BluetoothDeviceClient::~BluetoothDeviceClient() {
402 }
403
404 BluetoothDeviceClient* BluetoothDeviceClient::Create() {
405   return new BluetoothDeviceClientImpl();
406 }
407
408 }  // namespace chromeos