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

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: wat 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 permits one to
29 // exist per D-Bus connection, it just has to be unique within Chromium.
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 accordingly.
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 // Register the pairing agent.
70 dbus::Bus* system_bus = DBusThreadManager::Get()->GetSystemBus();
71 agent_.reset(BluetoothAgentServiceProvider::Create(
72 system_bus, dbus::ObjectPath(kAgentPath), this));
73 DCHECK(agent_.get());
74
75 VLOG(1) << "Registering pairing agent";
76 DBusThreadManager::Get()->GetBluetoothAgentManagerClient()->
77 RegisterAgent(
78 dbus::ObjectPath(kAgentPath),
79 bluetooth_agent_manager::kKeyboardDisplayCapability,
80 base::Bind(&BluetoothAdapterChromeOS::OnRegisterAgent,
81 weak_ptr_factory_.GetWeakPtr()),
82 base::Bind(&BluetoothAdapterChromeOS::OnRegisterAgentError,
83 weak_ptr_factory_.GetWeakPtr()));
38 } 84 }
39 85
40 BluetoothAdapterChromeOS::~BluetoothAdapterChromeOS() { 86 BluetoothAdapterChromeOS::~BluetoothAdapterChromeOS() {
41 DBusThreadManager::Get()->GetBluetoothAdapterClient()->RemoveObserver(this); 87 DBusThreadManager::Get()->GetBluetoothAdapterClient()->RemoveObserver(this);
42 DBusThreadManager::Get()->GetBluetoothDeviceClient()->RemoveObserver(this); 88 DBusThreadManager::Get()->GetBluetoothDeviceClient()->RemoveObserver(this);
43 DBusThreadManager::Get()->GetBluetoothInputClient()->RemoveObserver(this); 89 DBusThreadManager::Get()->GetBluetoothInputClient()->RemoveObserver(this);
90
91 VLOG(1) << "Unregistering pairing agent";
92 DBusThreadManager::Get()->GetBluetoothAgentManagerClient()->
93 UnregisterAgent(
94 dbus::ObjectPath(kAgentPath),
95 base::Bind(&base::DoNothing),
96 base::Bind(&OnUnregisterAgentError));
44 } 97 }
45 98
46 void BluetoothAdapterChromeOS::AddObserver( 99 void BluetoothAdapterChromeOS::AddObserver(
47 BluetoothAdapter::Observer* observer) { 100 BluetoothAdapter::Observer* observer) {
48 DCHECK(observer); 101 DCHECK(observer);
49 observers_.AddObserver(observer); 102 observers_.AddObserver(observer);
50 } 103 }
51 104
52 void BluetoothAdapterChromeOS::RemoveObserver( 105 void BluetoothAdapterChromeOS::RemoveObserver(
53 BluetoothAdapter::Observer* observer) { 106 BluetoothAdapter::Observer* observer) {
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
308 GetProperties(object_path); 361 GetProperties(object_path);
309 362
310 // Properties structure can be removed, which triggers a change in the 363 // Properties structure can be removed, which triggers a change in the
311 // BluetoothDevice::IsConnectable() property, as does a change in the 364 // BluetoothDevice::IsConnectable() property, as does a change in the
312 // actual reconnect_mode property. 365 // actual reconnect_mode property.
313 if (!properties || 366 if (!properties ||
314 property_name == properties->reconnect_mode.name()) 367 property_name == properties->reconnect_mode.name())
315 NotifyDeviceChanged(device_chromeos); 368 NotifyDeviceChanged(device_chromeos);
316 } 369 }
317 370
371 void BluetoothAdapterChromeOS::Release() {
372 DCHECK(agent_.get());
373 VLOG(1) << "Release";
374
375 // Called after we unregister the pairing agent, e.g. when changing I/O
376 // capabilities. Nothing much to be done right now.
377 }
378
379 void BluetoothAdapterChromeOS::RequestPinCode(
380 const dbus::ObjectPath& device_path,
381 const PinCodeCallback& callback) {
382 DCHECK(agent_.get());
383 VLOG(1) << device_path.value() << ": RequestPinCode";
384
385 BluetoothDeviceChromeOS* device_chromeos;
386 PairingContext* pairing_context;
387 if (!GetDeviceAndPairingContext(device_path,
388 &device_chromeos, &pairing_context)) {
389 callback.Run(REJECTED, "");
390 return;
391 }
392
393 UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingMethod",
394 UMA_PAIRING_METHOD_REQUEST_PINCODE,
395 UMA_PAIRING_METHOD_COUNT);
396
397 DCHECK(pairing_context->pincode_callback_.is_null());
398 pairing_context->pincode_callback_ = callback;
399 pairing_context->pairing_delegate_->RequestPinCode(device_chromeos);
400 pairing_context->pairing_delegate_used_ = true;
401 }
402
403 void BluetoothAdapterChromeOS::DisplayPinCode(
404 const dbus::ObjectPath& device_path,
405 const std::string& pincode) {
406 DCHECK(agent_.get());
407 VLOG(1) << device_path.value() << ": DisplayPinCode: " << pincode;
408
409 BluetoothDeviceChromeOS* device_chromeos;
410 PairingContext* pairing_context;
411 if (!GetDeviceAndPairingContext(device_path,
412 &device_chromeos, &pairing_context))
413 return;
414
415 UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingMethod",
416 UMA_PAIRING_METHOD_DISPLAY_PINCODE,
417 UMA_PAIRING_METHOD_COUNT);
418
419 pairing_context->pairing_delegate_->DisplayPinCode(device_chromeos, pincode);
420 pairing_context->pairing_delegate_used_ = true;
421 }
422
423 void BluetoothAdapterChromeOS::RequestPasskey(
424 const dbus::ObjectPath& device_path,
425 const PasskeyCallback& callback) {
426 DCHECK(agent_.get());
427 VLOG(1) << device_path.value() << ": RequestPasskey";
428
429 BluetoothDeviceChromeOS* device_chromeos;
430 PairingContext* pairing_context;
431 if (!GetDeviceAndPairingContext(device_path,
432 &device_chromeos, &pairing_context)) {
433 callback.Run(REJECTED, 0);
434 return;
435 }
436
437 UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingMethod",
438 UMA_PAIRING_METHOD_REQUEST_PASSKEY,
439 UMA_PAIRING_METHOD_COUNT);
440
441 DCHECK(pairing_context->passkey_callback_.is_null());
442 pairing_context->passkey_callback_ = callback;
443 pairing_context->pairing_delegate_->RequestPasskey(device_chromeos);
444 pairing_context->pairing_delegate_used_ = true;
445 }
446
447 void BluetoothAdapterChromeOS::DisplayPasskey(
448 const dbus::ObjectPath& device_path,
449 uint32 passkey,
450 uint16 entered) {
451 DCHECK(agent_.get());
452 VLOG(1) << device_path.value() << ": DisplayPasskey: " << passkey
453 << " (" << entered << " entered)";
454
455 BluetoothDeviceChromeOS* device_chromeos;
456 PairingContext* pairing_context;
457 if (!GetDeviceAndPairingContext(device_path,
458 &device_chromeos, &pairing_context))
459 return;
460
461 if (entered == 0)
462 UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingMethod",
463 UMA_PAIRING_METHOD_DISPLAY_PASSKEY,
464 UMA_PAIRING_METHOD_COUNT);
465
466 if (entered == 0)
467 pairing_context->pairing_delegate_->DisplayPasskey(device_chromeos,
468 passkey);
469
470 pairing_context->pairing_delegate_->KeysEntered(device_chromeos, entered);
471 pairing_context->pairing_delegate_used_ = true;
472 }
473
474 void BluetoothAdapterChromeOS::RequestConfirmation(
475 const dbus::ObjectPath& device_path,
476 uint32 passkey,
477 const ConfirmationCallback& callback) {
478 DCHECK(agent_.get());
479 VLOG(1) << device_path.value() << ": RequestConfirmation: " << passkey;
480
481 BluetoothDeviceChromeOS* device_chromeos;
482 PairingContext* pairing_context;
483 if (!GetDeviceAndPairingContext(device_path,
484 &device_chromeos, &pairing_context)) {
485 callback.Run(REJECTED);
486 return;
487 }
488
489 UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingMethod",
490 UMA_PAIRING_METHOD_CONFIRM_PASSKEY,
491 UMA_PAIRING_METHOD_COUNT);
492
493 DCHECK(pairing_context->confirmation_callback_.is_null());
494 pairing_context->confirmation_callback_ = callback;
495 pairing_context->pairing_delegate_->ConfirmPasskey(device_chromeos, passkey);
496 pairing_context->pairing_delegate_used_ = true;
497 }
498
499 void BluetoothAdapterChromeOS::RequestAuthorization(
500 const dbus::ObjectPath& device_path,
501 const ConfirmationCallback& callback) {
502 DCHECK(agent_.get());
503 VLOG(1) << device_path.value() << ": RequestAuthorization";
504
505 // TODO(keybuk): implement
506 callback.Run(CANCELLED);
507 }
508
509 void BluetoothAdapterChromeOS::AuthorizeService(
510 const dbus::ObjectPath& device_path,
511 const std::string& uuid,
512 const ConfirmationCallback& callback) {
513 DCHECK(agent_.get());
514 VLOG(1) << device_path.value() << ": AuthorizeService: " << uuid;
515
516 // TODO(keybuk): implement
517 callback.Run(CANCELLED);
518 }
519
520 void BluetoothAdapterChromeOS::Cancel() {
521 DCHECK(agent_.get());
522 VLOG(1) << "Cancel";
523 }
524
525 bool BluetoothAdapterChromeOS::PairingContext::ExpectingPinCode() const {
526 return !pincode_callback_.is_null();
527 }
528
529 bool BluetoothAdapterChromeOS::PairingContext::ExpectingPasskey() const {
530 return !passkey_callback_.is_null();
531 }
532
533 bool BluetoothAdapterChromeOS::PairingContext::ExpectingConfirmation() const {
534 return !confirmation_callback_.is_null();
535 }
536
537 void BluetoothAdapterChromeOS::PairingContext::SetPinCode(
538 const std::string& pincode) {
539 if (pincode_callback_.is_null())
540 return;
541
542 pincode_callback_.Run(SUCCESS, pincode);
543 pincode_callback_.Reset();
544 }
545
546 void BluetoothAdapterChromeOS::PairingContext::SetPasskey(uint32 passkey) {
547 if (passkey_callback_.is_null())
548 return;
549
550 passkey_callback_.Run(SUCCESS, passkey);
551 passkey_callback_.Reset();
552 }
553
554 void BluetoothAdapterChromeOS::PairingContext::ConfirmPairing() {
555 if (confirmation_callback_.is_null())
556 return;
557
558 confirmation_callback_.Run(SUCCESS);
559 confirmation_callback_.Reset();
560 }
561
562 bool BluetoothAdapterChromeOS::PairingContext::RejectPairing() {
563 return RunPairingCallbacks(REJECTED);
564 }
565
566 bool BluetoothAdapterChromeOS::PairingContext::CancelPairing() {
567 return RunPairingCallbacks(CANCELLED);
568 }
569
570 BluetoothAdapterChromeOS::PairingContext::PairingContext(
571 BluetoothDevice::PairingDelegate* pairing_delegate)
572 : pairing_delegate_(pairing_delegate),
573 pairing_delegate_used_(false) {
574 VLOG(1) << "Created PairingContext";
575 }
576
577 BluetoothAdapterChromeOS::PairingContext::~PairingContext() {
578 VLOG(1) << "Destroying PairingContext";
579
580 if (!pairing_delegate_used_)
581 UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingMethod",
582 UMA_PAIRING_METHOD_NONE,
583 UMA_PAIRING_METHOD_COUNT);
584
585 DCHECK(pincode_callback_.is_null());
586 DCHECK(passkey_callback_.is_null());
587 DCHECK(confirmation_callback_.is_null());
588
589 pairing_delegate_->DismissDisplayOrConfirm();
590 pairing_delegate_ = NULL;
591 }
592
593 bool BluetoothAdapterChromeOS::PairingContext::RunPairingCallbacks(
594 BluetoothAgentServiceProvider::Delegate::Status status) {
595 pairing_delegate_used_ = true;
596
597 bool callback_run = false;
598 if (!pincode_callback_.is_null()) {
599 pincode_callback_.Run(status, "");
600 pincode_callback_.Reset();
601 callback_run = true;
602 }
603
604 if (!passkey_callback_.is_null()) {
605 passkey_callback_.Run(status, 0);
606 passkey_callback_.Reset();
607 callback_run = true;
608 }
609
610 if (!confirmation_callback_.is_null()) {
611 confirmation_callback_.Run(status);
612 confirmation_callback_.Reset();
613 callback_run = true;
614 }
615
616 return callback_run;
617 }
618
619 void BluetoothAdapterChromeOS::OnRegisterAgent() {
620 VLOG(1) << "Pairing agent registered";
621 }
622
623 void BluetoothAdapterChromeOS::OnRegisterAgentError(
624 const std::string& error_name,
625 const std::string& error_message) {
626 LOG(WARNING) << ": Failed to register pairing agent: "
627 << error_name << ": " << error_message;
628
629 agent_.reset();
630 }
631
318 BluetoothDeviceChromeOS* 632 BluetoothDeviceChromeOS*
319 BluetoothAdapterChromeOS::GetDeviceWithPath( 633 BluetoothAdapterChromeOS::GetDeviceWithPath(
320 const dbus::ObjectPath& object_path) { 634 const dbus::ObjectPath& object_path) {
321 for (DevicesMap::iterator iter = devices_.begin(); 635 for (DevicesMap::iterator iter = devices_.begin();
322 iter != devices_.end(); ++iter) { 636 iter != devices_.end(); ++iter) {
323 BluetoothDeviceChromeOS* device_chromeos = 637 BluetoothDeviceChromeOS* device_chromeos =
324 static_cast<BluetoothDeviceChromeOS*>(iter->second); 638 static_cast<BluetoothDeviceChromeOS*>(iter->second);
325 if (device_chromeos->object_path() == object_path) 639 if (device_chromeos->object_path() == object_path)
326 return device_chromeos; 640 return device_chromeos;
327 } 641 }
328 642
329 return NULL; 643 return NULL;
330 } 644 }
331 645
646 bool BluetoothAdapterChromeOS::GetDeviceAndPairingContext(
647 const dbus::ObjectPath& object_path,
648 BluetoothDeviceChromeOS** device_chromeos,
649 PairingContext** pairing_context)
650 {
651 *device_chromeos = GetDeviceWithPath(object_path);
652 if (!device_chromeos) {
653 LOG(WARNING) << "Pairing Agent request for unknown device: "
654 << object_path.value();
655 return false;
656 }
657
658 *pairing_context = (*device_chromeos)->pairing_context_.get();
659 if (*pairing_context)
660 return true;
661
662 // TODO(keybuk): this is the point we need a default pairing delegate, create
663 // a PairingContext with that passed in, set it as the context on the device
664 // and return true.
665 return false;
666 }
667
332 void BluetoothAdapterChromeOS::SetAdapter(const dbus::ObjectPath& object_path) { 668 void BluetoothAdapterChromeOS::SetAdapter(const dbus::ObjectPath& object_path) {
333 DCHECK(!IsPresent()); 669 DCHECK(!IsPresent());
334 object_path_ = object_path; 670 object_path_ = object_path;
335 671
336 VLOG(1) << object_path_.value() << ": using adapter."; 672 VLOG(1) << object_path_.value() << ": using adapter.";
337 673
338 SetDefaultAdapterName(); 674 SetDefaultAdapterName();
339 675
340 BluetoothAdapterClient::Properties* properties = 676 BluetoothAdapterClient::Properties* properties =
341 DBusThreadManager::Get()->GetBluetoothAdapterClient()-> 677 DBusThreadManager::Get()->GetBluetoothAdapterClient()->
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
486 void BluetoothAdapterChromeOS::OnStopDiscoveryError( 822 void BluetoothAdapterChromeOS::OnStopDiscoveryError(
487 const ErrorCallback& error_callback, 823 const ErrorCallback& error_callback,
488 const std::string& error_name, 824 const std::string& error_name,
489 const std::string& error_message) { 825 const std::string& error_message) {
490 LOG(WARNING) << object_path_.value() << ": Failed to stop discovery: " 826 LOG(WARNING) << object_path_.value() << ": Failed to stop discovery: "
491 << error_name << ": " << error_message; 827 << error_name << ": " << error_message;
492 error_callback.Run(); 828 error_callback.Run();
493 } 829 }
494 830
495 } // namespace chromeos 831 } // namespace chromeos
OLDNEW
« no previous file with comments | « device/bluetooth/bluetooth_adapter_chromeos.h ('k') | device/bluetooth/bluetooth_device_chromeos.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698