Roll src/third_party/WebKit d9c6159:8139f33 (svn 201974:201975)
[chromium-blink-merge.git] / chromeos / dbus / bluetooth_device_client.cc
blob02a5c6b7baced51ceb8e9bde6f4b822c86471782
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_proxy.h"
14 #include "third_party/cros_system_api/dbus/service_constants.h"
16 namespace chromeos {
18 namespace {
20 // Value returned for the the RSSI or TX power if it cannot be read.
21 const int kUnknownPower = 127;
23 } // namespace
25 const char BluetoothDeviceClient::kNoResponseError[] =
26 "org.chromium.Error.NoResponse";
27 const char BluetoothDeviceClient::kUnknownDeviceError[] =
28 "org.chromium.Error.UnknownDevice";
30 BluetoothDeviceClient::Properties::Properties(
31 dbus::ObjectProxy* object_proxy,
32 const std::string& interface_name,
33 const PropertyChangedCallback& callback)
34 : dbus::PropertySet(object_proxy, interface_name, callback) {
35 RegisterProperty(bluetooth_device::kAddressProperty, &address);
36 RegisterProperty(bluetooth_device::kNameProperty, &name);
37 RegisterProperty(bluetooth_device::kIconProperty, &icon);
38 RegisterProperty(bluetooth_device::kClassProperty, &bluetooth_class);
39 RegisterProperty(bluetooth_device::kAppearanceProperty, &appearance);
40 RegisterProperty(bluetooth_device::kUUIDsProperty, &uuids);
41 RegisterProperty(bluetooth_device::kPairedProperty, &paired);
42 RegisterProperty(bluetooth_device::kConnectedProperty, &connected);
43 RegisterProperty(bluetooth_device::kTrustedProperty, &trusted);
44 RegisterProperty(bluetooth_device::kBlockedProperty, &blocked);
45 RegisterProperty(bluetooth_device::kAliasProperty, &alias);
46 RegisterProperty(bluetooth_device::kAdapterProperty, &adapter);
47 RegisterProperty(bluetooth_device::kLegacyPairingProperty, &legacy_pairing);
48 RegisterProperty(bluetooth_device::kModaliasProperty, &modalias);
49 RegisterProperty(bluetooth_device::kRSSIProperty, &rssi);
50 RegisterProperty(bluetooth_device::kTxPowerProperty, &tx_power);
53 BluetoothDeviceClient::Properties::~Properties() {
57 // The BluetoothDeviceClient implementation used in production.
58 class BluetoothDeviceClientImpl
59 : public BluetoothDeviceClient,
60 public dbus::ObjectManager::Interface {
61 public:
62 BluetoothDeviceClientImpl()
63 : object_manager_(NULL), weak_ptr_factory_(this) {}
65 ~BluetoothDeviceClientImpl() override {
66 object_manager_->UnregisterInterface(
67 bluetooth_device::kBluetoothDeviceInterface);
70 // BluetoothDeviceClient override.
71 void AddObserver(BluetoothDeviceClient::Observer* observer) override {
72 DCHECK(observer);
73 observers_.AddObserver(observer);
76 // BluetoothDeviceClient override.
77 void RemoveObserver(BluetoothDeviceClient::Observer* observer) override {
78 DCHECK(observer);
79 observers_.RemoveObserver(observer);
82 // dbus::ObjectManager::Interface override.
83 dbus::PropertySet* CreateProperties(
84 dbus::ObjectProxy* object_proxy,
85 const dbus::ObjectPath& object_path,
86 const std::string& interface_name) override {
87 Properties* properties = new Properties(
88 object_proxy,
89 interface_name,
90 base::Bind(&BluetoothDeviceClientImpl::OnPropertyChanged,
91 weak_ptr_factory_.GetWeakPtr(),
92 object_path));
93 return static_cast<dbus::PropertySet*>(properties);
96 // BluetoothDeviceClient override.
97 std::vector<dbus::ObjectPath> GetDevicesForAdapter(
98 const dbus::ObjectPath& adapter_path) override {
99 std::vector<dbus::ObjectPath> object_paths, device_paths;
100 device_paths = object_manager_->GetObjectsWithInterface(
101 bluetooth_device::kBluetoothDeviceInterface);
102 for (std::vector<dbus::ObjectPath>::iterator iter = device_paths.begin();
103 iter != device_paths.end(); ++iter) {
104 Properties* properties = GetProperties(*iter);
105 if (properties->adapter.value() == adapter_path)
106 object_paths.push_back(*iter);
108 return object_paths;
111 // BluetoothDeviceClient override.
112 Properties* GetProperties(const dbus::ObjectPath& object_path) override {
113 return static_cast<Properties*>(
114 object_manager_->GetProperties(
115 object_path,
116 bluetooth_device::kBluetoothDeviceInterface));
119 // BluetoothDeviceClient override.
120 void Connect(const dbus::ObjectPath& object_path,
121 const base::Closure& callback,
122 const ErrorCallback& error_callback) override {
123 dbus::MethodCall method_call(
124 bluetooth_device::kBluetoothDeviceInterface,
125 bluetooth_device::kConnect);
127 dbus::ObjectProxy* object_proxy =
128 object_manager_->GetObjectProxy(object_path);
129 if (!object_proxy) {
130 error_callback.Run(kUnknownDeviceError, "");
131 return;
134 // Connect may take an arbitrary length of time, so use no timeout.
135 object_proxy->CallMethodWithErrorCallback(
136 &method_call,
137 dbus::ObjectProxy::TIMEOUT_INFINITE,
138 base::Bind(&BluetoothDeviceClientImpl::OnSuccess,
139 weak_ptr_factory_.GetWeakPtr(), callback),
140 base::Bind(&BluetoothDeviceClientImpl::OnError,
141 weak_ptr_factory_.GetWeakPtr(), error_callback));
144 // BluetoothDeviceClient override.
145 void Disconnect(const dbus::ObjectPath& object_path,
146 const base::Closure& callback,
147 const ErrorCallback& error_callback) override {
148 dbus::MethodCall method_call(
149 bluetooth_device::kBluetoothDeviceInterface,
150 bluetooth_device::kDisconnect);
152 dbus::ObjectProxy* object_proxy =
153 object_manager_->GetObjectProxy(object_path);
154 if (!object_proxy) {
155 error_callback.Run(kUnknownDeviceError, "");
156 return;
159 object_proxy->CallMethodWithErrorCallback(
160 &method_call,
161 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
162 base::Bind(&BluetoothDeviceClientImpl::OnSuccess,
163 weak_ptr_factory_.GetWeakPtr(), callback),
164 base::Bind(&BluetoothDeviceClientImpl::OnError,
165 weak_ptr_factory_.GetWeakPtr(), error_callback));
168 // BluetoothDeviceClient override.
169 void ConnectProfile(const dbus::ObjectPath& object_path,
170 const std::string& uuid,
171 const base::Closure& callback,
172 const ErrorCallback& error_callback) override {
173 dbus::MethodCall method_call(
174 bluetooth_device::kBluetoothDeviceInterface,
175 bluetooth_device::kConnectProfile);
177 dbus::MessageWriter writer(&method_call);
178 writer.AppendString(uuid);
180 dbus::ObjectProxy* object_proxy =
181 object_manager_->GetObjectProxy(object_path);
182 if (!object_proxy) {
183 error_callback.Run(kUnknownDeviceError, "");
184 return;
187 // Connect may take an arbitrary length of time, so use no timeout.
188 object_proxy->CallMethodWithErrorCallback(
189 &method_call,
190 dbus::ObjectProxy::TIMEOUT_INFINITE,
191 base::Bind(&BluetoothDeviceClientImpl::OnSuccess,
192 weak_ptr_factory_.GetWeakPtr(), callback),
193 base::Bind(&BluetoothDeviceClientImpl::OnError,
194 weak_ptr_factory_.GetWeakPtr(), error_callback));
197 // BluetoothDeviceClient override.
198 void DisconnectProfile(const dbus::ObjectPath& object_path,
199 const std::string& uuid,
200 const base::Closure& callback,
201 const ErrorCallback& error_callback) 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 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 void CancelPairing(const dbus::ObjectPath& object_path,
252 const base::Closure& callback,
253 const ErrorCallback& error_callback) override {
254 dbus::MethodCall method_call(
255 bluetooth_device::kBluetoothDeviceInterface,
256 bluetooth_device::kCancelPairing);
258 dbus::ObjectProxy* object_proxy =
259 object_manager_->GetObjectProxy(object_path);
260 if (!object_proxy) {
261 error_callback.Run(kUnknownDeviceError, "");
262 return;
264 object_proxy->CallMethodWithErrorCallback(
265 &method_call,
266 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
267 base::Bind(&BluetoothDeviceClientImpl::OnSuccess,
268 weak_ptr_factory_.GetWeakPtr(), callback),
269 base::Bind(&BluetoothDeviceClientImpl::OnError,
270 weak_ptr_factory_.GetWeakPtr(), error_callback));
273 // BluetoothDeviceClient override.
274 void GetConnInfo(const dbus::ObjectPath& object_path,
275 const ConnInfoCallback& callback,
276 const ErrorCallback& error_callback) override {
277 dbus::MethodCall method_call(
278 bluetooth_plugin_device::kBluetoothPluginInterface,
279 bluetooth_plugin_device::kGetConnInfo);
281 dbus::ObjectProxy* object_proxy =
282 object_manager_->GetObjectProxy(object_path);
283 if (!object_proxy) {
284 error_callback.Run(kUnknownDeviceError, "");
285 return;
287 object_proxy->CallMethodWithErrorCallback(
288 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
289 base::Bind(&BluetoothDeviceClientImpl::OnGetConnInfoSuccess,
290 weak_ptr_factory_.GetWeakPtr(), callback),
291 base::Bind(&BluetoothDeviceClientImpl::OnError,
292 weak_ptr_factory_.GetWeakPtr(), error_callback));
295 protected:
296 void Init(dbus::Bus* bus) override {
297 object_manager_ = bus->GetObjectManager(
298 bluetooth_object_manager::kBluetoothObjectManagerServiceName,
299 dbus::ObjectPath(
300 bluetooth_object_manager::kBluetoothObjectManagerServicePath));
301 object_manager_->RegisterInterface(
302 bluetooth_device::kBluetoothDeviceInterface, this);
305 private:
306 // Called by dbus::ObjectManager when an object with the device interface
307 // is created. Informs observers.
308 void ObjectAdded(const dbus::ObjectPath& object_path,
309 const std::string& interface_name) override {
310 FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer, observers_,
311 DeviceAdded(object_path));
314 // Called by dbus::ObjectManager when an object with the device interface
315 // is removed. Informs observers.
316 void ObjectRemoved(const dbus::ObjectPath& object_path,
317 const std::string& interface_name) override {
318 FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer, observers_,
319 DeviceRemoved(object_path));
322 // Called by BluetoothPropertySet when a property value is changed,
323 // either by result of a signal or response to a GetAll() or Get()
324 // call. Informs observers.
325 void OnPropertyChanged(const dbus::ObjectPath& object_path,
326 const std::string& property_name) {
327 FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer, observers_,
328 DevicePropertyChanged(object_path, property_name));
331 // Called when a response for successful method call is received.
332 void OnSuccess(const base::Closure& callback,
333 dbus::Response* response) {
334 DCHECK(response);
335 callback.Run();
338 // Called when a response for the GetConnInfo method is received.
339 void OnGetConnInfoSuccess(const ConnInfoCallback& callback,
340 dbus::Response* response) {
341 int16 rssi = kUnknownPower;
342 int16 transmit_power = kUnknownPower;
343 int16 max_transmit_power = kUnknownPower;
345 if (!response) {
346 LOG(ERROR) << "GetConnInfo succeeded, but no response received.";
347 callback.Run(rssi, transmit_power, max_transmit_power);
348 return;
351 dbus::MessageReader reader(response);
352 if (!reader.PopInt16(&rssi) || !reader.PopInt16(&transmit_power) ||
353 !reader.PopInt16(&max_transmit_power)) {
354 LOG(ERROR) << "Arguments for GetConnInfo invalid.";
356 callback.Run(rssi, transmit_power, max_transmit_power);
359 // Called when a response for a failed method call is received.
360 void OnError(const ErrorCallback& error_callback,
361 dbus::ErrorResponse* response) {
362 // Error response has optional error message argument.
363 std::string error_name;
364 std::string error_message;
365 if (response) {
366 dbus::MessageReader reader(response);
367 error_name = response->GetErrorName();
368 reader.PopString(&error_message);
369 } else {
370 error_name = kNoResponseError;
371 error_message = "";
373 error_callback.Run(error_name, error_message);
376 dbus::ObjectManager* object_manager_;
378 // List of observers interested in event notifications from us.
379 base::ObserverList<BluetoothDeviceClient::Observer> observers_;
381 // Weak pointer factory for generating 'this' pointers that might live longer
382 // than we do.
383 // Note: This should remain the last member so it'll be destroyed and
384 // invalidate its weak pointers before any other members are destroyed.
385 base::WeakPtrFactory<BluetoothDeviceClientImpl> weak_ptr_factory_;
387 DISALLOW_COPY_AND_ASSIGN(BluetoothDeviceClientImpl);
390 BluetoothDeviceClient::BluetoothDeviceClient() {
393 BluetoothDeviceClient::~BluetoothDeviceClient() {
396 BluetoothDeviceClient* BluetoothDeviceClient::Create() {
397 return new BluetoothDeviceClientImpl();
400 } // namespace chromeos