Pepper: Fix crash on allocation failure.
[chromium-blink-merge.git] / chromeos / dbus / bluetooth_device_client.cc
blobb505401d2f3b91efb7120672fa74cfbd444a64ab
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.
5 #include "chromeos/dbus/bluetooth_device_client.h"
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"
17 namespace chromeos {
19 const char BluetoothDeviceClient::kNoResponseError[] =
20 "org.chromium.Error.NoResponse";
21 const char BluetoothDeviceClient::kUnknownDeviceError[] =
22 "org.chromium.Error.UnknownDevice";
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);
50 BluetoothDeviceClient::Properties::~Properties() {
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) {}
61 virtual ~BluetoothDeviceClientImpl() {
62 object_manager_->UnregisterInterface(
63 bluetooth_device::kBluetoothDeviceInterface);
66 // BluetoothDeviceClient override.
67 virtual void AddObserver(BluetoothDeviceClient::Observer* observer)
68 OVERRIDE {
69 DCHECK(observer);
70 observers_.AddObserver(observer);
73 // BluetoothDeviceClient override.
74 virtual void RemoveObserver(BluetoothDeviceClient::Observer* observer)
75 OVERRIDE {
76 DCHECK(observer);
77 observers_.RemoveObserver(observer);
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);
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);
106 return object_paths;
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));
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);
126 dbus::ObjectProxy* object_proxy =
127 object_manager_->GetObjectProxy(object_path);
128 if (!object_proxy) {
129 error_callback.Run(kUnknownDeviceError, "");
130 return;
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));
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);
151 dbus::ObjectProxy* object_proxy =
152 object_manager_->GetObjectProxy(object_path);
153 if (!object_proxy) {
154 error_callback.Run(kUnknownDeviceError, "");
155 return;
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));
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);
176 dbus::MessageWriter writer(&method_call);
177 writer.AppendString(uuid);
179 dbus::ObjectProxy* object_proxy =
180 object_manager_->GetObjectProxy(object_path);
181 if (!object_proxy) {
182 error_callback.Run(kUnknownDeviceError, "");
183 return;
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));
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);
206 dbus::MessageWriter writer(&method_call);
207 writer.AppendString(uuid);
209 dbus::ObjectProxy* object_proxy =
210 object_manager_->GetObjectProxy(object_path);
211 if (!object_proxy) {
212 error_callback.Run(kUnknownDeviceError, "");
213 return;
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));
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);
233 dbus::ObjectProxy* object_proxy =
234 object_manager_->GetObjectProxy(object_path);
235 if (!object_proxy) {
236 error_callback.Run(kUnknownDeviceError, "");
237 return;
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));
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);
259 dbus::ObjectProxy* object_proxy =
260 object_manager_->GetObjectProxy(object_path);
261 if (!object_proxy) {
262 error_callback.Run(kUnknownDeviceError, "");
263 return;
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));
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);
282 dbus::ObjectProxy* object_proxy =
283 object_manager_->GetObjectProxy(object_path);
284 if (!object_proxy) {
285 error_callback.Run(kUnknownDeviceError, "");
286 return;
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));
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);
307 dbus::ObjectProxy* object_proxy =
308 object_manager_->GetObjectProxy(object_path);
309 if (!object_proxy) {
310 error_callback.Run(kUnknownDeviceError, "");
311 return;
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));
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);
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));
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));
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));
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();
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 = "";
381 error_callback.Run(error_name, error_message);
384 dbus::ObjectManager* object_manager_;
386 // List of observers interested in event notifications from us.
387 ObserverList<BluetoothDeviceClient::Observer> observers_;
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_;
395 DISALLOW_COPY_AND_ASSIGN(BluetoothDeviceClientImpl);
398 BluetoothDeviceClient::BluetoothDeviceClient() {
401 BluetoothDeviceClient::~BluetoothDeviceClient() {
404 BluetoothDeviceClient* BluetoothDeviceClient::Create() {
405 return new BluetoothDeviceClientImpl();
408 } // namespace chromeos