Add some instrumentation for jank in URLRequest::Start.
[chromium-blink-merge.git] / chromeos / dbus / bluetooth_device_client.cc
blob96fba6274c0c5be78e3e9b1c383aee2eb1078694
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);
52 BluetoothDeviceClient::Properties::~Properties() {
56 // The BluetoothDeviceClient implementation used in production.
57 class BluetoothDeviceClientImpl
58 : public BluetoothDeviceClient,
59 public dbus::ObjectManager::Interface {
60 public:
61 BluetoothDeviceClientImpl()
62 : object_manager_(NULL), weak_ptr_factory_(this) {}
64 ~BluetoothDeviceClientImpl() override {
65 object_manager_->UnregisterInterface(
66 bluetooth_device::kBluetoothDeviceInterface);
69 // BluetoothDeviceClient override.
70 void AddObserver(BluetoothDeviceClient::Observer* observer) override {
71 DCHECK(observer);
72 observers_.AddObserver(observer);
75 // BluetoothDeviceClient override.
76 void RemoveObserver(BluetoothDeviceClient::Observer* observer) override {
77 DCHECK(observer);
78 observers_.RemoveObserver(observer);
81 // dbus::ObjectManager::Interface override.
82 dbus::PropertySet* CreateProperties(
83 dbus::ObjectProxy* object_proxy,
84 const dbus::ObjectPath& object_path,
85 const std::string& interface_name) override {
86 Properties* properties = new Properties(
87 object_proxy,
88 interface_name,
89 base::Bind(&BluetoothDeviceClientImpl::OnPropertyChanged,
90 weak_ptr_factory_.GetWeakPtr(),
91 object_path));
92 return static_cast<dbus::PropertySet*>(properties);
95 // BluetoothDeviceClient override.
96 std::vector<dbus::ObjectPath> GetDevicesForAdapter(
97 const dbus::ObjectPath& adapter_path) override {
98 std::vector<dbus::ObjectPath> object_paths, device_paths;
99 device_paths = object_manager_->GetObjectsWithInterface(
100 bluetooth_device::kBluetoothDeviceInterface);
101 for (std::vector<dbus::ObjectPath>::iterator iter = device_paths.begin();
102 iter != device_paths.end(); ++iter) {
103 Properties* properties = GetProperties(*iter);
104 if (properties->adapter.value() == adapter_path)
105 object_paths.push_back(*iter);
107 return object_paths;
110 // BluetoothDeviceClient override.
111 Properties* GetProperties(const dbus::ObjectPath& object_path) override {
112 return static_cast<Properties*>(
113 object_manager_->GetProperties(
114 object_path,
115 bluetooth_device::kBluetoothDeviceInterface));
118 // BluetoothDeviceClient override.
119 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 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 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 void DisconnectProfile(const dbus::ObjectPath& object_path,
198 const std::string& uuid,
199 const base::Closure& callback,
200 const ErrorCallback& error_callback) override {
201 dbus::MethodCall method_call(
202 bluetooth_device::kBluetoothDeviceInterface,
203 bluetooth_device::kDisconnectProfile);
205 dbus::MessageWriter writer(&method_call);
206 writer.AppendString(uuid);
208 dbus::ObjectProxy* object_proxy =
209 object_manager_->GetObjectProxy(object_path);
210 if (!object_proxy) {
211 error_callback.Run(kUnknownDeviceError, "");
212 return;
215 object_proxy->CallMethodWithErrorCallback(
216 &method_call,
217 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
218 base::Bind(&BluetoothDeviceClientImpl::OnSuccess,
219 weak_ptr_factory_.GetWeakPtr(), callback),
220 base::Bind(&BluetoothDeviceClientImpl::OnError,
221 weak_ptr_factory_.GetWeakPtr(), error_callback));
224 // BluetoothDeviceClient override.
225 void Pair(const dbus::ObjectPath& object_path,
226 const base::Closure& callback,
227 const ErrorCallback& error_callback) override {
228 dbus::MethodCall method_call(
229 bluetooth_device::kBluetoothDeviceInterface,
230 bluetooth_device::kPair);
232 dbus::ObjectProxy* object_proxy =
233 object_manager_->GetObjectProxy(object_path);
234 if (!object_proxy) {
235 error_callback.Run(kUnknownDeviceError, "");
236 return;
239 // Pairing may take an arbitrary length of time, so use no timeout.
240 object_proxy->CallMethodWithErrorCallback(
241 &method_call,
242 dbus::ObjectProxy::TIMEOUT_INFINITE,
243 base::Bind(&BluetoothDeviceClientImpl::OnSuccess,
244 weak_ptr_factory_.GetWeakPtr(), callback),
245 base::Bind(&BluetoothDeviceClientImpl::OnError,
246 weak_ptr_factory_.GetWeakPtr(), error_callback));
249 // BluetoothDeviceClient override.
250 void CancelPairing(const dbus::ObjectPath& object_path,
251 const base::Closure& callback,
252 const ErrorCallback& error_callback) override {
253 dbus::MethodCall method_call(
254 bluetooth_device::kBluetoothDeviceInterface,
255 bluetooth_device::kCancelPairing);
257 dbus::ObjectProxy* object_proxy =
258 object_manager_->GetObjectProxy(object_path);
259 if (!object_proxy) {
260 error_callback.Run(kUnknownDeviceError, "");
261 return;
263 object_proxy->CallMethodWithErrorCallback(
264 &method_call,
265 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
266 base::Bind(&BluetoothDeviceClientImpl::OnSuccess,
267 weak_ptr_factory_.GetWeakPtr(), callback),
268 base::Bind(&BluetoothDeviceClientImpl::OnError,
269 weak_ptr_factory_.GetWeakPtr(), error_callback));
272 // BluetoothDeviceClient override.
273 void GetConnInfo(const dbus::ObjectPath& object_path,
274 const ConnInfoCallback& callback,
275 const ErrorCallback& error_callback) override {
276 dbus::MethodCall method_call(
277 bluetooth_plugin_device::kBluetoothPluginInterface,
278 bluetooth_plugin_device::kGetConnInfo);
280 dbus::ObjectProxy* object_proxy =
281 object_manager_->GetObjectProxy(object_path);
282 if (!object_proxy) {
283 error_callback.Run(kUnknownDeviceError, "");
284 return;
286 object_proxy->CallMethodWithErrorCallback(
287 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
288 base::Bind(&BluetoothDeviceClientImpl::OnGetConnInfoSuccess,
289 weak_ptr_factory_.GetWeakPtr(), callback),
290 base::Bind(&BluetoothDeviceClientImpl::OnError,
291 weak_ptr_factory_.GetWeakPtr(), error_callback));
294 protected:
295 void Init(dbus::Bus* bus) override {
296 object_manager_ = bus->GetObjectManager(
297 bluetooth_object_manager::kBluetoothObjectManagerServiceName,
298 dbus::ObjectPath(
299 bluetooth_object_manager::kBluetoothObjectManagerServicePath));
300 object_manager_->RegisterInterface(
301 bluetooth_device::kBluetoothDeviceInterface, this);
304 private:
305 // Called by dbus::ObjectManager when an object with the device interface
306 // is created. Informs observers.
307 void ObjectAdded(const dbus::ObjectPath& object_path,
308 const std::string& interface_name) override {
309 FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer, observers_,
310 DeviceAdded(object_path));
313 // Called by dbus::ObjectManager when an object with the device interface
314 // is removed. Informs observers.
315 void ObjectRemoved(const dbus::ObjectPath& object_path,
316 const std::string& interface_name) override {
317 FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer, observers_,
318 DeviceRemoved(object_path));
321 // Called by BluetoothPropertySet when a property value is changed,
322 // either by result of a signal or response to a GetAll() or Get()
323 // call. Informs observers.
324 void OnPropertyChanged(const dbus::ObjectPath& object_path,
325 const std::string& property_name) {
326 FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer, observers_,
327 DevicePropertyChanged(object_path, property_name));
330 // Called when a response for successful method call is received.
331 void OnSuccess(const base::Closure& callback,
332 dbus::Response* response) {
333 DCHECK(response);
334 callback.Run();
337 // Called when a response for the GetConnInfo method is received.
338 void OnGetConnInfoSuccess(const ConnInfoCallback& callback,
339 dbus::Response* response) {
340 int16 rssi = kUnknownPower;
341 int16 transmit_power = kUnknownPower;
342 int16 max_transmit_power = kUnknownPower;
344 if (!response) {
345 LOG(ERROR) << "GetConnInfo succeeded, but no response received.";
346 callback.Run(rssi, transmit_power, max_transmit_power);
347 return;
350 dbus::MessageReader reader(response);
351 if (!reader.PopInt16(&rssi) || !reader.PopInt16(&transmit_power) ||
352 !reader.PopInt16(&max_transmit_power)) {
353 LOG(ERROR) << "Arguments for GetConnInfo invalid.";
355 callback.Run(rssi, transmit_power, max_transmit_power);
358 // Called when a response for a failed method call is received.
359 void OnError(const ErrorCallback& error_callback,
360 dbus::ErrorResponse* response) {
361 // Error response has optional error message argument.
362 std::string error_name;
363 std::string error_message;
364 if (response) {
365 dbus::MessageReader reader(response);
366 error_name = response->GetErrorName();
367 reader.PopString(&error_message);
368 } else {
369 error_name = kNoResponseError;
370 error_message = "";
372 error_callback.Run(error_name, error_message);
375 dbus::ObjectManager* object_manager_;
377 // List of observers interested in event notifications from us.
378 ObserverList<BluetoothDeviceClient::Observer> observers_;
380 // Weak pointer factory for generating 'this' pointers that might live longer
381 // than we do.
382 // Note: This should remain the last member so it'll be destroyed and
383 // invalidate its weak pointers before any other members are destroyed.
384 base::WeakPtrFactory<BluetoothDeviceClientImpl> weak_ptr_factory_;
386 DISALLOW_COPY_AND_ASSIGN(BluetoothDeviceClientImpl);
389 BluetoothDeviceClient::BluetoothDeviceClient() {
392 BluetoothDeviceClient::~BluetoothDeviceClient() {
395 BluetoothDeviceClient* BluetoothDeviceClient::Create() {
396 return new BluetoothDeviceClientImpl();
399 } // namespace chromeos