OLD | NEW |
| (Empty) |
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_adapter_client.h" | |
6 | |
7 #include "base/bind.h" | |
8 #include "base/logging.h" | |
9 #include "dbus/bus.h" | |
10 #include "dbus/message.h" | |
11 #include "dbus/object_manager.h" | |
12 #include "dbus/object_proxy.h" | |
13 #include "third_party/cros_system_api/dbus/service_constants.h" | |
14 | |
15 namespace chromeos { | |
16 | |
17 BluetoothAdapterClient::DiscoveryFilter::DiscoveryFilter() { | |
18 } | |
19 | |
20 BluetoothAdapterClient::DiscoveryFilter::~DiscoveryFilter() { | |
21 } | |
22 | |
23 void BluetoothAdapterClient::DiscoveryFilter::CopyFrom( | |
24 const DiscoveryFilter& filter) { | |
25 if (filter.rssi.get()) | |
26 rssi.reset(new int16_t(*filter.rssi)); | |
27 else | |
28 rssi.reset(); | |
29 | |
30 if (filter.pathloss.get()) | |
31 pathloss.reset(new uint16_t(*filter.pathloss)); | |
32 else | |
33 pathloss.reset(); | |
34 | |
35 if (filter.transport.get()) | |
36 transport.reset(new std::string(*filter.transport)); | |
37 else | |
38 transport.reset(); | |
39 | |
40 if (filter.uuids.get()) | |
41 uuids.reset(new std::vector<std::string>(*filter.uuids)); | |
42 else | |
43 uuids.reset(); | |
44 } | |
45 | |
46 const char BluetoothAdapterClient::kNoResponseError[] = | |
47 "org.chromium.Error.NoResponse"; | |
48 const char BluetoothAdapterClient::kUnknownAdapterError[] = | |
49 "org.chromium.Error.UnknownAdapter"; | |
50 | |
51 BluetoothAdapterClient::Properties::Properties( | |
52 dbus::ObjectProxy* object_proxy, | |
53 const std::string& interface_name, | |
54 const PropertyChangedCallback& callback) | |
55 : dbus::PropertySet(object_proxy, interface_name, callback) { | |
56 RegisterProperty(bluetooth_adapter::kAddressProperty, &address); | |
57 RegisterProperty(bluetooth_adapter::kNameProperty, &name); | |
58 RegisterProperty(bluetooth_adapter::kAliasProperty, &alias); | |
59 RegisterProperty(bluetooth_adapter::kClassProperty, &bluetooth_class); | |
60 RegisterProperty(bluetooth_adapter::kPoweredProperty, &powered); | |
61 RegisterProperty(bluetooth_adapter::kDiscoverableProperty, &discoverable); | |
62 RegisterProperty(bluetooth_adapter::kPairableProperty, &pairable); | |
63 RegisterProperty(bluetooth_adapter::kPairableTimeoutProperty, | |
64 &pairable_timeout); | |
65 RegisterProperty(bluetooth_adapter::kDiscoverableTimeoutProperty, | |
66 &discoverable_timeout); | |
67 RegisterProperty(bluetooth_adapter::kDiscoveringProperty, &discovering); | |
68 RegisterProperty(bluetooth_adapter::kUUIDsProperty, &uuids); | |
69 RegisterProperty(bluetooth_adapter::kModaliasProperty, &modalias); | |
70 } | |
71 | |
72 BluetoothAdapterClient::Properties::~Properties() { | |
73 } | |
74 | |
75 | |
76 // The BluetoothAdapterClient implementation used in production. | |
77 class BluetoothAdapterClientImpl | |
78 : public BluetoothAdapterClient, | |
79 public dbus::ObjectManager::Interface { | |
80 public: | |
81 BluetoothAdapterClientImpl() | |
82 : object_manager_(NULL), weak_ptr_factory_(this) {} | |
83 | |
84 ~BluetoothAdapterClientImpl() override { | |
85 object_manager_->UnregisterInterface( | |
86 bluetooth_adapter::kBluetoothAdapterInterface); | |
87 } | |
88 | |
89 // BluetoothAdapterClient override. | |
90 void AddObserver(BluetoothAdapterClient::Observer* observer) override { | |
91 DCHECK(observer); | |
92 observers_.AddObserver(observer); | |
93 } | |
94 | |
95 // BluetoothAdapterClient override. | |
96 void RemoveObserver(BluetoothAdapterClient::Observer* observer) override { | |
97 DCHECK(observer); | |
98 observers_.RemoveObserver(observer); | |
99 } | |
100 | |
101 // Returns the list of adapter object paths known to the system. | |
102 std::vector<dbus::ObjectPath> GetAdapters() override { | |
103 return object_manager_->GetObjectsWithInterface( | |
104 bluetooth_adapter::kBluetoothAdapterInterface); | |
105 } | |
106 | |
107 // dbus::ObjectManager::Interface override. | |
108 dbus::PropertySet* CreateProperties( | |
109 dbus::ObjectProxy* object_proxy, | |
110 const dbus::ObjectPath& object_path, | |
111 const std::string& interface_name) override { | |
112 Properties* properties = new Properties( | |
113 object_proxy, | |
114 interface_name, | |
115 base::Bind(&BluetoothAdapterClientImpl::OnPropertyChanged, | |
116 weak_ptr_factory_.GetWeakPtr(), | |
117 object_path)); | |
118 return static_cast<dbus::PropertySet*>(properties); | |
119 } | |
120 | |
121 // BluetoothAdapterClient override. | |
122 Properties* GetProperties(const dbus::ObjectPath& object_path) override { | |
123 return static_cast<Properties*>( | |
124 object_manager_->GetProperties( | |
125 object_path, | |
126 bluetooth_adapter::kBluetoothAdapterInterface)); | |
127 } | |
128 | |
129 // BluetoothAdapterClient override. | |
130 void StartDiscovery(const dbus::ObjectPath& object_path, | |
131 const base::Closure& callback, | |
132 const ErrorCallback& error_callback) override { | |
133 dbus::MethodCall method_call( | |
134 bluetooth_adapter::kBluetoothAdapterInterface, | |
135 bluetooth_adapter::kStartDiscovery); | |
136 | |
137 dbus::ObjectProxy* object_proxy = | |
138 object_manager_->GetObjectProxy(object_path); | |
139 if (!object_proxy) { | |
140 error_callback.Run(kUnknownAdapterError, ""); | |
141 return; | |
142 } | |
143 | |
144 object_proxy->CallMethodWithErrorCallback( | |
145 &method_call, | |
146 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, | |
147 base::Bind(&BluetoothAdapterClientImpl::OnSuccess, | |
148 weak_ptr_factory_.GetWeakPtr(), callback), | |
149 base::Bind(&BluetoothAdapterClientImpl::OnError, | |
150 weak_ptr_factory_.GetWeakPtr(), error_callback)); | |
151 } | |
152 | |
153 // BluetoothAdapterClient override. | |
154 void StopDiscovery(const dbus::ObjectPath& object_path, | |
155 const base::Closure& callback, | |
156 const ErrorCallback& error_callback) override { | |
157 dbus::MethodCall method_call( | |
158 bluetooth_adapter::kBluetoothAdapterInterface, | |
159 bluetooth_adapter::kStopDiscovery); | |
160 | |
161 dbus::ObjectProxy* object_proxy = | |
162 object_manager_->GetObjectProxy(object_path); | |
163 if (!object_proxy) { | |
164 error_callback.Run(kUnknownAdapterError, ""); | |
165 return; | |
166 } | |
167 | |
168 object_proxy->CallMethodWithErrorCallback( | |
169 &method_call, | |
170 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, | |
171 base::Bind(&BluetoothAdapterClientImpl::OnSuccess, | |
172 weak_ptr_factory_.GetWeakPtr(), callback), | |
173 base::Bind(&BluetoothAdapterClientImpl::OnError, | |
174 weak_ptr_factory_.GetWeakPtr(), error_callback)); | |
175 } | |
176 | |
177 // BluetoothAdapterClient override. | |
178 void RemoveDevice(const dbus::ObjectPath& object_path, | |
179 const dbus::ObjectPath& device_path, | |
180 const base::Closure& callback, | |
181 const ErrorCallback& error_callback) override { | |
182 dbus::MethodCall method_call( | |
183 bluetooth_adapter::kBluetoothAdapterInterface, | |
184 bluetooth_adapter::kRemoveDevice); | |
185 | |
186 dbus::MessageWriter writer(&method_call); | |
187 writer.AppendObjectPath(device_path); | |
188 | |
189 dbus::ObjectProxy* object_proxy = | |
190 object_manager_->GetObjectProxy(object_path); | |
191 if (!object_proxy) { | |
192 error_callback.Run(kUnknownAdapterError, ""); | |
193 return; | |
194 } | |
195 | |
196 object_proxy->CallMethodWithErrorCallback( | |
197 &method_call, | |
198 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, | |
199 base::Bind(&BluetoothAdapterClientImpl::OnSuccess, | |
200 weak_ptr_factory_.GetWeakPtr(), callback), | |
201 base::Bind(&BluetoothAdapterClientImpl::OnError, | |
202 weak_ptr_factory_.GetWeakPtr(), error_callback)); | |
203 } | |
204 | |
205 // BluetoothAdapterClient override. | |
206 void SetDiscoveryFilter(const dbus::ObjectPath& object_path, | |
207 const DiscoveryFilter& discovery_filter, | |
208 const base::Closure& callback, | |
209 const ErrorCallback& error_callback) override { | |
210 dbus::MethodCall method_call(bluetooth_adapter::kBluetoothAdapterInterface, | |
211 bluetooth_adapter::kSetDiscoveryFilter); | |
212 | |
213 dbus::MessageWriter writer(&method_call); | |
214 dbus::MessageWriter dict_writer(nullptr); | |
215 | |
216 dbus::ObjectProxy* object_proxy = | |
217 object_manager_->GetObjectProxy(object_path); | |
218 if (!object_proxy) { | |
219 error_callback.Run(kUnknownAdapterError, ""); | |
220 return; | |
221 } | |
222 | |
223 writer.OpenArray("{sv}", &dict_writer); | |
224 | |
225 if (discovery_filter.uuids.get()) { | |
226 std::vector<std::string>* uuids = discovery_filter.uuids.get(); | |
227 dbus::MessageWriter uuids_entry_writer(nullptr); | |
228 dict_writer.OpenDictEntry(&uuids_entry_writer); | |
229 uuids_entry_writer.AppendString( | |
230 bluetooth_adapter::kDiscoveryFilterParameterUUIDs); | |
231 | |
232 dbus::MessageWriter uuids_array_variant(nullptr); | |
233 uuids_entry_writer.OpenVariant("as", &uuids_array_variant); | |
234 dbus::MessageWriter uuids_array(nullptr); | |
235 uuids_array_variant.OpenArray("s", &uuids_array); | |
236 | |
237 for (auto& it : *uuids) | |
238 uuids_array.AppendString(it); | |
239 | |
240 uuids_array_variant.CloseContainer(&uuids_array); | |
241 uuids_entry_writer.CloseContainer(&uuids_array_variant); | |
242 dict_writer.CloseContainer(&uuids_entry_writer); | |
243 } | |
244 | |
245 if (discovery_filter.rssi.get()) { | |
246 dbus::MessageWriter rssi_entry_writer(nullptr); | |
247 dict_writer.OpenDictEntry(&rssi_entry_writer); | |
248 rssi_entry_writer.AppendString( | |
249 bluetooth_adapter::kDiscoveryFilterParameterRSSI); | |
250 rssi_entry_writer.AppendVariantOfInt16(*discovery_filter.rssi.get()); | |
251 dict_writer.CloseContainer(&rssi_entry_writer); | |
252 } | |
253 | |
254 if (discovery_filter.pathloss.get()) { | |
255 dbus::MessageWriter pathloss_entry_writer(nullptr); | |
256 dict_writer.OpenDictEntry(&pathloss_entry_writer); | |
257 pathloss_entry_writer.AppendString( | |
258 bluetooth_adapter::kDiscoveryFilterParameterPathloss); | |
259 pathloss_entry_writer.AppendVariantOfUint16( | |
260 *discovery_filter.pathloss.get()); | |
261 dict_writer.CloseContainer(&pathloss_entry_writer); | |
262 } | |
263 | |
264 if (discovery_filter.transport.get()) { | |
265 dbus::MessageWriter transport_entry_writer(nullptr); | |
266 dict_writer.OpenDictEntry(&transport_entry_writer); | |
267 transport_entry_writer.AppendString( | |
268 bluetooth_adapter::kDiscoveryFilterParameterTransport); | |
269 transport_entry_writer.AppendVariantOfString( | |
270 *discovery_filter.transport.get()); | |
271 dict_writer.CloseContainer(&transport_entry_writer); | |
272 } | |
273 | |
274 writer.CloseContainer(&dict_writer); | |
275 | |
276 object_proxy->CallMethodWithErrorCallback( | |
277 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, | |
278 base::Bind(&BluetoothAdapterClientImpl::OnSuccess, | |
279 weak_ptr_factory_.GetWeakPtr(), callback), | |
280 base::Bind(&BluetoothAdapterClientImpl::OnError, | |
281 weak_ptr_factory_.GetWeakPtr(), error_callback)); | |
282 } | |
283 | |
284 protected: | |
285 void Init(dbus::Bus* bus) override { | |
286 object_manager_ = bus->GetObjectManager( | |
287 bluetooth_object_manager::kBluetoothObjectManagerServiceName, | |
288 dbus::ObjectPath( | |
289 bluetooth_object_manager::kBluetoothObjectManagerServicePath)); | |
290 object_manager_->RegisterInterface( | |
291 bluetooth_adapter::kBluetoothAdapterInterface, this); | |
292 } | |
293 | |
294 private: | |
295 // Called by dbus::ObjectManager when an object with the adapter interface | |
296 // is created. Informs observers. | |
297 void ObjectAdded(const dbus::ObjectPath& object_path, | |
298 const std::string& interface_name) override { | |
299 FOR_EACH_OBSERVER(BluetoothAdapterClient::Observer, observers_, | |
300 AdapterAdded(object_path)); | |
301 } | |
302 | |
303 // Called by dbus::ObjectManager when an object with the adapter interface | |
304 // is removed. Informs observers. | |
305 void ObjectRemoved(const dbus::ObjectPath& object_path, | |
306 const std::string& interface_name) override { | |
307 FOR_EACH_OBSERVER(BluetoothAdapterClient::Observer, observers_, | |
308 AdapterRemoved(object_path)); | |
309 } | |
310 | |
311 // Called by dbus::PropertySet when a property value is changed, | |
312 // either by result of a signal or response to a GetAll() or Get() | |
313 // call. Informs observers. | |
314 void OnPropertyChanged(const dbus::ObjectPath& object_path, | |
315 const std::string& property_name) { | |
316 FOR_EACH_OBSERVER(BluetoothAdapterClient::Observer, observers_, | |
317 AdapterPropertyChanged(object_path, property_name)); | |
318 } | |
319 | |
320 // Called when a response for successful method call is received. | |
321 void OnSuccess(const base::Closure& callback, | |
322 dbus::Response* response) { | |
323 DCHECK(response); | |
324 callback.Run(); | |
325 } | |
326 | |
327 // Called when a response for a failed method call is received. | |
328 void OnError(const ErrorCallback& error_callback, | |
329 dbus::ErrorResponse* response) { | |
330 // Error response has optional error message argument. | |
331 std::string error_name; | |
332 std::string error_message; | |
333 if (response) { | |
334 dbus::MessageReader reader(response); | |
335 error_name = response->GetErrorName(); | |
336 reader.PopString(&error_message); | |
337 } else { | |
338 error_name = kNoResponseError; | |
339 error_message = ""; | |
340 } | |
341 error_callback.Run(error_name, error_message); | |
342 } | |
343 | |
344 dbus::ObjectManager* object_manager_; | |
345 | |
346 // List of observers interested in event notifications from us. | |
347 base::ObserverList<BluetoothAdapterClient::Observer> observers_; | |
348 | |
349 // Weak pointer factory for generating 'this' pointers that might live longer | |
350 // than we do. | |
351 // Note: This should remain the last member so it'll be destroyed and | |
352 // invalidate its weak pointers before any other members are destroyed. | |
353 base::WeakPtrFactory<BluetoothAdapterClientImpl> | |
354 weak_ptr_factory_; | |
355 | |
356 DISALLOW_COPY_AND_ASSIGN(BluetoothAdapterClientImpl); | |
357 }; | |
358 | |
359 BluetoothAdapterClient::BluetoothAdapterClient() { | |
360 } | |
361 | |
362 BluetoothAdapterClient::~BluetoothAdapterClient() { | |
363 } | |
364 | |
365 BluetoothAdapterClient* BluetoothAdapterClient::Create() { | |
366 return new BluetoothAdapterClientImpl; | |
367 } | |
368 | |
369 } // namespace chromeos | |
OLD | NEW |