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

Side by Side Diff: chrome/browser/chromeos/bluetooth/bluetooth_device.cc

Issue 10899037: Refactoring bluetooth API code. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: I Created 8 years, 2 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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "chrome/browser/chromeos/bluetooth/bluetooth_device.h" 5 #include "chrome/browser/chromeos/bluetooth/bluetooth_device.h"
6 6
7 #include <map>
8 #include <string>
9 #include <vector>
10
11 #include "base/bind.h"
12 #include "base/command_line.h"
13 #include "base/logging.h"
14 #include "base/memory/scoped_vector.h"
15 #include "base/memory/weak_ptr.h"
16 #include "base/string16.h"
17 #include "base/string_util.h"
18 #include "base/utf_string_conversions.h" 7 #include "base/utf_string_conversions.h"
19 #include "base/values.h"
20 #include "chrome/browser/chromeos/bluetooth/bluetooth_adapter.h"
21 #include "chrome/browser/chromeos/bluetooth/bluetooth_service_record.h"
22 #include "chrome/browser/chromeos/bluetooth/bluetooth_socket.h"
23 #include "chrome/browser/chromeos/bluetooth/bluetooth_utils.h"
24 #include "chrome/common/chrome_switches.h"
25 #include "chromeos/dbus/bluetooth_adapter_client.h"
26 #include "chromeos/dbus/bluetooth_agent_service_provider.h"
27 #include "chromeos/dbus/bluetooth_device_client.h"
28 #include "chromeos/dbus/bluetooth_input_client.h"
29 #include "chromeos/dbus/bluetooth_out_of_band_client.h"
30 #include "chromeos/dbus/dbus_thread_manager.h"
31 #include "chromeos/dbus/introspectable_client.h"
32 #include "dbus/bus.h"
33 #include "dbus/object_path.h"
34 #include "grit/generated_resources.h" 8 #include "grit/generated_resources.h"
35 #include "third_party/cros_system_api/dbus/service_constants.h"
36 #include "ui/base/l10n/l10n_util.h" 9 #include "ui/base/l10n/l10n_util.h"
37 10
38 namespace chromeos { 11 namespace chromeos {
39 12
40 BluetoothDevice::BluetoothDevice(BluetoothAdapter* adapter) 13 BluetoothDevice::BluetoothDevice()
41 : adapter_(adapter), 14 : bluetooth_class_(0),
42 bluetooth_class_(0), 15 visible_(false),
43 visible_(false), 16 bonded_(false),
44 bonded_(false), 17 connected_(false) {
45 connected_(false),
46 pairing_delegate_(NULL),
47 connecting_applications_counter_(0),
48 weak_ptr_factory_(this) {
49 } 18 }
50 19
51 BluetoothDevice::~BluetoothDevice() { 20 BluetoothDevice::~BluetoothDevice() {
52 } 21 }
53 22
54 const std::string& BluetoothDevice::address() const { return address_; } 23 const std::string& BluetoothDevice::address() const {
24 return address_;
25 }
55 26
56 string16 BluetoothDevice::GetName() const { 27 string16 BluetoothDevice::GetName() const {
57 if (!name_.empty()) { 28 if (!name_.empty()) {
58 return UTF8ToUTF16(name_); 29 return UTF8ToUTF16(name_);
59 } else { 30 } else {
60 return GetAddressWithLocalizedDeviceTypeName(); 31 return GetAddressWithLocalizedDeviceTypeName();
61 } 32 }
62 } 33 }
63 34
35 string16 BluetoothDevice::GetAddressWithLocalizedDeviceTypeName() const {
36 string16 address = UTF8ToUTF16(address_);
37 BluetoothDevice::DeviceType device_type = GetDeviceType();
38 switch (device_type) {
39 case DEVICE_COMPUTER:
40 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_COMPUTER,
41 address);
42 case DEVICE_PHONE:
43 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_PHONE,
44 address);
45 case DEVICE_MODEM:
46 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_MODEM,
47 address);
48 case DEVICE_JOYSTICK:
49 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_JOYSTICK,
50 address);
51 case DEVICE_GAMEPAD:
52 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_GAMEPAD,
53 address);
54 case DEVICE_KEYBOARD:
55 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_KEYBOARD,
56 address);
57 case DEVICE_MOUSE:
58 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_MOUSE,
59 address);
60 case DEVICE_TABLET:
61 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_TABLET,
62 address);
63 case DEVICE_KEYBOARD_MOUSE_COMBO:
64 return l10n_util::GetStringFUTF16(
65 IDS_BLUETOOTH_DEVICE_KEYBOARD_MOUSE_COMBO, address);
66 default:
67 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_UNKNOWN, address);
68 }
69 }
70
64 BluetoothDevice::DeviceType BluetoothDevice::GetDeviceType() const { 71 BluetoothDevice::DeviceType BluetoothDevice::GetDeviceType() const {
65 // https://www.bluetooth.org/Technical/AssignedNumbers/baseband.htm 72 // https://www.bluetooth.org/Technical/AssignedNumbers/baseband.htm
66 switch ((bluetooth_class_ & 0x1f00) >> 8) { 73 switch ((bluetooth_class_ & 0x1f00) >> 8) {
67 case 0x01: 74 case 0x01:
68 // Computer major device class. 75 // Computer major device class.
69 return DEVICE_COMPUTER; 76 return DEVICE_COMPUTER;
70 case 0x02: 77 case 0x02:
71 // Phone major device class. 78 // Phone major device class.
72 switch ((bluetooth_class_ & 0xfc) >> 2) { 79 switch ((bluetooth_class_ & 0xfc) >> 2) {
73 case 0x01: 80 case 0x01:
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 case 0x03: 121 case 0x03:
115 // Combo device. 122 // Combo device.
116 return DEVICE_KEYBOARD_MOUSE_COMBO; 123 return DEVICE_KEYBOARD_MOUSE_COMBO;
117 } 124 }
118 break; 125 break;
119 } 126 }
120 127
121 return DEVICE_UNKNOWN; 128 return DEVICE_UNKNOWN;
122 } 129 }
123 130
124 string16 BluetoothDevice::GetAddressWithLocalizedDeviceTypeName() const { 131 bool BluetoothDevice::IsVisible() const {
125 string16 address = UTF8ToUTF16(address_); 132 return visible_;
126 DeviceType device_type = GetDeviceType();
127 switch (device_type) {
128 case DEVICE_COMPUTER:
129 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_COMPUTER,
130 address);
131 case DEVICE_PHONE:
132 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_PHONE,
133 address);
134 case DEVICE_MODEM:
135 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_MODEM,
136 address);
137 case DEVICE_JOYSTICK:
138 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_JOYSTICK,
139 address);
140 case DEVICE_GAMEPAD:
141 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_GAMEPAD,
142 address);
143 case DEVICE_KEYBOARD:
144 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_KEYBOARD,
145 address);
146 case DEVICE_MOUSE:
147 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_MOUSE,
148 address);
149 case DEVICE_TABLET:
150 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_TABLET,
151 address);
152 case DEVICE_KEYBOARD_MOUSE_COMBO:
153 return l10n_util::GetStringFUTF16(
154 IDS_BLUETOOTH_DEVICE_KEYBOARD_MOUSE_COMBO, address);
155 default:
156 return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_UNKNOWN, address);
157 }
158 } 133 }
159 134
160 bool BluetoothDevice::IsSupported() const { 135 bool BluetoothDevice::IsBonded() const {
161 if (CommandLine::ForCurrentProcess()->HasSwitch( 136 return bonded_;
162 switches::kEnableUnsupportedBluetoothDevices))
163 return true;
164
165 DeviceType device_type = GetDeviceType();
166 return (device_type == DEVICE_JOYSTICK ||
167 device_type == DEVICE_GAMEPAD ||
168 device_type == DEVICE_KEYBOARD ||
169 device_type == DEVICE_MOUSE ||
170 device_type == DEVICE_TABLET ||
171 device_type == DEVICE_KEYBOARD_MOUSE_COMBO);
172 } 137 }
173 138
174 bool BluetoothDevice::IsPaired() const { return !object_path_.value().empty(); }
175
176 bool BluetoothDevice::IsBonded() const { return bonded_; }
177
178 bool BluetoothDevice::IsConnected() const { 139 bool BluetoothDevice::IsConnected() const {
179 // TODO(keybuk): examine protocol-specific connected state, such as Input
180 return connected_; 140 return connected_;
181 } 141 }
182 142
183 void BluetoothDevice::GetServiceRecords(const ServiceRecordsCallback& callback,
184 const ErrorCallback& error_callback) {
185 DBusThreadManager::Get()->GetBluetoothDeviceClient()->
186 DiscoverServices(
187 object_path_,
188 "", // empty pattern to browse all services
189 base::Bind(&BluetoothDevice::CollectServiceRecordsCallback,
190 weak_ptr_factory_.GetWeakPtr(),
191 callback,
192 error_callback));
193 }
194
195 bool BluetoothDevice::ProvidesServiceWithUUID(const std::string& uuid) const {
196 const BluetoothDevice::ServiceList& services = GetServices();
197 for (BluetoothDevice::ServiceList::const_iterator iter = services.begin();
198 iter != services.end(); ++iter) {
199 if (bluetooth_utils::CanonicalUuid(*iter) == uuid)
200 return true;
201 }
202 return false;
203 }
204
205 void BluetoothDevice::ProvidesServiceWithName(const std::string& name,
206 const ProvidesServiceCallback& callback) {
207 GetServiceRecords(
208 base::Bind(&BluetoothDevice::SearchServicesForNameCallback,
209 weak_ptr_factory_.GetWeakPtr(),
210 name,
211 callback),
212 base::Bind(&BluetoothDevice::SearchServicesForNameErrorCallback,
213 weak_ptr_factory_.GetWeakPtr(),
214 callback));
215 }
216
217 void BluetoothDevice::Connect(PairingDelegate* pairing_delegate,
218 const base::Closure& callback,
219 const ErrorCallback& error_callback) {
220 if (IsPaired() || IsBonded() || IsConnected()) {
221 // Connection to already paired or connected device.
222 ConnectApplications(callback, error_callback);
223
224 } else if (!pairing_delegate) {
225 // No pairing delegate supplied, initiate low-security connection only.
226 DBusThreadManager::Get()->GetBluetoothAdapterClient()->
227 CreateDevice(adapter_->object_path_,
228 address_,
229 base::Bind(&BluetoothDevice::ConnectCallback,
230 weak_ptr_factory_.GetWeakPtr(),
231 callback,
232 error_callback),
233 base::Bind(&BluetoothDevice::ConnectErrorCallback,
234 weak_ptr_factory_.GetWeakPtr(),
235 error_callback));
236 } else {
237 // Initiate high-security connection with pairing.
238 DCHECK(!pairing_delegate_);
239 pairing_delegate_ = pairing_delegate;
240
241 // The agent path is relatively meaningless, we use the device address
242 // to generate it as we only support one pairing attempt at a time for
243 // a given bluetooth device.
244 DCHECK(agent_.get() == NULL);
245
246 std::string agent_path_basename;
247 ReplaceChars(address_, ":", "_", &agent_path_basename);
248 dbus::ObjectPath agent_path("/org/chromium/bluetooth_agent/" +
249 agent_path_basename);
250
251 dbus::Bus* system_bus = DBusThreadManager::Get()->GetSystemBus();
252 if (system_bus) {
253 agent_.reset(BluetoothAgentServiceProvider::Create(system_bus,
254 agent_path,
255 this));
256 } else {
257 agent_.reset(NULL);
258 }
259
260 DVLOG(1) << "Pairing: " << address_;
261 DBusThreadManager::Get()->GetBluetoothAdapterClient()->
262 CreatePairedDevice(adapter_->object_path_,
263 address_,
264 agent_path,
265 bluetooth_agent::kDisplayYesNoCapability,
266 base::Bind(&BluetoothDevice::ConnectCallback,
267 weak_ptr_factory_.GetWeakPtr(),
268 callback,
269 error_callback),
270 base::Bind(&BluetoothDevice::ConnectErrorCallback,
271 weak_ptr_factory_.GetWeakPtr(),
272 error_callback));
273 }
274 }
275
276 void BluetoothDevice::SetPinCode(const std::string& pincode) {
277 if (!agent_.get() || pincode_callback_.is_null())
278 return;
279
280 pincode_callback_.Run(SUCCESS, pincode);
281 pincode_callback_.Reset();
282 }
283
284 void BluetoothDevice::SetPasskey(uint32 passkey) {
285 if (!agent_.get() || passkey_callback_.is_null())
286 return;
287
288 passkey_callback_.Run(SUCCESS, passkey);
289 passkey_callback_.Reset();
290 }
291
292 void BluetoothDevice::ConfirmPairing() {
293 if (!agent_.get() || confirmation_callback_.is_null())
294 return;
295
296 confirmation_callback_.Run(SUCCESS);
297 confirmation_callback_.Reset();
298 }
299
300 void BluetoothDevice::RejectPairing() {
301 if (!agent_.get())
302 return;
303
304 if (!pincode_callback_.is_null()) {
305 pincode_callback_.Run(REJECTED, "");
306 pincode_callback_.Reset();
307 }
308 if (!passkey_callback_.is_null()) {
309 passkey_callback_.Run(REJECTED, 0);
310 passkey_callback_.Reset();
311 }
312 if (!confirmation_callback_.is_null()) {
313 confirmation_callback_.Run(REJECTED);
314 confirmation_callback_.Reset();
315 }
316 }
317
318 void BluetoothDevice::CancelPairing() {
319 if (!agent_.get())
320 return;
321
322 if (!pincode_callback_.is_null()) {
323 pincode_callback_.Run(CANCELLED, "");
324 pincode_callback_.Reset();
325 }
326 if (!passkey_callback_.is_null()) {
327 passkey_callback_.Run(CANCELLED, 0);
328 passkey_callback_.Reset();
329 }
330 if (!confirmation_callback_.is_null()) {
331 confirmation_callback_.Run(CANCELLED);
332 confirmation_callback_.Reset();
333 }
334 }
335
336 void BluetoothDevice::Disconnect(const base::Closure& callback,
337 const ErrorCallback& error_callback) {
338 DBusThreadManager::Get()->GetBluetoothDeviceClient()->
339 Disconnect(object_path_,
340 base::Bind(&BluetoothDevice::DisconnectCallback,
341 weak_ptr_factory_.GetWeakPtr(),
342 callback,
343 error_callback));
344
345 }
346
347 void BluetoothDevice::Forget(const ErrorCallback& error_callback) {
348 DBusThreadManager::Get()->GetBluetoothAdapterClient()->
349 RemoveDevice(adapter_->object_path_,
350 object_path_,
351 base::Bind(&BluetoothDevice::ForgetCallback,
352 weak_ptr_factory_.GetWeakPtr(),
353 error_callback));
354 }
355
356 void BluetoothDevice::ConnectToService(const std::string& service_uuid,
357 const SocketCallback& callback) {
358 GetServiceRecords(
359 base::Bind(&BluetoothDevice::GetServiceRecordsForConnectCallback,
360 weak_ptr_factory_.GetWeakPtr(),
361 service_uuid,
362 callback),
363 base::Bind(&BluetoothDevice::GetServiceRecordsForConnectErrorCallback,
364 weak_ptr_factory_.GetWeakPtr(),
365 callback));
366 }
367
368 void BluetoothDevice::SetOutOfBandPairingData(
369 const chromeos::BluetoothOutOfBandPairingData& data,
370 const base::Closure& callback,
371 const ErrorCallback& error_callback) {
372 DBusThreadManager::Get()->GetBluetoothOutOfBandClient()->
373 AddRemoteData(
374 object_path_,
375 address(),
376 data,
377 base::Bind(&BluetoothDevice::OnRemoteDataCallback,
378 weak_ptr_factory_.GetWeakPtr(),
379 callback,
380 error_callback));
381 }
382
383 void BluetoothDevice::ClearOutOfBandPairingData(
384 const base::Closure& callback,
385 const ErrorCallback& error_callback) {
386 DBusThreadManager::Get()->GetBluetoothOutOfBandClient()->
387 RemoveRemoteData(
388 object_path_,
389 address(),
390 base::Bind(&BluetoothDevice::OnRemoteDataCallback,
391 weak_ptr_factory_.GetWeakPtr(),
392 callback,
393 error_callback));
394 }
395
396 void BluetoothDevice::SetObjectPath(const dbus::ObjectPath& object_path) {
397 DCHECK(object_path_ == dbus::ObjectPath(""));
398 object_path_ = object_path;
399 }
400
401 void BluetoothDevice::RemoveObjectPath() {
402 DCHECK(object_path_ != dbus::ObjectPath(""));
403 object_path_ = dbus::ObjectPath("");
404 }
405
406 void BluetoothDevice::Update(
407 const BluetoothDeviceClient::Properties* properties,
408 bool update_state) {
409 std::string address = properties->address.value();
410 std::string name = properties->name.value();
411 uint32 bluetooth_class = properties->bluetooth_class.value();
412 const std::vector<std::string>& uuids = properties->uuids.value();
413
414 if (!address.empty())
415 address_ = address;
416 if (!name.empty())
417 name_ = name;
418 if (bluetooth_class)
419 bluetooth_class_ = bluetooth_class;
420 if (!uuids.empty()) {
421 service_uuids_.clear();
422 service_uuids_.assign(uuids.begin(), uuids.end());
423 }
424
425 if (update_state) {
426 // BlueZ uses paired to mean link keys exchanged, whereas the Bluetooth
427 // spec refers to this as bonded. Use the spec name for our interface.
428 bonded_ = properties->paired.value();
429 connected_ = properties->connected.value();
430 }
431 }
432
433 void BluetoothDevice::ConnectCallback(const base::Closure& callback,
434 const ErrorCallback& error_callback,
435 const dbus::ObjectPath& device_path) {
436 DVLOG(1) << "Connection successful: " << device_path.value();
437 if (object_path_.value().empty()) {
438 object_path_ = device_path;
439 } else {
440 LOG_IF(WARNING, object_path_ != device_path)
441 << "Conflicting device paths for objects, result gave: "
442 << device_path.value() << " but signal gave: "
443 << object_path_.value();
444 }
445
446 // Mark the device trusted so it can connect to us automatically, and
447 // we can connect after rebooting. This information is part of the
448 // pairing information of the device, and is unique to the combination
449 // of our bluetooth address and the device's bluetooth address. A
450 // different host needs a new pairing, so it's not useful to sync.
451 DBusThreadManager::Get()->GetBluetoothDeviceClient()->
452 GetProperties(object_path_)->trusted.Set(
453 true,
454 base::Bind(&BluetoothDevice::OnSetTrusted,
455 weak_ptr_factory_.GetWeakPtr(),
456 callback,
457 error_callback));
458
459 // Connect application-layer protocols.
460 ConnectApplications(callback, error_callback);
461 }
462
463 void BluetoothDevice::ConnectErrorCallback(const ErrorCallback& error_callback,
464 const std::string& error_name,
465 const std::string& error_message) {
466 LOG(WARNING) << "Connection failed: " << address_
467 << ": " << error_name << ": " << error_message;
468 error_callback.Run();
469 }
470
471 void BluetoothDevice::CollectServiceRecordsCallback(
472 const ServiceRecordsCallback& callback,
473 const ErrorCallback& error_callback,
474 const dbus::ObjectPath& device_path,
475 const BluetoothDeviceClient::ServiceMap& service_map,
476 bool success) {
477 if (!success) {
478 error_callback.Run();
479 return;
480 }
481
482 ScopedVector<BluetoothServiceRecord> records;
483 for (BluetoothDeviceClient::ServiceMap::const_iterator i =
484 service_map.begin(); i != service_map.end(); ++i) {
485 records.push_back(
486 new BluetoothServiceRecord(address(), i->second));
487 }
488 callback.Run(records);
489 }
490
491 void BluetoothDevice::OnSetTrusted(const base::Closure& callback,
492 const ErrorCallback& error_callback,
493 bool success) {
494 if (success) {
495 callback.Run();
496 } else {
497 LOG(WARNING) << "Failed to set device as trusted: " << address_;
498 error_callback.Run();
499 }
500 }
501
502 void BluetoothDevice::ConnectApplications(const base::Closure& callback,
503 const ErrorCallback& error_callback) {
504 // Introspect the device object to determine supported applications.
505 DBusThreadManager::Get()->GetIntrospectableClient()->
506 Introspect(bluetooth_device::kBluetoothDeviceServiceName,
507 object_path_,
508 base::Bind(&BluetoothDevice::OnIntrospect,
509 weak_ptr_factory_.GetWeakPtr(),
510 callback,
511 error_callback));
512 }
513
514 void BluetoothDevice::OnIntrospect(const base::Closure& callback,
515 const ErrorCallback& error_callback,
516 const std::string& service_name,
517 const dbus::ObjectPath& device_path,
518 const std::string& xml_data,
519 bool success) {
520 if (!success) {
521 LOG(WARNING) << "Failed to determine supported applications: " << address_;
522 error_callback.Run();
523 return;
524 }
525
526 // The introspection data for the device object may list one or more
527 // additional D-Bus interfaces that BlueZ supports for this particular
528 // device. Send appropraite Connect calls for each of those interfaces
529 // to connect all of the application protocols for this device.
530 std::vector<std::string> interfaces =
531 IntrospectableClient::GetInterfacesFromIntrospectResult(xml_data);
532
533 DCHECK_EQ(0, connecting_applications_counter_);
534 connecting_applications_counter_ = 0;
535 for (std::vector<std::string>::iterator iter = interfaces.begin();
536 iter != interfaces.end(); ++iter) {
537 if (*iter == bluetooth_input::kBluetoothInputInterface) {
538 connecting_applications_counter_++;
539 // Supports Input interface.
540 DBusThreadManager::Get()->GetBluetoothInputClient()->
541 Connect(object_path_,
542 base::Bind(&BluetoothDevice::OnConnect,
543 weak_ptr_factory_.GetWeakPtr(),
544 callback,
545 *iter),
546 base::Bind(&BluetoothDevice::OnConnectError,
547 weak_ptr_factory_.GetWeakPtr(),
548 error_callback, *iter));
549 }
550 }
551
552 // If OnConnect has been called for every call to Connect above, then this
553 // will decrement the counter to -1. In that case, call the callback
554 // directly as it has not been called by any of the OnConnect callbacks.
555 // This is safe because OnIntrospect and OnConnect run on the same thread.
556 connecting_applications_counter_--;
557 if (connecting_applications_counter_ == -1)
558 callback.Run();
559 }
560
561 void BluetoothDevice::OnConnect(const base::Closure& callback,
562 const std::string& interface_name,
563 const dbus::ObjectPath& device_path) {
564 DVLOG(1) << "Application connection successful: " << device_path.value()
565 << ": " << interface_name;
566
567 connecting_applications_counter_--;
568 // |callback| should only be called once, meaning it cannot be called before
569 // all requests have been started. The extra decrement after all requests
570 // have been started, and the check for -1 instead of 0 below, insure only a
571 // single call to |callback| will occur (provided OnConnect and OnIntrospect
572 // run on the same thread, which is true).
573 if (connecting_applications_counter_ == -1) {
574 connecting_applications_counter_ = 0;
575 callback.Run();
576 }
577 }
578
579 void BluetoothDevice::OnConnectError(const ErrorCallback& error_callback,
580 const std::string& interface_name,
581 const dbus::ObjectPath& device_path,
582 const std::string& error_name,
583 const std::string& error_message) {
584 LOG(WARNING) << "Connection failed: " << address_ << ": " << interface_name
585 << ": " << error_name << ": " << error_message;
586 error_callback.Run();
587 }
588
589 void BluetoothDevice::DisconnectCallback(const base::Closure& callback,
590 const ErrorCallback& error_callback,
591 const dbus::ObjectPath& device_path,
592 bool success) {
593 DCHECK(device_path == object_path_);
594 if (success) {
595 DVLOG(1) << "Disconnection successful: " << address_;
596 callback.Run();
597 } else {
598 LOG(WARNING) << "Disconnection failed: " << address_;
599 error_callback.Run();
600 }
601 }
602
603 void BluetoothDevice::ForgetCallback(const ErrorCallback& error_callback,
604 const dbus::ObjectPath& adapter_path,
605 bool success) {
606 // It's quite normal that this path never gets called on success; we use a
607 // weak pointer, and bluetoothd might send the DeviceRemoved signal before
608 // the method reply, in which case this object is deleted and the
609 // callback never takes place. Therefore don't do anything here for the
610 // success case.
611 if (!success) {
612 LOG(WARNING) << "Forget failed: " << address_;
613 error_callback.Run();
614 }
615 }
616
617 void BluetoothDevice::SearchServicesForNameErrorCallback(
618 const ProvidesServiceCallback& callback) {
619 callback.Run(false);
620 }
621
622 void BluetoothDevice::SearchServicesForNameCallback(
623 const std::string& name,
624 const ProvidesServiceCallback& callback,
625 const ServiceRecordList& list) {
626 for (ServiceRecordList::const_iterator i = list.begin();
627 i != list.end(); ++i) {
628 if ((*i)->name() == name) {
629 callback.Run(true);
630 return;
631 }
632 }
633 callback.Run(false);
634 }
635
636 void BluetoothDevice::GetServiceRecordsForConnectErrorCallback(
637 const SocketCallback& callback) {
638 callback.Run(NULL);
639 }
640
641 void BluetoothDevice::GetServiceRecordsForConnectCallback(
642 const std::string& service_uuid,
643 const SocketCallback& callback,
644 const ServiceRecordList& list) {
645 for (ServiceRecordList::const_iterator i = list.begin();
646 i != list.end(); ++i) {
647 if ((*i)->uuid() == service_uuid) {
648 // If multiple service records are found, use the first one that works.
649 scoped_refptr<BluetoothSocket> socket(
650 BluetoothSocket::CreateBluetoothSocket(**i));
651 if (socket.get() != NULL) {
652 callback.Run(socket);
653 return;
654 }
655 }
656 }
657 callback.Run(NULL);
658 }
659
660 void BluetoothDevice::OnRemoteDataCallback(const base::Closure& callback,
661 const ErrorCallback& error_callback,
662 bool success) {
663 if (success)
664 callback.Run();
665 else
666 error_callback.Run();
667 }
668
669 void BluetoothDevice::DisconnectRequested(const dbus::ObjectPath& object_path) {
670 DCHECK(object_path == object_path_);
671 }
672
673 void BluetoothDevice::Release() {
674 DCHECK(agent_.get());
675 DVLOG(1) << "Release: " << address_;
676
677 DCHECK(pairing_delegate_);
678 pairing_delegate_->DismissDisplayOrConfirm();
679 pairing_delegate_ = NULL;
680
681 pincode_callback_.Reset();
682 passkey_callback_.Reset();
683 confirmation_callback_.Reset();
684
685 agent_.reset();
686 }
687
688 void BluetoothDevice::RequestPinCode(const dbus::ObjectPath& device_path,
689 const PinCodeCallback& callback) {
690 DCHECK(agent_.get());
691 DVLOG(1) << "RequestPinCode: " << device_path.value();
692
693 DCHECK(pairing_delegate_);
694 DCHECK(pincode_callback_.is_null());
695 pincode_callback_ = callback;
696 pairing_delegate_->RequestPinCode(this);
697 }
698
699 void BluetoothDevice::RequestPasskey(const dbus::ObjectPath& device_path,
700 const PasskeyCallback& callback) {
701 DCHECK(agent_.get());
702 DCHECK(device_path == object_path_);
703 DVLOG(1) << "RequestPasskey: " << device_path.value();
704
705 DCHECK(pairing_delegate_);
706 DCHECK(passkey_callback_.is_null());
707 passkey_callback_ = callback;
708 pairing_delegate_->RequestPasskey(this);
709 }
710
711 void BluetoothDevice::DisplayPinCode(const dbus::ObjectPath& device_path,
712 const std::string& pincode) {
713 DCHECK(agent_.get());
714 DCHECK(device_path == object_path_);
715 DVLOG(1) << "DisplayPinCode: " << device_path.value() << " " << pincode;
716
717 DCHECK(pairing_delegate_);
718 pairing_delegate_->DisplayPinCode(this, pincode);
719 }
720
721 void BluetoothDevice::DisplayPasskey(const dbus::ObjectPath& device_path,
722 uint32 passkey) {
723 DCHECK(agent_.get());
724 DCHECK(device_path == object_path_);
725 DVLOG(1) << "DisplayPasskey: " << device_path.value() << " " << passkey;
726
727 DCHECK(pairing_delegate_);
728 pairing_delegate_->DisplayPasskey(this, passkey);
729 }
730
731 void BluetoothDevice::RequestConfirmation(
732 const dbus::ObjectPath& device_path,
733 uint32 passkey,
734 const ConfirmationCallback& callback) {
735 DCHECK(agent_.get());
736 DCHECK(device_path == object_path_);
737 DVLOG(1) << "RequestConfirmation: " << device_path.value() << " " << passkey;
738
739 DCHECK(pairing_delegate_);
740 DCHECK(confirmation_callback_.is_null());
741 confirmation_callback_ = callback;
742 pairing_delegate_->ConfirmPasskey(this, passkey);
743 }
744
745 void BluetoothDevice::Authorize(const dbus::ObjectPath& device_path,
746 const std::string& uuid,
747 const ConfirmationCallback& callback) {
748 DCHECK(agent_.get());
749 DCHECK(device_path == object_path_);
750 LOG(WARNING) << "Rejected authorization for service: " << uuid
751 << " requested from device: " << device_path.value();
752 callback.Run(REJECTED);
753 }
754
755 void BluetoothDevice::ConfirmModeChange(Mode mode,
756 const ConfirmationCallback& callback) {
757 DCHECK(agent_.get());
758 LOG(WARNING) << "Rejected adapter-level mode change: " << mode
759 << " made on agent for device: " << address_;
760 callback.Run(REJECTED);
761 }
762
763 void BluetoothDevice::Cancel() {
764 DCHECK(agent_.get());
765 DVLOG(1) << "Cancel: " << address_;
766
767 DCHECK(pairing_delegate_);
768 pairing_delegate_->DismissDisplayOrConfirm();
769 }
770
771
772 // static
773 BluetoothDevice* BluetoothDevice::Create(BluetoothAdapter* adapter) {
774 return new BluetoothDevice(adapter);
775 }
776
777 } // namespace chromeos 143 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698