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

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

Issue 148293003: Refactor to support default Bluetooth pairing delegate (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix commit error and add comments Created 6 years, 10 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
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 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 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_chromeos.h" 5 #include "device/bluetooth/bluetooth_adapter_chromeos.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/metrics/histogram.h" 11 #include "base/metrics/histogram.h"
12 #include "base/sys_info.h" 12 #include "base/sys_info.h"
13 #include "chromeos/dbus/bluetooth_adapter_client.h" 13 #include "chromeos/dbus/bluetooth_adapter_client.h"
14 #include "chromeos/dbus/bluetooth_agent_manager_client.h"
15 #include "chromeos/dbus/bluetooth_agent_service_provider.h"
14 #include "chromeos/dbus/bluetooth_device_client.h" 16 #include "chromeos/dbus/bluetooth_device_client.h"
15 #include "chromeos/dbus/bluetooth_input_client.h" 17 #include "chromeos/dbus/bluetooth_input_client.h"
16 #include "chromeos/dbus/dbus_thread_manager.h" 18 #include "chromeos/dbus/dbus_thread_manager.h"
17 #include "device/bluetooth/bluetooth_device.h" 19 #include "device/bluetooth/bluetooth_device.h"
18 #include "device/bluetooth/bluetooth_device_chromeos.h" 20 #include "device/bluetooth/bluetooth_device_chromeos.h"
21 #include "third_party/cros_system_api/dbus/service_constants.h"
19 22
20 using device::BluetoothAdapter; 23 using device::BluetoothAdapter;
21 using device::BluetoothDevice; 24 using device::BluetoothDevice;
22 25
26 namespace {
27
28 // The agent path is relatively meaningless since BlueZ only supports one
29 // at time and will fail in an attempt to register another with "Already Exists"
30 const char kAgentPath[] = "/org/chromium/bluetooth_agent";
31
32 // Histogram enumerations for pairing methods.
33 enum UMAPairingMethod {
34 UMA_PAIRING_METHOD_NONE,
35 UMA_PAIRING_METHOD_REQUEST_PINCODE,
36 UMA_PAIRING_METHOD_REQUEST_PASSKEY,
37 UMA_PAIRING_METHOD_DISPLAY_PINCODE,
38 UMA_PAIRING_METHOD_DISPLAY_PASSKEY,
39 UMA_PAIRING_METHOD_CONFIRM_PASSKEY,
40 // NOTE: Add new pairing methods immediately above this line. Make sure to
41 // update the enum list in tools/histogram/histograms.xml accordinly.
42 UMA_PAIRING_METHOD_COUNT
43 };
44
45 void OnUnregisterAgentError(const std::string& error_name,
46 const std::string& error_message) {
47 LOG(WARNING) << "Failed to unregister pairing agent: "
48 << error_name << ": " << error_message;
49 }
50
51 } // namespace
52
23 namespace chromeos { 53 namespace chromeos {
24 54
25 BluetoothAdapterChromeOS::BluetoothAdapterChromeOS() 55 BluetoothAdapterChromeOS::BluetoothAdapterChromeOS()
26 : weak_ptr_factory_(this) { 56 : weak_ptr_factory_(this) {
27 DBusThreadManager::Get()->GetBluetoothAdapterClient()->AddObserver(this); 57 DBusThreadManager::Get()->GetBluetoothAdapterClient()->AddObserver(this);
28 DBusThreadManager::Get()->GetBluetoothDeviceClient()->AddObserver(this); 58 DBusThreadManager::Get()->GetBluetoothDeviceClient()->AddObserver(this);
29 DBusThreadManager::Get()->GetBluetoothInputClient()->AddObserver(this); 59 DBusThreadManager::Get()->GetBluetoothInputClient()->AddObserver(this);
30 60
31 std::vector<dbus::ObjectPath> object_paths = 61 std::vector<dbus::ObjectPath> object_paths =
32 DBusThreadManager::Get()->GetBluetoothAdapterClient()->GetAdapters(); 62 DBusThreadManager::Get()->GetBluetoothAdapterClient()->GetAdapters();
33 63
34 if (!object_paths.empty()) { 64 if (!object_paths.empty()) {
35 VLOG(1) << object_paths.size() << " Bluetooth adapter(s) available."; 65 VLOG(1) << object_paths.size() << " Bluetooth adapter(s) available.";
36 SetAdapter(object_paths[0]); 66 SetAdapter(object_paths[0]);
37 } 67 }
68
69 // The agent path is relatively meaningless since BlueZ only supports
70 // one per application at a time.
71 dbus::Bus* system_bus = DBusThreadManager::Get()->GetSystemBus();
72 agent_.reset(BluetoothAgentServiceProvider::Create(
73 system_bus, dbus::ObjectPath(kAgentPath), this));
74 DCHECK(agent_.get());
75
76 VLOG(1) << "Registering pairing agent";
77 DBusThreadManager::Get()->GetBluetoothAgentManagerClient()->
78 RegisterAgent(
79 dbus::ObjectPath(kAgentPath),
80 bluetooth_agent_manager::kKeyboardDisplayCapability,
81 base::Bind(&BluetoothAdapterChromeOS::OnRegisterAgent,
82 weak_ptr_factory_.GetWeakPtr()),
83 base::Bind(&BluetoothAdapterChromeOS::OnRegisterAgentError,
84 weak_ptr_factory_.GetWeakPtr()));
38 } 85 }
39 86
40 BluetoothAdapterChromeOS::~BluetoothAdapterChromeOS() { 87 BluetoothAdapterChromeOS::~BluetoothAdapterChromeOS() {
41 DBusThreadManager::Get()->GetBluetoothAdapterClient()->RemoveObserver(this); 88 DBusThreadManager::Get()->GetBluetoothAdapterClient()->RemoveObserver(this);
42 DBusThreadManager::Get()->GetBluetoothDeviceClient()->RemoveObserver(this); 89 DBusThreadManager::Get()->GetBluetoothDeviceClient()->RemoveObserver(this);
43 DBusThreadManager::Get()->GetBluetoothInputClient()->RemoveObserver(this); 90 DBusThreadManager::Get()->GetBluetoothInputClient()->RemoveObserver(this);
91
92 // Clean up after ourselves. Ignore failures since the class is going away.
93 VLOG(1) << "Unregistering pairing agent";
94 DBusThreadManager::Get()->GetBluetoothAgentManagerClient()->
95 UnregisterAgent(
96 dbus::ObjectPath(kAgentPath),
97 base::Bind(&base::DoNothing),
98 base::Bind(&OnUnregisterAgentError));
44 } 99 }
45 100
46 void BluetoothAdapterChromeOS::AddObserver( 101 void BluetoothAdapterChromeOS::AddObserver(
47 BluetoothAdapter::Observer* observer) { 102 BluetoothAdapter::Observer* observer) {
48 DCHECK(observer); 103 DCHECK(observer);
49 observers_.AddObserver(observer); 104 observers_.AddObserver(observer);
50 } 105 }
51 106
52 void BluetoothAdapterChromeOS::RemoveObserver( 107 void BluetoothAdapterChromeOS::RemoveObserver(
53 BluetoothAdapter::Observer* observer) { 108 BluetoothAdapter::Observer* observer) {
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
270 GetProperties(object_path); 325 GetProperties(object_path);
271 326
272 // Properties structure can be removed, which triggers a change in the 327 // Properties structure can be removed, which triggers a change in the
273 // BluetoothDevice::IsConnectable() property, as does a change in the 328 // BluetoothDevice::IsConnectable() property, as does a change in the
274 // actual reconnect_mode property. 329 // actual reconnect_mode property.
275 if (!properties || 330 if (!properties ||
276 property_name == properties->reconnect_mode.name()) 331 property_name == properties->reconnect_mode.name())
277 NotifyDeviceChanged(device_chromeos); 332 NotifyDeviceChanged(device_chromeos);
278 } 333 }
279 334
335 void BluetoothAdapterChromeOS::Release() {
336 DCHECK(agent_.get());
337 VLOG(1) << "Release";
338
339 // Called after we unregister the pairing agent, e.g. when changing I/O
340 // capabilities. Nothing much to be done right now.
341 }
342
343 void BluetoothAdapterChromeOS::RequestPinCode(
344 const dbus::ObjectPath& device_path,
345 const PinCodeCallback& callback) {
346 DCHECK(agent_.get());
347 VLOG(1) << device_path.value() << ": RequestPinCode";
348
349 BluetoothDeviceChromeOS* device_chromeos;
350 PairingContext* pairing_context;
351 if (!GetDeviceAndPairingContext(device_path,
352 &device_chromeos, &pairing_context))
353 return;
354
355 UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingMethod",
356 UMA_PAIRING_METHOD_REQUEST_PINCODE,
357 UMA_PAIRING_METHOD_COUNT);
358
359 DCHECK(pairing_context->pincode_callback_.is_null());
360 pairing_context->pincode_callback_ = callback;
361 pairing_context->pairing_delegate_->RequestPinCode(device_chromeos);
362 pairing_context->pairing_delegate_used_ = true;
363 }
364
365 void BluetoothAdapterChromeOS::DisplayPinCode(
366 const dbus::ObjectPath& device_path,
367 const std::string& pincode) {
368 DCHECK(agent_.get());
369 VLOG(1) << device_path.value() << ": DisplayPinCode: " << pincode;
370
371 BluetoothDeviceChromeOS* device_chromeos;
372 PairingContext* pairing_context;
373 if (!GetDeviceAndPairingContext(device_path,
374 &device_chromeos, &pairing_context))
375 return;
376
377 UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingMethod",
378 UMA_PAIRING_METHOD_DISPLAY_PINCODE,
379 UMA_PAIRING_METHOD_COUNT);
380
381 pairing_context->pairing_delegate_->DisplayPinCode(device_chromeos, pincode);
382 pairing_context->pairing_delegate_used_ = true;
383 }
384
385 void BluetoothAdapterChromeOS::RequestPasskey(
386 const dbus::ObjectPath& device_path,
387 const PasskeyCallback& callback) {
388 DCHECK(agent_.get());
389 VLOG(1) << device_path.value() << ": RequestPasskey";
390
391 BluetoothDeviceChromeOS* device_chromeos;
392 PairingContext* pairing_context;
393 if (!GetDeviceAndPairingContext(device_path,
394 &device_chromeos, &pairing_context))
395 return;
396
397 UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingMethod",
398 UMA_PAIRING_METHOD_REQUEST_PASSKEY,
399 UMA_PAIRING_METHOD_COUNT);
400
401 DCHECK(pairing_context->passkey_callback_.is_null());
402 pairing_context->passkey_callback_ = callback;
403 pairing_context->pairing_delegate_->RequestPasskey(device_chromeos);
404 pairing_context->pairing_delegate_used_ = true;
405 }
406
407 void BluetoothAdapterChromeOS::DisplayPasskey(
408 const dbus::ObjectPath& device_path,
409 uint32 passkey,
410 uint16 entered) {
411 DCHECK(agent_.get());
412 VLOG(1) << device_path.value() << ": DisplayPasskey: " << passkey
413 << " (" << entered << " entered)";
414
415 BluetoothDeviceChromeOS* device_chromeos;
416 PairingContext* pairing_context;
417 if (!GetDeviceAndPairingContext(device_path,
418 &device_chromeos, &pairing_context))
419 return;
420
421 if (entered == 0)
422 UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingMethod",
423 UMA_PAIRING_METHOD_DISPLAY_PASSKEY,
424 UMA_PAIRING_METHOD_COUNT);
425
426 if (entered == 0)
427 pairing_context->pairing_delegate_->DisplayPasskey(device_chromeos,
428 passkey);
429
430 pairing_context->pairing_delegate_->KeysEntered(device_chromeos, entered);
431 pairing_context->pairing_delegate_used_ = true;
432 }
433
434 void BluetoothAdapterChromeOS::RequestConfirmation(
435 const dbus::ObjectPath& device_path,
436 uint32 passkey,
437 const ConfirmationCallback& callback) {
438 DCHECK(agent_.get());
439 VLOG(1) << device_path.value() << ": RequestConfirmation: " << passkey;
440
441 BluetoothDeviceChromeOS* device_chromeos;
442 PairingContext* pairing_context;
443 if (!GetDeviceAndPairingContext(device_path,
444 &device_chromeos, &pairing_context))
445 return;
446
447 UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingMethod",
448 UMA_PAIRING_METHOD_CONFIRM_PASSKEY,
449 UMA_PAIRING_METHOD_COUNT);
450
451 DCHECK(pairing_context->confirmation_callback_.is_null());
452 pairing_context->confirmation_callback_ = callback;
453 pairing_context->pairing_delegate_->ConfirmPasskey(device_chromeos, passkey);
454 pairing_context->pairing_delegate_used_ = true;
455 }
456
457 void BluetoothAdapterChromeOS::RequestAuthorization(
458 const dbus::ObjectPath& device_path,
459 const ConfirmationCallback& callback) {
460 DCHECK(agent_.get());
461 VLOG(1) << device_path.value() << ": RequestAuthorization";
462
463 // TODO(keybuk): implement
464 callback.Run(CANCELLED);
465 }
466
467 void BluetoothAdapterChromeOS::AuthorizeService(
468 const dbus::ObjectPath& device_path,
469 const std::string& uuid,
470 const ConfirmationCallback& callback) {
471 DCHECK(agent_.get());
472 VLOG(1) << device_path.value() << ": AuthorizeService: " << uuid;
473
474 // TODO(keybuk): implement
475 callback.Run(CANCELLED);
476 }
477
478 void BluetoothAdapterChromeOS::Cancel() {
479 DCHECK(agent_.get());
480 VLOG(1) << "Cancel";
481 }
482
483 bool BluetoothAdapterChromeOS::PairingContext::ExpectingPinCode() const {
484 return !pincode_callback_.is_null();
485 }
486
487 bool BluetoothAdapterChromeOS::PairingContext::ExpectingPasskey() const {
488 return !passkey_callback_.is_null();
489 }
490
491 bool BluetoothAdapterChromeOS::PairingContext::ExpectingConfirmation() const {
492 return !confirmation_callback_.is_null();
493 }
494
495 void BluetoothAdapterChromeOS::PairingContext::SetPinCode(
496 const std::string& pincode) {
497 if (pincode_callback_.is_null())
498 return;
499
500 pincode_callback_.Run(SUCCESS, pincode);
501 pincode_callback_.Reset();
502 }
503
504 void BluetoothAdapterChromeOS::PairingContext::SetPasskey(uint32 passkey) {
505 if (passkey_callback_.is_null())
506 return;
507
508 passkey_callback_.Run(SUCCESS, passkey);
509 passkey_callback_.Reset();
510 }
511
512 void BluetoothAdapterChromeOS::PairingContext::ConfirmPairing() {
513 if (confirmation_callback_.is_null())
514 return;
515
516 confirmation_callback_.Run(SUCCESS);
517 confirmation_callback_.Reset();
518 }
519
520 bool BluetoothAdapterChromeOS::PairingContext::RejectPairing() {
521 return RunPairingCallbacks(REJECTED);
522 }
523
524 bool BluetoothAdapterChromeOS::PairingContext::CancelPairing() {
525 return RunPairingCallbacks(CANCELLED);
526 }
527
528 BluetoothAdapterChromeOS::PairingContext::PairingContext(
529 BluetoothDevice::PairingDelegate* pairing_delegate)
530 : pairing_delegate_(pairing_delegate),
531 pairing_delegate_used_(false) {
532 VLOG(1) << "Created PairingContext";
533 }
534
535 BluetoothAdapterChromeOS::PairingContext::~PairingContext() {
536 VLOG(1) << "Destroying PairingContext";
537
538 if (!pairing_delegate_used_)
539 UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingMethod",
540 UMA_PAIRING_METHOD_NONE,
541 UMA_PAIRING_METHOD_COUNT);
542
543 DCHECK(pincode_callback_.is_null());
544 DCHECK(passkey_callback_.is_null());
545 DCHECK(confirmation_callback_.is_null());
546
547 if (pairing_delegate_used_)
548 pairing_delegate_->DismissDisplayOrConfirm();
549 pairing_delegate_ = NULL;
550 }
551
552 bool BluetoothAdapterChromeOS::PairingContext::RunPairingCallbacks(
553 BluetoothAgentServiceProvider::Delegate::Status status) {
554 pairing_delegate_used_ = true;
555
556 bool callback_run = false;
557 if (!pincode_callback_.is_null()) {
558 pincode_callback_.Run(status, "");
559 pincode_callback_.Reset();
560 callback_run = true;
561 }
562
563 if (!passkey_callback_.is_null()) {
564 passkey_callback_.Run(status, 0);
565 passkey_callback_.Reset();
566 callback_run = true;
567 }
568
569 if (!confirmation_callback_.is_null()) {
570 confirmation_callback_.Run(status);
571 confirmation_callback_.Reset();
572 callback_run = true;
573 }
574
575 return callback_run;
576 }
577
578 bool BluetoothAdapterChromeOS::GetDeviceAndPairingContext(
579 const dbus::ObjectPath& object_path,
580 BluetoothDeviceChromeOS** device_chromeos,
581 PairingContext** pairing_context)
582 {
583 *device_chromeos = GetDeviceWithPath(object_path);
584 if (!device_chromeos) {
585 LOG(WARNING) << "Pairing Agent request for unknown device: "
586 << object_path.value();
587 return false;
588 }
589
590 *pairing_context = (*device_chromeos)->pairing_context_.get();
591 if (*pairing_context)
592 return true;
593
594 // TODO(keybuk): this is the point we need a default pairing delegate, create
595 // a PairingContext with that passed in, set it as the context on the device
596 // and return true.
597 return false;
598 }
599
600 void BluetoothAdapterChromeOS::OnRegisterAgent() {
601 VLOG(1) << "Pairing agent registered";
602 }
603
604 void BluetoothAdapterChromeOS::OnRegisterAgentError(
605 const std::string& error_name,
606 const std::string& error_message) {
607 LOG(WARNING) << ": Failed to register pairing agent: "
608 << error_name << ": " << error_message;
609
610 agent_.reset();
611 }
612
280 BluetoothDeviceChromeOS* 613 BluetoothDeviceChromeOS*
281 BluetoothAdapterChromeOS::GetDeviceWithPath( 614 BluetoothAdapterChromeOS::GetDeviceWithPath(
282 const dbus::ObjectPath& object_path) { 615 const dbus::ObjectPath& object_path) {
283 for (DevicesMap::iterator iter = devices_.begin(); 616 for (DevicesMap::iterator iter = devices_.begin();
284 iter != devices_.end(); ++iter) { 617 iter != devices_.end(); ++iter) {
285 BluetoothDeviceChromeOS* device_chromeos = 618 BluetoothDeviceChromeOS* device_chromeos =
286 static_cast<BluetoothDeviceChromeOS*>(iter->second); 619 static_cast<BluetoothDeviceChromeOS*>(iter->second);
287 if (device_chromeos->object_path() == object_path) 620 if (device_chromeos->object_path() == object_path)
288 return device_chromeos; 621 return device_chromeos;
289 } 622 }
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
432 void BluetoothAdapterChromeOS::OnStopDiscoveryError( 765 void BluetoothAdapterChromeOS::OnStopDiscoveryError(
433 const ErrorCallback& error_callback, 766 const ErrorCallback& error_callback,
434 const std::string& error_name, 767 const std::string& error_name,
435 const std::string& error_message) { 768 const std::string& error_message) {
436 LOG(WARNING) << object_path_.value() << ": Failed to stop discovery: " 769 LOG(WARNING) << object_path_.value() << ": Failed to stop discovery: "
437 << error_name << ": " << error_message; 770 << error_name << ": " << error_message;
438 error_callback.Run(); 771 error_callback.Run();
439 } 772 }
440 773
441 } // namespace chromeos 774 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698