Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(84)

Side by Side Diff: device/bluetooth/bluetooth_adapter_experimental_chromeos.cc

Issue 13927010: Bluetooth: implement BlueZ 5 backend for Chrome OS (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "device/bluetooth/bluetooth_adapter_experimental_chromeos.h" 5 #include "device/bluetooth/bluetooth_adapter_experimental_chromeos.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/bind.h"
10 #include "base/logging.h"
11 #include "chromeos/dbus/dbus_thread_manager.h"
12 #include "chromeos/dbus/experimental_bluetooth_adapter_client.h"
13 #include "chromeos/dbus/experimental_bluetooth_device_client.h"
14 #include "device/bluetooth/bluetooth_device.h"
15 #include "device/bluetooth/bluetooth_device_experimental_chromeos.h"
16
9 using device::BluetoothAdapter; 17 using device::BluetoothAdapter;
18 using device::BluetoothDevice;
10 19
11 namespace chromeos { 20 namespace chromeos {
12 21
13 BluetoothAdapterExperimentalChromeOS::BluetoothAdapterExperimentalChromeOS() 22 BluetoothAdapterExperimentalChromeOS::BluetoothAdapterExperimentalChromeOS()
14 : BluetoothAdapter(), 23 : weak_ptr_factory_(this) {
15 weak_ptr_factory_(this) { 24 DBusThreadManager::Get()->GetExperimentalBluetoothAdapterClient()->
25 AddObserver(this);
26 DBusThreadManager::Get()->GetExperimentalBluetoothDeviceClient()->
27 AddObserver(this);
28
29 std::vector<dbus::ObjectPath> object_paths =
30 DBusThreadManager::Get()->GetExperimentalBluetoothAdapterClient()->
31 GetAdapters();
32
33 if (!object_paths.empty()) {
34 VLOG(1) << object_paths.size() << " Bluetooth adapter(s) available.";
35 SetAdapter(object_paths[0]);
36 }
16 } 37 }
17 38
18 BluetoothAdapterExperimentalChromeOS::~BluetoothAdapterExperimentalChromeOS() { 39 BluetoothAdapterExperimentalChromeOS::~BluetoothAdapterExperimentalChromeOS() {
40 DBusThreadManager::Get()->GetExperimentalBluetoothAdapterClient()->
41 RemoveObserver(this);
42 DBusThreadManager::Get()->GetExperimentalBluetoothDeviceClient()->
43 RemoveObserver(this);
19 } 44 }
20 45
21 void BluetoothAdapterExperimentalChromeOS::AddObserver( 46 void BluetoothAdapterExperimentalChromeOS::AddObserver(
22 BluetoothAdapter::Observer* observer) { 47 BluetoothAdapter::Observer* observer) {
48 DCHECK(observer);
49 observers_.AddObserver(observer);
23 } 50 }
24 51
25 void BluetoothAdapterExperimentalChromeOS::RemoveObserver( 52 void BluetoothAdapterExperimentalChromeOS::RemoveObserver(
26 BluetoothAdapter::Observer* observer) { 53 BluetoothAdapter::Observer* observer) {
54 DCHECK(observer);
55 observers_.RemoveObserver(observer);
27 } 56 }
28 57
29 std::string BluetoothAdapterExperimentalChromeOS::GetAddress() const { 58 std::string BluetoothAdapterExperimentalChromeOS::GetAddress() const {
30 return std::string(); 59 if (object_path_.value().empty())
60 return std::string();
61
62 ExperimentalBluetoothAdapterClient::Properties* properties =
63 DBusThreadManager::Get()->GetExperimentalBluetoothAdapterClient()->
64 GetProperties(object_path_);
65 DCHECK(properties);
66
67 return properties->address.value();
31 } 68 }
32 69
33 std::string BluetoothAdapterExperimentalChromeOS::GetName() const { 70 std::string BluetoothAdapterExperimentalChromeOS::GetName() const {
34 return std::string(); 71 if (object_path_.value().empty())
72 return std::string();
73
74 ExperimentalBluetoothAdapterClient::Properties* properties =
75 DBusThreadManager::Get()->GetExperimentalBluetoothAdapterClient()->
76 GetProperties(object_path_);
77 DCHECK(properties);
78
79 return properties->alias.value();
35 } 80 }
36 81
37 bool BluetoothAdapterExperimentalChromeOS::IsInitialized() const { 82 bool BluetoothAdapterExperimentalChromeOS::IsInitialized() const {
38 return true; 83 return true;
39 } 84 }
40 85
41 bool BluetoothAdapterExperimentalChromeOS::IsPresent() const { 86 bool BluetoothAdapterExperimentalChromeOS::IsPresent() const {
42 return false; 87 return !object_path_.value().empty();
43 } 88 }
44 89
45 bool BluetoothAdapterExperimentalChromeOS::IsPowered() const { 90 bool BluetoothAdapterExperimentalChromeOS::IsPowered() const {
46 return false; 91 if (object_path_.value().empty())
youngki 2013/04/16 15:26:56 Would it be more elegant if we reuse IsPresent() h
keybuk 2013/04/16 23:19:13 Done.
92 return false;
93
94 ExperimentalBluetoothAdapterClient::Properties* properties =
95 DBusThreadManager::Get()->GetExperimentalBluetoothAdapterClient()->
96 GetProperties(object_path_);
97
98 return properties->powered.value();
47 } 99 }
48 100
49 void BluetoothAdapterExperimentalChromeOS::SetPowered(bool powered, 101 void BluetoothAdapterExperimentalChromeOS::SetPowered(
50 const base::Closure& callback, 102 bool powered,
51 const ErrorCallback& error_callback) { 103 const base::Closure& callback,
52 error_callback.Run(); 104 const ErrorCallback& error_callback) {
105 DBusThreadManager::Get()->GetExperimentalBluetoothAdapterClient()->
106 GetProperties(object_path_)->powered.Set(
107 powered,
108 base::Bind(&BluetoothAdapterExperimentalChromeOS::OnSetPowered,
109 weak_ptr_factory_.GetWeakPtr(),
110 callback, error_callback));
youngki 2013/04/16 15:26:56 style nits: one argument per line.
keybuk 2013/04/16 23:19:13 Done.
53 } 111 }
54 112
55 bool BluetoothAdapterExperimentalChromeOS::IsDiscovering() const { 113 bool BluetoothAdapterExperimentalChromeOS::IsDiscovering() const {
56 return false; 114 if (object_path_.value().empty())
youngki 2013/04/16 15:26:56 Can we reuse IsPresent()? if (!IsPresent()) ret
keybuk 2013/04/16 23:19:13 Done.
115 return false;
116
117 ExperimentalBluetoothAdapterClient::Properties* properties =
118 DBusThreadManager::Get()->GetExperimentalBluetoothAdapterClient()->
119 GetProperties(object_path_);
120
121 return properties->discovering.value();
57 } 122 }
58 123
59 void BluetoothAdapterExperimentalChromeOS::StartDiscovering( 124 void BluetoothAdapterExperimentalChromeOS::StartDiscovering(
60 const base::Closure& callback, 125 const base::Closure& callback,
61 const ErrorCallback& error_callback) { 126 const ErrorCallback& error_callback) {
62 error_callback.Run(); 127 // BlueZ counts discovery sessions, and permits multiple sessions for a
128 // single connection, so issue a StartDiscovery() call for every use
129 // within Chromium for the right behavior.
130 DBusThreadManager::Get()->GetExperimentalBluetoothAdapterClient()->
131 StartDiscovery(
132 object_path_,
133 base::Bind(
134 &BluetoothAdapterExperimentalChromeOS::OnStartDiscovery,
135 weak_ptr_factory_.GetWeakPtr(),
136 callback),
137 base::Bind(
138 &BluetoothAdapterExperimentalChromeOS::OnStartDiscoveryError,
139 weak_ptr_factory_.GetWeakPtr(),
140 error_callback));
63 } 141 }
64 142
65 void BluetoothAdapterExperimentalChromeOS::StopDiscovering( 143 void BluetoothAdapterExperimentalChromeOS::StopDiscovering(
66 const base::Closure& callback, 144 const base::Closure& callback,
67 const ErrorCallback& error_callback) { 145 const ErrorCallback& error_callback) {
68 error_callback.Run(); 146 // Inform BlueZ to stop one of our open discovery sessions.
147 DBusThreadManager::Get()->GetExperimentalBluetoothAdapterClient()->
148 StopDiscovery(
149 object_path_,
150 base::Bind(
151 &BluetoothAdapterExperimentalChromeOS::OnStopDiscovery,
152 weak_ptr_factory_.GetWeakPtr(),
153 callback),
154 base::Bind(
155 &BluetoothAdapterExperimentalChromeOS::OnStopDiscoveryError,
156 weak_ptr_factory_.GetWeakPtr(),
157 error_callback));
69 } 158 }
70 159
71 void BluetoothAdapterExperimentalChromeOS::ReadLocalOutOfBandPairingData( 160 void BluetoothAdapterExperimentalChromeOS::ReadLocalOutOfBandPairingData(
72 const BluetoothAdapter::BluetoothOutOfBandPairingDataCallback& callback, 161 const BluetoothAdapter::BluetoothOutOfBandPairingDataCallback& callback,
73 const ErrorCallback& error_callback) { 162 const ErrorCallback& error_callback) {
74 error_callback.Run(); 163 error_callback.Run();
75 } 164 }
76 165
166 void BluetoothAdapterExperimentalChromeOS::AdapterAdded(
167 const dbus::ObjectPath& object_path) {
168 if (object_path_.value().empty())
satorux1 2013/04/16 06:30:45 Did you mean: if (!object_path_.value().empty())
keybuk 2013/04/16 23:19:13 No, this only sets the adapter if it *isn't* alrea
169 SetAdapter(object_path);
170 }
171
172 void BluetoothAdapterExperimentalChromeOS::AdapterRemoved(
173 const dbus::ObjectPath& object_path) {
174 if (object_path == object_path_)
175 RemoveAdapter();
176 }
177
178 void BluetoothAdapterExperimentalChromeOS::AdapterPropertyChanged(
179 const dbus::ObjectPath& object_path,
180 const std::string& property_name) {
181 if (object_path != object_path_)
182 return;
183
184 ExperimentalBluetoothAdapterClient::Properties* properties =
185 DBusThreadManager::Get()->GetExperimentalBluetoothAdapterClient()->
186 GetProperties(object_path_);
187
188 if (property_name == properties->powered.name())
189 PoweredChanged(properties->powered.value());
190 else if (property_name == properties->discovering.name())
191 DiscoveringChanged(properties->discovering.value());
192 }
193
194 void BluetoothAdapterExperimentalChromeOS::DeviceAdded(
195 const dbus::ObjectPath& object_path) {
196 ExperimentalBluetoothDeviceClient::Properties* properties =
197 DBusThreadManager::Get()->GetExperimentalBluetoothDeviceClient()->
198 GetProperties(object_path);
199 if (properties->adapter.value() != object_path_)
200 return;
201
202 BluetoothDeviceExperimentalChromeOS* device_chromeos =
203 new BluetoothDeviceExperimentalChromeOS(this, object_path);
204
youngki 2013/04/16 15:26:56 Can we put DCHECK here that devices_[device_chrome
keybuk 2013/04/16 23:19:13 Done.
205 devices_[device_chromeos->GetAddress()] = device_chromeos;
206
207 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
208 DeviceAdded(this, device_chromeos));
209 }
210
211 void BluetoothAdapterExperimentalChromeOS::DeviceRemoved(
212 const dbus::ObjectPath& object_path) {
213 for (DevicesMap::iterator iter = devices_.begin();
214 iter != devices_.end(); ++iter) {
215 BluetoothDeviceExperimentalChromeOS* device_chromeos =
216 static_cast<BluetoothDeviceExperimentalChromeOS*>(iter->second);
217 if (device_chromeos->object_path() == object_path) {
218 devices_.erase(iter);
219
220 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
221 DeviceRemoved(this, device_chromeos));
222 delete device_chromeos;
223 return;
224 }
225 }
226 }
227
228 void BluetoothAdapterExperimentalChromeOS::DevicePropertyChanged(
229 const dbus::ObjectPath& object_path,
230 const std::string& property_name) {
231 BluetoothDeviceExperimentalChromeOS* device_chromeos =
232 GetDeviceWithPath(object_path);
233 if (!device_chromeos)
234 return;
235
236 ExperimentalBluetoothDeviceClient::Properties* properties =
237 DBusThreadManager::Get()->GetExperimentalBluetoothDeviceClient()->
238 GetProperties(object_path);
239
240 if (property_name == properties->bluetooth_class.name() ||
241 property_name == properties->alias.name() ||
242 property_name == properties->paired.name() ||
243 property_name == properties->connected.name() ||
244 property_name == properties->uuids.name()) {
245 FOR_EACH_OBSERVER(
246 BluetoothAdapter::Observer, observers_,
247 DeviceChanged(this, static_cast<BluetoothDevice*>(device_chromeos)));
youngki 2013/04/16 15:26:56 I don't think this cast is necessary since Bluetoo
keybuk 2013/04/16 23:19:13 Done.
248 }
249 }
250
251 BluetoothDeviceExperimentalChromeOS*
252 BluetoothAdapterExperimentalChromeOS::GetDeviceWithPath(
253 const dbus::ObjectPath& object_path) {
254 for (DevicesMap::iterator iter = devices_.begin();
255 iter != devices_.end(); ++iter) {
256 BluetoothDeviceExperimentalChromeOS* device_chromeos =
257 static_cast<BluetoothDeviceExperimentalChromeOS*>(iter->second);
258 if (device_chromeos->object_path() == object_path)
259 return device_chromeos;
260 }
261
262 return NULL;
263 }
264
265 void BluetoothAdapterExperimentalChromeOS::SetAdapter(
266 const dbus::ObjectPath& object_path)
267 {
268 DCHECK(object_path_.value().empty());
269 object_path_ = object_path;
270
271 VLOG(1) << object_path_.value() << ": using adapter.";
272
273 ExperimentalBluetoothAdapterClient::Properties* properties =
274 DBusThreadManager::Get()->GetExperimentalBluetoothAdapterClient()->
275 GetProperties(object_path_);
276
277 PresentChanged(true);
278
279 if (properties->powered.value() != false)
youngki 2013/04/16 15:26:56 change it to if (properties->powered.value())
keybuk 2013/04/16 23:19:13 Done.
280 PoweredChanged(properties->powered.value());
youngki 2013/04/16 15:26:56 Also I think we should just make it PoweredChanged
keybuk 2013/04/16 23:19:13 Done.
281 if (properties->discovering.value() != false)
youngki 2013/04/16 15:26:56 change it to if (properties->discovering.value())
keybuk 2013/04/16 23:19:13 Done.
282 DiscoveringChanged(properties->discovering.value());
youngki 2013/04/16 15:26:56 Change it to DiscoveringChanged(true) also.
keybuk 2013/04/16 23:19:13 Done.
283
284 std::vector<dbus::ObjectPath> device_paths =
285 DBusThreadManager::Get()->GetExperimentalBluetoothDeviceClient()->
286 GetDevicesForAdapter(object_path_);
287
288 for (std::vector<dbus::ObjectPath>::iterator iter = device_paths.begin();
289 iter != device_paths.end(); ++iter) {
290 BluetoothDeviceExperimentalChromeOS* device_chromeos =
291 new BluetoothDeviceExperimentalChromeOS(this, *iter);
292
293 devices_[device_chromeos->GetAddress()] = device_chromeos;
294
295 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
296 DeviceAdded(this, device_chromeos));
297 }
298 }
299
300 void BluetoothAdapterExperimentalChromeOS::RemoveAdapter()
301 {
302 DCHECK(!object_path_.value().empty());
youngki 2013/04/16 15:26:56 DCHECK(IsPresent());
keybuk 2013/04/16 23:19:13 Done.
303 VLOG(1) << object_path_.value() << ": adapter removed.";
304
305 ExperimentalBluetoothAdapterClient::Properties* properties =
306 DBusThreadManager::Get()->GetExperimentalBluetoothAdapterClient()->
307 GetProperties(object_path_);
308
309 object_path_ = dbus::ObjectPath("");
310
311 if (properties->powered.value() != false)
youngki 2013/04/16 15:26:56 change it to if (properties->powered.value())
keybuk 2013/04/16 23:19:13 Done.
312 PoweredChanged(false);
youngki 2013/04/16 15:26:56 Are you sure this logic is right? This looks to me
keybuk 2013/04/16 23:19:13 "if powered was on, the adapter is going buh-bye,
313 if (properties->discovering.value() != false)
youngki 2013/04/16 15:26:56 change it to if (properties->discovering.value())
keybuk 2013/04/16 23:19:13 Done.
314 DiscoveringChanged(false);
315
316 // Copy the devices list here and clear the original so that when we
317 // send DeviceRemoved(), GetDevices() returns no devices.
318 DevicesMap devices = devices_;
319 devices_.clear();
320
321 for (DevicesMap::iterator iter = devices.begin();
322 iter != devices.end(); ++iter) {
323 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
324 DeviceRemoved(this, iter->second));
325 delete iter->second;
326 }
327
328 PresentChanged(false);
329 }
330
331 void BluetoothAdapterExperimentalChromeOS::PoweredChanged(bool powered)
332 {
333 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
334 AdapterPoweredChanged(this, powered));
335 }
336
337 void BluetoothAdapterExperimentalChromeOS::DiscoveringChanged(bool discovering)
338 {
339 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
340 AdapterDiscoveringChanged(this, discovering));
341 }
342
343 void BluetoothAdapterExperimentalChromeOS::PresentChanged(bool present)
344 {
345 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
346 AdapterPresentChanged(this, present));
347 }
348
349 void BluetoothAdapterExperimentalChromeOS::OnSetPowered(
350 const base::Closure& callback,
351 const ErrorCallback& error_callback,
352 bool success)
353 {
satorux1 2013/04/16 06:30:45 nit: move { to the previous line
keybuk 2013/04/16 23:19:13 Done.
354 if (success)
355 callback.Run();
356 else
357 error_callback.Run();
358 }
359
360 void BluetoothAdapterExperimentalChromeOS::OnStartDiscovery(
361 const base::Closure& callback) {
362 callback.Run();
363 }
364
365 void BluetoothAdapterExperimentalChromeOS::OnStartDiscoveryError(
366 const ErrorCallback& error_callback,
367 const std::string& error_name,
368 const std::string& error_message)
369 {
satorux1 2013/04/16 06:30:45 ditto
keybuk 2013/04/16 23:19:13 Done.
370 LOG(WARNING) << object_path_.value() << ": Failed to start discovery: "
371 << error_name << ": " << error_message;
372 error_callback.Run();
373 }
374
375 void BluetoothAdapterExperimentalChromeOS::OnStopDiscovery(
376 const base::Closure& callback) {
377 callback.Run();
378 }
379
380 void BluetoothAdapterExperimentalChromeOS::OnStopDiscoveryError(
381 const ErrorCallback& error_callback,
382 const std::string& error_name,
383 const std::string& error_message)
384 {
satorux1 2013/04/16 06:30:45 ditto
keybuk 2013/04/16 23:19:13 Done.
385 LOG(WARNING) << object_path_.value() << ": Failed to stop discovery: "
386 << error_name << ": " << error_message;
387 error_callback.Run();
388 }
389
77 } // namespace chromeos 390 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698