1 // Copyright (c) 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/experimental_bluetooth_device_client.h"
8 #include "base/logging.h"
9 #include "base/stl_util.h"
10 #include "chromeos/dbus/fake_bluetooth_device_client.h"
12 #include "dbus/message.h"
13 #include "dbus/object_manager.h"
14 #include "dbus/object_path.h"
15 #include "dbus/object_proxy.h"
16 #include "third_party/cros_system_api/dbus/service_constants.h"
20 const char ExperimentalBluetoothDeviceClient::kNoResponseError
[] =
21 "org.chromium.Error.NoResponse";
22 const char ExperimentalBluetoothDeviceClient::kUnknownDeviceError
[] =
23 "org.chromium.Error.UnknownDevice";
25 ExperimentalBluetoothDeviceClient::Properties::Properties(
26 dbus::ObjectProxy
* object_proxy
,
27 const std::string
& interface_name
,
28 const PropertyChangedCallback
& callback
)
29 : dbus::PropertySet(object_proxy
, interface_name
, callback
) {
30 RegisterProperty(bluetooth_device::kAddressProperty
, &address
);
31 RegisterProperty(bluetooth_device::kNameProperty
, &name
);
32 RegisterProperty(bluetooth_device::kIconProperty
, &icon
);
33 RegisterProperty(bluetooth_device::kClassProperty
, &bluetooth_class
);
34 RegisterProperty(bluetooth_device::kAppearanceProperty
, &appearance
);
35 RegisterProperty(bluetooth_device::kUUIDsProperty
, &uuids
);
36 RegisterProperty(bluetooth_device::kPairedProperty
, &paired
);
37 RegisterProperty(bluetooth_device::kConnectedProperty
, &connected
);
38 RegisterProperty(bluetooth_device::kTrustedProperty
, &trusted
);
39 RegisterProperty(bluetooth_device::kBlockedProperty
, &blocked
);
40 RegisterProperty(bluetooth_device::kAliasProperty
, &alias
);
41 RegisterProperty(bluetooth_device::kAdapterProperty
, &adapter
);
42 RegisterProperty(bluetooth_device::kLegacyPairingProperty
, &legacy_pairing
);
43 RegisterProperty(bluetooth_device::kModaliasProperty
, &modalias
);
44 RegisterProperty(bluetooth_device::kRSSIProperty
, &rssi
);
47 ExperimentalBluetoothDeviceClient::Properties::~Properties() {
51 // The ExperimentalBluetoothDeviceClient implementation used in production.
52 class ExperimentalBluetoothDeviceClientImpl
53 : public ExperimentalBluetoothDeviceClient
,
54 public dbus::ObjectManager::Interface
{
56 explicit ExperimentalBluetoothDeviceClientImpl(dbus::Bus
* bus
)
58 weak_ptr_factory_(this) {
59 object_manager_
= bus_
->GetObjectManager(
60 bluetooth_manager::kBluetoothManagerServiceName
,
61 dbus::ObjectPath(bluetooth_manager::kBluetoothManagerServicePath
));
62 object_manager_
->RegisterInterface(
63 bluetooth_device::kExperimentalBluetoothDeviceInterface
, this);
66 virtual ~ExperimentalBluetoothDeviceClientImpl() {
67 object_manager_
->UnregisterInterface(
68 bluetooth_device::kExperimentalBluetoothDeviceInterface
);
71 // ExperimentalBluetoothDeviceClient override.
72 virtual void AddObserver(
73 ExperimentalBluetoothDeviceClient::Observer
* observer
) OVERRIDE
{
75 observers_
.AddObserver(observer
);
78 // ExperimentalBluetoothDeviceClient override.
79 virtual void RemoveObserver(
80 ExperimentalBluetoothDeviceClient::Observer
* observer
) OVERRIDE
{
82 observers_
.RemoveObserver(observer
);
85 // dbus::ObjectManager::Interface override.
86 virtual dbus::PropertySet
* CreateProperties(
87 dbus::ObjectProxy
* object_proxy
,
88 const dbus::ObjectPath
& object_path
,
89 const std::string
& interface_name
) OVERRIDE
{
90 Properties
* properties
= new Properties(
93 base::Bind(&ExperimentalBluetoothDeviceClientImpl::OnPropertyChanged
,
94 weak_ptr_factory_
.GetWeakPtr(),
96 return static_cast<dbus::PropertySet
*>(properties
);
99 // ExperimentalBluetoothDeviceClient override.
100 virtual std::vector
<dbus::ObjectPath
> GetDevicesForAdapter(
101 const dbus::ObjectPath
& adapter_path
) OVERRIDE
{
102 std::vector
<dbus::ObjectPath
> object_paths
, device_paths
;
103 device_paths
= object_manager_
->GetObjectsWithInterface(
104 bluetooth_device::kExperimentalBluetoothDeviceInterface
);
105 for (std::vector
<dbus::ObjectPath
>::iterator iter
= device_paths
.begin();
106 iter
!= device_paths
.end(); ++iter
) {
107 Properties
* properties
= GetProperties(*iter
);
108 if (properties
->adapter
.value() == adapter_path
)
109 object_paths
.push_back(*iter
);
114 // ExperimentalBluetoothDeviceClient override.
115 virtual Properties
* GetProperties(const dbus::ObjectPath
& object_path
)
117 return static_cast<Properties
*>(
118 object_manager_
->GetProperties(
120 bluetooth_device::kExperimentalBluetoothDeviceInterface
));
123 // ExperimentalBluetoothDeviceClient override.
124 virtual void Connect(const dbus::ObjectPath
& object_path
,
125 const base::Closure
& callback
,
126 const ErrorCallback
& error_callback
) OVERRIDE
{
127 dbus::MethodCall
method_call(
128 bluetooth_device::kExperimentalBluetoothDeviceInterface
,
129 bluetooth_device::kConnect
);
131 dbus::ObjectProxy
* object_proxy
=
132 object_manager_
->GetObjectProxy(object_path
);
134 error_callback
.Run(kUnknownDeviceError
, "");
138 // Connect may take an arbitrary length of time, so use no timeout.
139 object_proxy
->CallMethodWithErrorCallback(
141 dbus::ObjectProxy::TIMEOUT_INFINITE
,
142 base::Bind(&ExperimentalBluetoothDeviceClientImpl::OnSuccess
,
143 weak_ptr_factory_
.GetWeakPtr(), callback
),
144 base::Bind(&ExperimentalBluetoothDeviceClientImpl::OnError
,
145 weak_ptr_factory_
.GetWeakPtr(), error_callback
));
148 // ExperimentalBluetoothDeviceClient override.
149 virtual void Disconnect(const dbus::ObjectPath
& object_path
,
150 const base::Closure
& callback
,
151 const ErrorCallback
& error_callback
) OVERRIDE
{
152 dbus::MethodCall
method_call(
153 bluetooth_device::kExperimentalBluetoothDeviceInterface
,
154 bluetooth_device::kDisconnect
);
156 dbus::ObjectProxy
* object_proxy
=
157 object_manager_
->GetObjectProxy(object_path
);
159 error_callback
.Run(kUnknownDeviceError
, "");
163 object_proxy
->CallMethodWithErrorCallback(
165 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
166 base::Bind(&ExperimentalBluetoothDeviceClientImpl::OnSuccess
,
167 weak_ptr_factory_
.GetWeakPtr(), callback
),
168 base::Bind(&ExperimentalBluetoothDeviceClientImpl::OnError
,
169 weak_ptr_factory_
.GetWeakPtr(), error_callback
));
172 // ExperimentalBluetoothDeviceClient override.
173 virtual void ConnectProfile(const dbus::ObjectPath
& object_path
,
174 const std::string
& uuid
,
175 const base::Closure
& callback
,
176 const ErrorCallback
& error_callback
) OVERRIDE
{
177 dbus::MethodCall
method_call(
178 bluetooth_device::kExperimentalBluetoothDeviceInterface
,
179 bluetooth_device::kConnectProfile
);
181 dbus::MessageWriter
writer(&method_call
);
182 writer
.AppendString(uuid
);
184 dbus::ObjectProxy
* object_proxy
=
185 object_manager_
->GetObjectProxy(object_path
);
187 error_callback
.Run(kUnknownDeviceError
, "");
191 // Connect may take an arbitrary length of time, so use no timeout.
192 object_proxy
->CallMethodWithErrorCallback(
194 dbus::ObjectProxy::TIMEOUT_INFINITE
,
195 base::Bind(&ExperimentalBluetoothDeviceClientImpl::OnSuccess
,
196 weak_ptr_factory_
.GetWeakPtr(), callback
),
197 base::Bind(&ExperimentalBluetoothDeviceClientImpl::OnError
,
198 weak_ptr_factory_
.GetWeakPtr(), error_callback
));
201 // ExperimentalBluetoothDeviceClient override.
202 virtual void DisconnectProfile(const dbus::ObjectPath
& object_path
,
203 const std::string
& uuid
,
204 const base::Closure
& callback
,
205 const ErrorCallback
& error_callback
)
207 dbus::MethodCall
method_call(
208 bluetooth_device::kExperimentalBluetoothDeviceInterface
,
209 bluetooth_device::kDisconnectProfile
);
211 dbus::MessageWriter
writer(&method_call
);
212 writer
.AppendString(uuid
);
214 dbus::ObjectProxy
* object_proxy
=
215 object_manager_
->GetObjectProxy(object_path
);
217 error_callback
.Run(kUnknownDeviceError
, "");
221 object_proxy
->CallMethodWithErrorCallback(
223 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
224 base::Bind(&ExperimentalBluetoothDeviceClientImpl::OnSuccess
,
225 weak_ptr_factory_
.GetWeakPtr(), callback
),
226 base::Bind(&ExperimentalBluetoothDeviceClientImpl::OnError
,
227 weak_ptr_factory_
.GetWeakPtr(), error_callback
));
230 // ExperimentalBluetoothDeviceClient override.
231 virtual void Pair(const dbus::ObjectPath
& object_path
,
232 const base::Closure
& callback
,
233 const ErrorCallback
& error_callback
) OVERRIDE
{
234 dbus::MethodCall
method_call(
235 bluetooth_device::kExperimentalBluetoothDeviceInterface
,
236 bluetooth_device::kPair
);
238 dbus::ObjectProxy
* object_proxy
=
239 object_manager_
->GetObjectProxy(object_path
);
241 error_callback
.Run(kUnknownDeviceError
, "");
245 // Pairing may take an arbitrary length of time, so use no timeout.
246 object_proxy
->CallMethodWithErrorCallback(
248 dbus::ObjectProxy::TIMEOUT_INFINITE
,
249 base::Bind(&ExperimentalBluetoothDeviceClientImpl::OnSuccess
,
250 weak_ptr_factory_
.GetWeakPtr(), callback
),
251 base::Bind(&ExperimentalBluetoothDeviceClientImpl::OnError
,
252 weak_ptr_factory_
.GetWeakPtr(), error_callback
));
255 // ExperimentalBluetoothDeviceClient override.
256 virtual void CancelPairing(const dbus::ObjectPath
& object_path
,
257 const base::Closure
& callback
,
258 const ErrorCallback
& error_callback
)
260 dbus::MethodCall
method_call(
261 bluetooth_device::kExperimentalBluetoothDeviceInterface
,
262 bluetooth_device::kCancelPairing
);
264 dbus::ObjectProxy
* object_proxy
=
265 object_manager_
->GetObjectProxy(object_path
);
267 error_callback
.Run(kUnknownDeviceError
, "");
270 object_proxy
->CallMethodWithErrorCallback(
272 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
273 base::Bind(&ExperimentalBluetoothDeviceClientImpl::OnSuccess
,
274 weak_ptr_factory_
.GetWeakPtr(), callback
),
275 base::Bind(&ExperimentalBluetoothDeviceClientImpl::OnError
,
276 weak_ptr_factory_
.GetWeakPtr(), error_callback
));
280 // Called by dbus::ObjectManager when an object with the device interface
281 // is created. Informs observers.
282 virtual void ObjectAdded(const dbus::ObjectPath
& object_path
,
283 const std::string
& interface_name
) OVERRIDE
{
284 FOR_EACH_OBSERVER(ExperimentalBluetoothDeviceClient::Observer
,
286 DeviceAdded(object_path
));
289 // Called by dbus::ObjectManager when an object with the device interface
290 // is removed. Informs observers.
291 virtual void ObjectRemoved(const dbus::ObjectPath
& object_path
,
292 const std::string
& interface_name
) OVERRIDE
{
293 FOR_EACH_OBSERVER(ExperimentalBluetoothDeviceClient::Observer
,
295 DeviceRemoved(object_path
));
298 // Called by BluetoothPropertySet when a property value is changed,
299 // either by result of a signal or response to a GetAll() or Get()
300 // call. Informs observers.
301 void OnPropertyChanged(const dbus::ObjectPath
& object_path
,
302 const std::string
& property_name
) {
303 FOR_EACH_OBSERVER(ExperimentalBluetoothDeviceClient::Observer
, observers_
,
304 DevicePropertyChanged(object_path
, property_name
));
307 // Called when a response for successful method call is received.
308 void OnSuccess(const base::Closure
& callback
,
309 dbus::Response
* response
) {
314 // Called when a response for a failed method call is received.
315 void OnError(const ErrorCallback
& error_callback
,
316 dbus::ErrorResponse
* response
) {
317 // Error response has optional error message argument.
318 std::string error_name
;
319 std::string error_message
;
321 dbus::MessageReader
reader(response
);
322 error_name
= response
->GetErrorName();
323 reader
.PopString(&error_message
);
325 error_name
= kNoResponseError
;
328 error_callback
.Run(error_name
, error_message
);
332 dbus::ObjectManager
* object_manager_
;
334 // List of observers interested in event notifications from us.
335 ObserverList
<ExperimentalBluetoothDeviceClient::Observer
> observers_
;
337 // Weak pointer factory for generating 'this' pointers that might live longer
339 // Note: This should remain the last member so it'll be destroyed and
340 // invalidate its weak pointers before any other members are destroyed.
341 base::WeakPtrFactory
<ExperimentalBluetoothDeviceClientImpl
> weak_ptr_factory_
;
343 DISALLOW_COPY_AND_ASSIGN(ExperimentalBluetoothDeviceClientImpl
);
346 ExperimentalBluetoothDeviceClient::ExperimentalBluetoothDeviceClient() {
349 ExperimentalBluetoothDeviceClient::~ExperimentalBluetoothDeviceClient() {
352 ExperimentalBluetoothDeviceClient
* ExperimentalBluetoothDeviceClient::Create(
353 DBusClientImplementationType type
,
355 if (type
== REAL_DBUS_CLIENT_IMPLEMENTATION
)
356 return new ExperimentalBluetoothDeviceClientImpl(bus
);
357 DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION
, type
);
358 return new FakeBluetoothDeviceClient();
361 } // namespace chromeos