| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "components/arc/bluetooth/arc_bluetooth_bridge.h" | 5 #include "components/arc/bluetooth/arc_bluetooth_bridge.h" |
| 6 | 6 |
| 7 #include <fcntl.h> | 7 #include <fcntl.h> |
| 8 #include <stddef.h> | 8 #include <stddef.h> |
| 9 | 9 |
| 10 #include <iomanip> | 10 #include <iomanip> |
| 11 #include <string> | 11 #include <string> |
| 12 | 12 |
| 13 #include "base/bind.h" | 13 #include "base/bind.h" |
| 14 #include "base/logging.h" | 14 #include "base/logging.h" |
| 15 #include "base/posix/eintr_wrapper.h" | 15 #include "base/posix/eintr_wrapper.h" |
| 16 #include "base/strings/string_number_conversions.h" | 16 #include "base/strings/string_number_conversions.h" |
| 17 #include "base/strings/utf_string_conversions.h" | 17 #include "base/strings/utf_string_conversions.h" |
| 18 #include "base/threading/thread_task_runner_handle.h" | 18 #include "base/threading/thread_task_runner_handle.h" |
| 19 #include "base/time/time.h" | 19 #include "base/time/time.h" |
| 20 #include "components/arc/arc_bridge_service.h" | 20 #include "components/arc/arc_bridge_service.h" |
| 21 #include "components/arc/bluetooth/bluetooth_type_converters.h" | 21 #include "components/arc/bluetooth/bluetooth_type_converters.h" |
| 22 #include "device/bluetooth/bluetooth_adapter_factory.h" | 22 #include "device/bluetooth/bluetooth_adapter_factory.h" |
| 23 #include "device/bluetooth/bluetooth_device.h" | 23 #include "device/bluetooth/bluetooth_device.h" |
| 24 #include "device/bluetooth/bluetooth_gatt_connection.h" |
| 25 #include "device/bluetooth/bluetooth_gatt_notify_session.h" |
| 24 #include "device/bluetooth/bluetooth_remote_gatt_characteristic.h" | 26 #include "device/bluetooth/bluetooth_remote_gatt_characteristic.h" |
| 25 #include "device/bluetooth/bluetooth_remote_gatt_descriptor.h" | 27 #include "device/bluetooth/bluetooth_remote_gatt_descriptor.h" |
| 26 #include "device/bluetooth/bluetooth_remote_gatt_service.h" | 28 #include "device/bluetooth/bluetooth_remote_gatt_service.h" |
| 27 | 29 |
| 28 using device::BluetoothAdapter; | 30 using device::BluetoothAdapter; |
| 29 using device::BluetoothAdapterFactory; | 31 using device::BluetoothAdapterFactory; |
| 32 using device::BluetoothAdvertisement; |
| 30 using device::BluetoothDevice; | 33 using device::BluetoothDevice; |
| 34 using device::BluetoothDiscoveryFilter; |
| 31 using device::BluetoothDiscoverySession; | 35 using device::BluetoothDiscoverySession; |
| 36 using device::BluetoothGattConnection; |
| 37 using device::BluetoothGattNotifySession; |
| 38 using device::BluetoothGattCharacteristic; |
| 39 using device::BluetoothGattDescriptor; |
| 40 using device::BluetoothGattService; |
| 32 using device::BluetoothRemoteGattCharacteristic; | 41 using device::BluetoothRemoteGattCharacteristic; |
| 33 using device::BluetoothRemoteGattDescriptor; | 42 using device::BluetoothRemoteGattDescriptor; |
| 34 using device::BluetoothRemoteGattService; | 43 using device::BluetoothRemoteGattService; |
| 44 using device::BluetoothUUID; |
| 45 |
| 46 namespace { |
| 47 const int kMinBtleVersion = 1; |
| 48 const uint32_t kGattReadPermission = |
| 49 BluetoothGattCharacteristic::Permission::PERMISSION_READ | |
| 50 BluetoothGattCharacteristic::Permission::PERMISSION_READ_ENCRYPTED | |
| 51 BluetoothGattCharacteristic::Permission:: |
| 52 PERMISSION_READ_ENCRYPTED_AUTHENTICATED; |
| 53 const uint32_t kGattWritePermission = |
| 54 BluetoothGattCharacteristic::Permission::PERMISSION_WRITE | |
| 55 BluetoothGattCharacteristic::Permission::PERMISSION_WRITE_ENCRYPTED | |
| 56 BluetoothGattCharacteristic::Permission:: |
| 57 PERMISSION_WRITE_ENCRYPTED_AUTHENTICATED; |
| 58 } // namespace |
| 35 | 59 |
| 36 namespace arc { | 60 namespace arc { |
| 37 | 61 |
| 38 ArcBluetoothBridge::ArcBluetoothBridge(ArcBridgeService* bridge_service) | 62 ArcBluetoothBridge::ArcBluetoothBridge(ArcBridgeService* bridge_service) |
| 39 : ArcService(bridge_service), binding_(this), weak_factory_(this) { | 63 : ArcService(bridge_service), binding_(this), weak_factory_(this) { |
| 40 if (BluetoothAdapterFactory::IsBluetoothAdapterAvailable()) { | 64 if (BluetoothAdapterFactory::IsBluetoothAdapterAvailable()) { |
| 41 VLOG(1) << "registering bluetooth adapter"; | 65 VLOG(1) << "registering bluetooth adapter"; |
| 42 BluetoothAdapterFactory::GetAdapter(base::Bind( | 66 BluetoothAdapterFactory::GetAdapter(base::Bind( |
| 43 &ArcBluetoothBridge::OnAdapterInitialized, weak_factory_.GetWeakPtr())); | 67 &ArcBluetoothBridge::OnAdapterInitialized, weak_factory_.GetWeakPtr())); |
| 44 } else { | 68 } else { |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 98 return; | 122 return; |
| 99 | 123 |
| 100 if (device->IsConnected()) | 124 if (device->IsConnected()) |
| 101 return; | 125 return; |
| 102 | 126 |
| 103 mojo::Array<mojom::BluetoothPropertyPtr> properties = | 127 mojo::Array<mojom::BluetoothPropertyPtr> properties = |
| 104 GetDeviceProperties(mojom::BluetoothPropertyType::ALL, device); | 128 GetDeviceProperties(mojom::BluetoothPropertyType::ALL, device); |
| 105 | 129 |
| 106 arc_bridge_service()->bluetooth_instance()->OnDeviceFound( | 130 arc_bridge_service()->bluetooth_instance()->OnDeviceFound( |
| 107 std::move(properties)); | 131 std::move(properties)); |
| 132 |
| 133 if (arc_bridge_service()->bluetooth_version() < kMinBtleVersion) { |
| 134 LOG(WARNING) << "Bluetooth instance is too old and does not support BTLE"; |
| 135 return; |
| 136 } |
| 137 |
| 138 mojom::BluetoothAddressPtr addr = |
| 139 mojom::BluetoothAddress::From(device->GetAddress()); |
| 140 int rssi = device->GetInquiryRSSI(); |
| 141 mojo::Array<mojom::BluetoothAdvertisingDataPtr> adv_data = |
| 142 GetAdvertisingData(device); |
| 143 arc_bridge_service()->bluetooth_instance()->OnLEDeviceFound( |
| 144 std::move(addr), rssi, std::move(adv_data)); |
| 108 } | 145 } |
| 109 | 146 |
| 110 void ArcBluetoothBridge::DeviceChanged(BluetoothAdapter* adapter, | 147 void ArcBluetoothBridge::DeviceChanged(BluetoothAdapter* adapter, |
| 111 BluetoothDevice* device) { | 148 BluetoothDevice* device) { |
| 112 // TODO(smbarber): device properties changed; inform the container. | 149 // TODO(smbarber): device properties changed; inform the container. |
| 113 } | 150 } |
| 114 | 151 |
| 115 void ArcBluetoothBridge::DeviceAddressChanged(BluetoothAdapter* adapter, | 152 void ArcBluetoothBridge::DeviceAddressChanged(BluetoothAdapter* adapter, |
| 116 BluetoothDevice* device, | 153 BluetoothDevice* device, |
| 117 const std::string& old_address) { | 154 const std::string& old_address) { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 157 | 194 |
| 158 void ArcBluetoothBridge::GattServiceRemoved( | 195 void ArcBluetoothBridge::GattServiceRemoved( |
| 159 BluetoothAdapter* adapter, | 196 BluetoothAdapter* adapter, |
| 160 BluetoothDevice* device, | 197 BluetoothDevice* device, |
| 161 BluetoothRemoteGattService* service) { | 198 BluetoothRemoteGattService* service) { |
| 162 // Placeholder for GATT client functionality | 199 // Placeholder for GATT client functionality |
| 163 } | 200 } |
| 164 | 201 |
| 165 void ArcBluetoothBridge::GattServicesDiscovered(BluetoothAdapter* adapter, | 202 void ArcBluetoothBridge::GattServicesDiscovered(BluetoothAdapter* adapter, |
| 166 BluetoothDevice* device) { | 203 BluetoothDevice* device) { |
| 167 // Placeholder for GATT client functionality | 204 if (!HasBluetoothInstance()) |
| 205 return; |
| 206 |
| 207 if (arc_bridge_service()->bluetooth_version() < kMinBtleVersion) { |
| 208 LOG(WARNING) << "Bluetooth instance is too old and does not support BTLE"; |
| 209 return; |
| 210 } |
| 211 |
| 212 mojom::BluetoothAddressPtr addr = |
| 213 mojom::BluetoothAddress::From(device->GetAddress()); |
| 214 |
| 215 arc_bridge_service()->bluetooth_instance()->OnSearchComplete( |
| 216 std::move(addr), mojom::BluetoothGattStatus::GATT_SUCCESS); |
| 168 } | 217 } |
| 169 | 218 |
| 170 void ArcBluetoothBridge::GattDiscoveryCompleteForService( | 219 void ArcBluetoothBridge::GattDiscoveryCompleteForService( |
| 171 BluetoothAdapter* adapter, | 220 BluetoothAdapter* adapter, |
| 172 BluetoothRemoteGattService* service) { | 221 BluetoothRemoteGattService* service) { |
| 173 // Placeholder for GATT client functionality | 222 // Placeholder for GATT client functionality |
| 174 } | 223 } |
| 175 | 224 |
| 176 void ArcBluetoothBridge::GattServiceChanged( | 225 void ArcBluetoothBridge::GattServiceChanged( |
| 177 BluetoothAdapter* adapter, | 226 BluetoothAdapter* adapter, |
| (...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 454 BluetoothDevice* device = | 503 BluetoothDevice* device = |
| 455 bluetooth_adapter_->GetDevice(addr->To<std::string>()); | 504 bluetooth_adapter_->GetDevice(addr->To<std::string>()); |
| 456 if (!device) { | 505 if (!device) { |
| 457 callback.Run(false); | 506 callback.Run(false); |
| 458 return; | 507 return; |
| 459 } | 508 } |
| 460 | 509 |
| 461 callback.Run(device->IsConnected()); | 510 callback.Run(device->IsConnected()); |
| 462 } | 511 } |
| 463 | 512 |
| 513 void ArcBluetoothBridge::StartLEScan() { |
| 514 DCHECK(bluetooth_adapter_); |
| 515 if (discovery_session_) { |
| 516 LOG(WARNING) << "Discovery session already running; leaving alone"; |
| 517 SendCachedDevicesFound(); |
| 518 return; |
| 519 } |
| 520 bluetooth_adapter_->StartDiscoverySessionWithFilter( |
| 521 base::WrapUnique(new BluetoothDiscoveryFilter( |
| 522 BluetoothDiscoveryFilter::Transport::TRANSPORT_LE)), |
| 523 base::Bind(&ArcBluetoothBridge::OnDiscoveryStarted, |
| 524 weak_factory_.GetWeakPtr()), |
| 525 base::Bind(&ArcBluetoothBridge::OnDiscoveryError, |
| 526 weak_factory_.GetWeakPtr())); |
| 527 } |
| 528 |
| 529 void ArcBluetoothBridge::StopLEScan() { |
| 530 CancelDiscovery(); |
| 531 } |
| 532 |
| 533 void ArcBluetoothBridge::OnGattConnectStateChanged( |
| 534 mojom::BluetoothAddressPtr addr, |
| 535 bool connected) const { |
| 536 if (!HasBluetoothInstance()) |
| 537 return; |
| 538 |
| 539 if (arc_bridge_service()->bluetooth_version() < kMinBtleVersion) { |
| 540 LOG(WARNING) << "Bluetooth instance is too old and does not support BTLE"; |
| 541 return; |
| 542 } |
| 543 |
| 544 DCHECK(addr); |
| 545 |
| 546 arc_bridge_service()->bluetooth_instance()->OnLEConnectionStateChange( |
| 547 std::move(addr), connected); |
| 548 } |
| 549 |
| 550 void ArcBluetoothBridge::OnGattConnected( |
| 551 mojom::BluetoothAddressPtr addr, |
| 552 std::unique_ptr<BluetoothGattConnection> connection) const { |
| 553 OnGattConnectStateChanged(std::move(addr), true); |
| 554 } |
| 555 |
| 556 void ArcBluetoothBridge::OnGattConnectError( |
| 557 mojom::BluetoothAddressPtr addr, |
| 558 BluetoothDevice::ConnectErrorCode error_code) const { |
| 559 OnGattConnectStateChanged(std::move(addr), false); |
| 560 } |
| 561 |
| 562 void ArcBluetoothBridge::OnGattDisconnected( |
| 563 mojom::BluetoothAddressPtr addr) const { |
| 564 OnGattConnectStateChanged(std::move(addr), false); |
| 565 } |
| 566 |
| 567 void ArcBluetoothBridge::ConnectLEDevice( |
| 568 mojom::BluetoothAddressPtr remote_addr) { |
| 569 if (!HasBluetoothInstance()) |
| 570 return; |
| 571 |
| 572 BluetoothDevice* device = |
| 573 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>()); |
| 574 DCHECK(device); |
| 575 |
| 576 if (device->IsConnected()) { |
| 577 arc_bridge_service()->bluetooth_instance()->OnLEConnectionStateChange( |
| 578 std::move(remote_addr), true); |
| 579 return; |
| 580 } |
| 581 |
| 582 // Also pass disconnect callback in error case |
| 583 // since it would be disconnected anyway. |
| 584 mojom::BluetoothAddressPtr remote_addr_clone = remote_addr.Clone(); |
| 585 device->CreateGattConnection( |
| 586 base::Bind(&ArcBluetoothBridge::OnGattConnected, |
| 587 weak_factory_.GetWeakPtr(), base::Passed(&remote_addr)), |
| 588 base::Bind(&ArcBluetoothBridge::OnGattConnectError, |
| 589 weak_factory_.GetWeakPtr(), base::Passed(&remote_addr_clone))); |
| 590 } |
| 591 |
| 592 void ArcBluetoothBridge::DisconnectLEDevice( |
| 593 mojom::BluetoothAddressPtr remote_addr) { |
| 594 if (!HasBluetoothInstance()) |
| 595 return; |
| 596 |
| 597 BluetoothDevice* device = |
| 598 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>()); |
| 599 DCHECK(device); |
| 600 |
| 601 if (!device->IsConnected()) { |
| 602 arc_bridge_service()->bluetooth_instance()->OnLEConnectionStateChange( |
| 603 std::move(remote_addr), false); |
| 604 return; |
| 605 } |
| 606 |
| 607 mojom::BluetoothAddressPtr remote_addr_clone = remote_addr.Clone(); |
| 608 device->Disconnect( |
| 609 base::Bind(&ArcBluetoothBridge::OnGattDisconnected, |
| 610 weak_factory_.GetWeakPtr(), base::Passed(&remote_addr)), |
| 611 base::Bind(&ArcBluetoothBridge::OnGattDisconnected, |
| 612 weak_factory_.GetWeakPtr(), base::Passed(&remote_addr_clone))); |
| 613 } |
| 614 |
| 615 void ArcBluetoothBridge::SearchService(mojom::BluetoothAddressPtr remote_addr) { |
| 616 if (!HasBluetoothInstance()) |
| 617 return; |
| 618 |
| 619 BluetoothDevice* device = |
| 620 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>()); |
| 621 DCHECK(device); |
| 622 |
| 623 // Call the callback if discovery is completed |
| 624 if (device->IsGattServicesDiscoveryComplete()) { |
| 625 arc_bridge_service()->bluetooth_instance()->OnSearchComplete( |
| 626 std::move(remote_addr), mojom::BluetoothGattStatus::GATT_SUCCESS); |
| 627 return; |
| 628 } |
| 629 |
| 630 // Discard result. Will call the callback when discovery is completed. |
| 631 device->GetGattServices(); |
| 632 } |
| 633 |
| 634 void ArcBluetoothBridge::OnStartLEListenDone( |
| 635 const StartLEListenCallback& callback, |
| 636 scoped_refptr<BluetoothAdvertisement> advertisement) { |
| 637 advertisment_ = advertisement; |
| 638 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS); |
| 639 } |
| 640 |
| 641 void ArcBluetoothBridge::OnStartLEListenError( |
| 642 const StartLEListenCallback& callback, |
| 643 BluetoothAdvertisement::ErrorCode error_code) { |
| 644 advertisment_ = nullptr; |
| 645 callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE); |
| 646 } |
| 647 |
| 648 void ArcBluetoothBridge::StartLEListen(const StartLEListenCallback& callback) { |
| 649 std::unique_ptr<BluetoothAdvertisement::Data> adv_data = |
| 650 base::WrapUnique(new BluetoothAdvertisement::Data( |
| 651 BluetoothAdvertisement::ADVERTISEMENT_TYPE_BROADCAST)); |
| 652 bluetooth_adapter_->RegisterAdvertisement( |
| 653 std::move(adv_data), base::Bind(&ArcBluetoothBridge::OnStartLEListenDone, |
| 654 weak_factory_.GetWeakPtr(), callback), |
| 655 base::Bind(&ArcBluetoothBridge::OnStartLEListenError, |
| 656 weak_factory_.GetWeakPtr(), callback)); |
| 657 } |
| 658 |
| 659 void ArcBluetoothBridge::OnStopLEListenDone( |
| 660 const StopLEListenCallback& callback) { |
| 661 advertisment_ = nullptr; |
| 662 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS); |
| 663 } |
| 664 |
| 665 void ArcBluetoothBridge::OnStopLEListenError( |
| 666 const StopLEListenCallback& callback, |
| 667 BluetoothAdvertisement::ErrorCode error_code) { |
| 668 advertisment_ = nullptr; |
| 669 callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE); |
| 670 } |
| 671 |
| 672 void ArcBluetoothBridge::StopLEListen(const StopLEListenCallback& callback) { |
| 673 if (!advertisment_) { |
| 674 OnStopLEListenError( |
| 675 callback, |
| 676 BluetoothAdvertisement::ErrorCode::ERROR_ADVERTISEMENT_DOES_NOT_EXIST); |
| 677 return; |
| 678 } |
| 679 advertisment_->Unregister(base::Bind(&ArcBluetoothBridge::OnStopLEListenDone, |
| 680 weak_factory_.GetWeakPtr(), callback), |
| 681 base::Bind(&ArcBluetoothBridge::OnStopLEListenError, |
| 682 weak_factory_.GetWeakPtr(), callback)); |
| 683 } |
| 684 |
| 685 // Example of identifier: /org/bluez/hci0/dev_E0_CF_65_8C_86_1A/service001a |
| 686 // We want to convert last digit of the identifier to int in base 16 |
| 687 int ArcBluetoothBridge::ConvertGattIdentifierToId( |
| 688 const std::string identifier) const { |
| 689 return std::stoi(identifier.substr(identifier.size() - 4), nullptr, 16); |
| 690 } |
| 691 |
| 692 // Create GattDBElement and fill in common data for |
| 693 // Gatt Service/Characteristic/Descriptor. |
| 694 template <class T> |
| 695 mojom::BluetoothGattDBElementPtr ArcBluetoothBridge::CreateGattDBElement( |
| 696 const mojom::BluetoothGattDBAttributeType type, |
| 697 const T* gattObject) const { |
| 698 mojom::BluetoothGattDBElementPtr element = |
| 699 mojom::BluetoothGattDBElement::New(); |
| 700 element->type = type; |
| 701 element->uuid = mojom::BluetoothUUID::From(gattObject->GetUUID()); |
| 702 element->id = element->attribute_handle = element->start_handle = |
| 703 element->end_handle = |
| 704 ConvertGattIdentifierToId(gattObject->GetIdentifier()); |
| 705 element->properties = 0; |
| 706 return element; |
| 707 } |
| 708 |
| 709 void ArcBluetoothBridge::GetGattDB(mojom::BluetoothAddressPtr remote_addr) { |
| 710 if (!HasBluetoothInstance()) |
| 711 return; |
| 712 |
| 713 BluetoothDevice* device = |
| 714 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>()); |
| 715 mojo::Array<mojom::BluetoothGattDBElementPtr> db; |
| 716 for (auto service : device->GetGattServices()) { |
| 717 mojom::BluetoothGattDBElementPtr service_element = CreateGattDBElement< |
| 718 device::BluetoothRemoteGattService>( |
| 719 service->IsPrimary() |
| 720 ? mojom::BluetoothGattDBAttributeType::BTGATT_DB_PRIMARY_SERVICE |
| 721 : mojom::BluetoothGattDBAttributeType::BTGATT_DB_SECONDARY_SERVICE, |
| 722 service); |
| 723 |
| 724 const auto& characteristics = service->GetCharacteristics(); |
| 725 if (characteristics.size() > 0) { |
| 726 const auto& descriptors = characteristics.back()->GetDescriptors(); |
| 727 service_element->start_handle = |
| 728 ConvertGattIdentifierToId(characteristics.front()->GetIdentifier()); |
| 729 service_element->end_handle = ConvertGattIdentifierToId( |
| 730 descriptors.size() > 0 ? descriptors.back()->GetIdentifier() |
| 731 : characteristics.back()->GetIdentifier()); |
| 732 } |
| 733 db.push_back(std::move(service_element)); |
| 734 |
| 735 for (auto characteristic : characteristics) { |
| 736 mojom::BluetoothGattDBElementPtr characteristic_element = |
| 737 CreateGattDBElement<device::BluetoothRemoteGattCharacteristic>( |
| 738 mojom::BluetoothGattDBAttributeType::BTGATT_DB_CHARACTERISTIC, |
| 739 characteristic); |
| 740 characteristic_element->properties = characteristic->GetProperties(); |
| 741 db.push_back(std::move(characteristic_element)); |
| 742 |
| 743 for (auto descriptor : characteristic->GetDescriptors()) { |
| 744 db.push_back(CreateGattDBElement<device::BluetoothRemoteGattDescriptor>( |
| 745 mojom::BluetoothGattDBAttributeType::BTGATT_DB_DESCRIPTOR, |
| 746 descriptor)); |
| 747 } |
| 748 } |
| 749 } |
| 750 |
| 751 arc_bridge_service()->bluetooth_instance()->OnGetGattDB( |
| 752 std::move(remote_addr), std::move(db)); |
| 753 } |
| 754 |
| 755 // Find Gatt Service/Characteristic/Descriptor from std::vector from UUID. |
| 756 template <class T> |
| 757 T* ArcBluetoothBridge::FindGattObjectFromUuid( |
| 758 const std::vector<T*> gatt_objs, |
| 759 const device::BluetoothUUID uuid) const { |
| 760 auto it = std::find_if(gatt_objs.begin(), gatt_objs.end(), |
| 761 [&](T* obj) { return obj->GetUUID() == uuid; }); |
| 762 if (it == gatt_objs.end()) |
| 763 return nullptr; |
| 764 return *it; |
| 765 } |
| 766 |
| 767 BluetoothRemoteGattCharacteristic* ArcBluetoothBridge::FindGattCharacteristic( |
| 768 mojom::BluetoothAddressPtr remote_addr, |
| 769 mojom::BluetoothGattServiceIDPtr service_id, |
| 770 mojom::BluetoothGattIDPtr char_id) const { |
| 771 DCHECK(remote_addr); |
| 772 DCHECK(service_id); |
| 773 DCHECK(char_id); |
| 774 |
| 775 BluetoothDevice* device = |
| 776 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>()); |
| 777 if (!device) |
| 778 return nullptr; |
| 779 |
| 780 BluetoothRemoteGattService* service = |
| 781 FindGattObjectFromUuid<BluetoothRemoteGattService>( |
| 782 device->GetGattServices(), service_id->id->uuid.To<BluetoothUUID>()); |
| 783 if (!service) |
| 784 return nullptr; |
| 785 |
| 786 return FindGattObjectFromUuid<BluetoothRemoteGattCharacteristic>( |
| 787 service->GetCharacteristics(), char_id->uuid.To<BluetoothUUID>()); |
| 788 } |
| 789 |
| 790 BluetoothRemoteGattDescriptor* ArcBluetoothBridge::FindGattDescriptor( |
| 791 mojom::BluetoothAddressPtr remote_addr, |
| 792 mojom::BluetoothGattServiceIDPtr service_id, |
| 793 mojom::BluetoothGattIDPtr char_id, |
| 794 mojom::BluetoothGattIDPtr desc_id) const { |
| 795 BluetoothRemoteGattCharacteristic* characteristic = FindGattCharacteristic( |
| 796 std::move(remote_addr), std::move(service_id), std::move(char_id)); |
| 797 if (!characteristic) |
| 798 return nullptr; |
| 799 |
| 800 return FindGattObjectFromUuid<BluetoothRemoteGattDescriptor>( |
| 801 characteristic->GetDescriptors(), desc_id->uuid.To<BluetoothUUID>()); |
| 802 } |
| 803 |
| 804 // Same callback for both ReadGattCharacteristic and ReadGattDescriptor |
| 805 void ArcBluetoothBridge::OnGattReadDone( |
| 806 const GattReadCallback& callback, |
| 807 const std::vector<uint8_t>& result) const { |
| 808 mojom::BluetoothGattValuePtr gattValue = mojom::BluetoothGattValue::New(); |
| 809 gattValue->status = mojom::BluetoothGattStatus::GATT_SUCCESS; |
| 810 gattValue->value = mojo::Array<uint8_t>::From(result); |
| 811 callback.Run(std::move(gattValue)); |
| 812 } |
| 813 |
| 814 void ArcBluetoothBridge::OnGattReadError( |
| 815 const GattReadCallback& callback, |
| 816 BluetoothGattService::GattErrorCode error_code) const { |
| 817 mojom::BluetoothGattValuePtr gattValue = mojom::BluetoothGattValue::New(); |
| 818 gattValue->status = mojo::ConvertTo<mojom::BluetoothGattStatus>(error_code); |
| 819 gattValue->value = nullptr; |
| 820 |
| 821 callback.Run(std::move(gattValue)); |
| 822 } |
| 823 |
| 824 // Same callback for both WriteGattCharacteristic and WriteGattDescriptor |
| 825 void ArcBluetoothBridge::OnGattWriteDone( |
| 826 const GattWriteCallback& callback) const { |
| 827 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS); |
| 828 } |
| 829 |
| 830 void ArcBluetoothBridge::OnGattWriteError( |
| 831 const GattWriteCallback& callback, |
| 832 BluetoothGattService::GattErrorCode error_code) const { |
| 833 callback.Run(mojo::ConvertTo<mojom::BluetoothGattStatus>(error_code)); |
| 834 } |
| 835 |
| 836 void ArcBluetoothBridge::ReadGattCharacteristic( |
| 837 mojom::BluetoothAddressPtr remote_addr, |
| 838 mojom::BluetoothGattServiceIDPtr service_id, |
| 839 mojom::BluetoothGattIDPtr char_id, |
| 840 const ReadGattCharacteristicCallback& callback) { |
| 841 BluetoothRemoteGattCharacteristic* characteristic = FindGattCharacteristic( |
| 842 std::move(remote_addr), std::move(service_id), std::move(char_id)); |
| 843 DCHECK(characteristic); |
| 844 DCHECK(characteristic->GetPermissions() & kGattReadPermission); |
| 845 |
| 846 characteristic->ReadRemoteCharacteristic( |
| 847 base::Bind(&ArcBluetoothBridge::OnGattReadDone, |
| 848 weak_factory_.GetWeakPtr(), callback), |
| 849 base::Bind(&ArcBluetoothBridge::OnGattReadError, |
| 850 weak_factory_.GetWeakPtr(), callback)); |
| 851 } |
| 852 |
| 853 void ArcBluetoothBridge::WriteGattCharacteristic( |
| 854 mojom::BluetoothAddressPtr remote_addr, |
| 855 mojom::BluetoothGattServiceIDPtr service_id, |
| 856 mojom::BluetoothGattIDPtr char_id, |
| 857 mojom::BluetoothGattValuePtr value, |
| 858 const WriteGattCharacteristicCallback& callback) { |
| 859 BluetoothRemoteGattCharacteristic* characteristic = FindGattCharacteristic( |
| 860 std::move(remote_addr), std::move(service_id), std::move(char_id)); |
| 861 DCHECK(characteristic); |
| 862 DCHECK(characteristic->GetPermissions() & kGattWritePermission); |
| 863 |
| 864 characteristic->WriteRemoteCharacteristic( |
| 865 value->value.To<std::vector<uint8_t>>(), |
| 866 base::Bind(&ArcBluetoothBridge::OnGattWriteDone, |
| 867 weak_factory_.GetWeakPtr(), callback), |
| 868 base::Bind(&ArcBluetoothBridge::OnGattWriteError, |
| 869 weak_factory_.GetWeakPtr(), callback)); |
| 870 } |
| 871 |
| 872 void ArcBluetoothBridge::ReadGattDescriptor( |
| 873 mojom::BluetoothAddressPtr remote_addr, |
| 874 mojom::BluetoothGattServiceIDPtr service_id, |
| 875 mojom::BluetoothGattIDPtr char_id, |
| 876 mojom::BluetoothGattIDPtr desc_id, |
| 877 const ReadGattDescriptorCallback& callback) { |
| 878 BluetoothRemoteGattDescriptor* descriptor = |
| 879 FindGattDescriptor(std::move(remote_addr), std::move(service_id), |
| 880 std::move(char_id), std::move(desc_id)); |
| 881 DCHECK(descriptor); |
| 882 DCHECK(descriptor->GetPermissions() & kGattReadPermission); |
| 883 |
| 884 descriptor->ReadRemoteDescriptor( |
| 885 base::Bind(&ArcBluetoothBridge::OnGattReadDone, |
| 886 weak_factory_.GetWeakPtr(), callback), |
| 887 base::Bind(&ArcBluetoothBridge::OnGattReadError, |
| 888 weak_factory_.GetWeakPtr(), callback)); |
| 889 } |
| 890 |
| 891 void ArcBluetoothBridge::WriteGattDescriptor( |
| 892 mojom::BluetoothAddressPtr remote_addr, |
| 893 mojom::BluetoothGattServiceIDPtr service_id, |
| 894 mojom::BluetoothGattIDPtr char_id, |
| 895 mojom::BluetoothGattIDPtr desc_id, |
| 896 mojom::BluetoothGattValuePtr value, |
| 897 const WriteGattDescriptorCallback& callback) { |
| 898 BluetoothRemoteGattDescriptor* descriptor = |
| 899 FindGattDescriptor(std::move(remote_addr), std::move(service_id), |
| 900 std::move(char_id), std::move(desc_id)); |
| 901 DCHECK(descriptor); |
| 902 DCHECK(descriptor->GetPermissions() & kGattWritePermission); |
| 903 |
| 904 descriptor->WriteRemoteDescriptor( |
| 905 value->value.To<std::vector<uint8_t>>(), |
| 906 base::Bind(&ArcBluetoothBridge::OnGattWriteDone, |
| 907 weak_factory_.GetWeakPtr(), callback), |
| 908 base::Bind(&ArcBluetoothBridge::OnGattWriteError, |
| 909 weak_factory_.GetWeakPtr(), callback)); |
| 910 } |
| 911 |
| 912 void ArcBluetoothBridge::OnGattNotifyStartDone( |
| 913 const RegisterForGattNotificationCallback& callback, |
| 914 const std::string char_string_id, |
| 915 std::unique_ptr<BluetoothGattNotifySession> notify_session) { |
| 916 notification_session_[char_string_id] = std::move(notify_session); |
| 917 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS); |
| 918 } |
| 919 |
| 920 void ArcBluetoothBridge::OnGattNotifyStartError( |
| 921 const RegisterForGattNotificationCallback& callback, |
| 922 BluetoothGattService::GattErrorCode error_code) const { |
| 923 callback.Run(mojo::ConvertTo<mojom::BluetoothGattStatus>(error_code)); |
| 924 } |
| 925 |
| 926 void ArcBluetoothBridge::OnGattNotifyStopDone( |
| 927 const DeregisterForGattNotificationCallback& callback) const { |
| 928 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS); |
| 929 } |
| 930 |
| 931 void ArcBluetoothBridge::RegisterForGattNotification( |
| 932 mojom::BluetoothAddressPtr remote_addr, |
| 933 mojom::BluetoothGattServiceIDPtr service_id, |
| 934 mojom::BluetoothGattIDPtr char_id, |
| 935 const RegisterForGattNotificationCallback& callback) { |
| 936 BluetoothRemoteGattCharacteristic* characteristic = FindGattCharacteristic( |
| 937 std::move(remote_addr), std::move(service_id), std::move(char_id)); |
| 938 |
| 939 if (!characteristic) { |
| 940 LOG(WARNING) << __func__ << " Characteristic is not existed."; |
| 941 return; |
| 942 } |
| 943 |
| 944 if (characteristic->IsNotifying()) { |
| 945 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS); |
| 946 return; |
| 947 } |
| 948 |
| 949 characteristic->StartNotifySession( |
| 950 base::Bind(&ArcBluetoothBridge::OnGattNotifyStartDone, |
| 951 weak_factory_.GetWeakPtr(), callback, |
| 952 characteristic->GetIdentifier()), |
| 953 base::Bind(&ArcBluetoothBridge::OnGattNotifyStartError, |
| 954 weak_factory_.GetWeakPtr(), callback)); |
| 955 } |
| 956 |
| 957 void ArcBluetoothBridge::DeregisterForGattNotification( |
| 958 mojom::BluetoothAddressPtr remote_addr, |
| 959 mojom::BluetoothGattServiceIDPtr service_id, |
| 960 mojom::BluetoothGattIDPtr char_id, |
| 961 const DeregisterForGattNotificationCallback& callback) { |
| 962 BluetoothRemoteGattCharacteristic* characteristic = FindGattCharacteristic( |
| 963 std::move(remote_addr), std::move(service_id), std::move(char_id)); |
| 964 |
| 965 if (!characteristic) { |
| 966 LOG(WARNING) << __func__ << " Characteristic is not existed."; |
| 967 return; |
| 968 } |
| 969 |
| 970 if (!characteristic->IsNotifying()) { |
| 971 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS); |
| 972 return; |
| 973 } |
| 974 |
| 975 std::string char_id_str = characteristic->GetIdentifier(); |
| 976 std::unique_ptr<BluetoothGattNotifySession> notify = |
| 977 std::move(notification_session_[char_id_str]); |
| 978 notification_session_.erase(char_id_str); |
| 979 notify->Stop(base::Bind(&ArcBluetoothBridge::OnGattNotifyStopDone, |
| 980 weak_factory_.GetWeakPtr(), callback)); |
| 981 } |
| 982 |
| 983 void ArcBluetoothBridge::ReadRemoteRssi( |
| 984 mojom::BluetoothAddressPtr remote_addr, |
| 985 const ReadRemoteRssiCallback& callback) { |
| 986 BluetoothDevice* device = |
| 987 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>()); |
| 988 int rssi = device->GetInquiryRSSI(); |
| 989 callback.Run(rssi); |
| 990 } |
| 991 |
| 464 void ArcBluetoothBridge::OnDiscoveryError() { | 992 void ArcBluetoothBridge::OnDiscoveryError() { |
| 465 LOG(WARNING) << "failed to change discovery state"; | 993 LOG(WARNING) << "failed to change discovery state"; |
| 466 } | 994 } |
| 467 | 995 |
| 468 void ArcBluetoothBridge::OnPairing(mojom::BluetoothAddressPtr addr) const { | 996 void ArcBluetoothBridge::OnPairing(mojom::BluetoothAddressPtr addr) const { |
| 469 if (!HasBluetoothInstance()) | 997 if (!HasBluetoothInstance()) |
| 470 return; | 998 return; |
| 471 | 999 |
| 472 arc_bridge_service()->bluetooth_instance()->OnBondStateChanged( | 1000 arc_bridge_service()->bluetooth_instance()->OnBondStateChanged( |
| 473 mojom::BluetoothStatus::SUCCESS, std::move(addr), | 1001 mojom::BluetoothStatus::SUCCESS, std::move(addr), |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 536 } | 1064 } |
| 537 if (type == mojom::BluetoothPropertyType::ALL || | 1065 if (type == mojom::BluetoothPropertyType::ALL || |
| 538 type == mojom::BluetoothPropertyType::BDADDR) { | 1066 type == mojom::BluetoothPropertyType::BDADDR) { |
| 539 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); | 1067 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); |
| 540 btp->set_bdaddr(mojom::BluetoothAddress::From(device->GetAddress())); | 1068 btp->set_bdaddr(mojom::BluetoothAddress::From(device->GetAddress())); |
| 541 properties.push_back(std::move(btp)); | 1069 properties.push_back(std::move(btp)); |
| 542 } | 1070 } |
| 543 if (type == mojom::BluetoothPropertyType::ALL || | 1071 if (type == mojom::BluetoothPropertyType::ALL || |
| 544 type == mojom::BluetoothPropertyType::UUIDS) { | 1072 type == mojom::BluetoothPropertyType::UUIDS) { |
| 545 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); | 1073 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); |
| 546 std::vector<device::BluetoothUUID> uuids = device->GetUUIDs(); | 1074 std::vector<BluetoothUUID> uuids = device->GetUUIDs(); |
| 547 mojo::Array<mojom::BluetoothUUIDPtr> uuid_results = | 1075 mojo::Array<mojom::BluetoothUUIDPtr> uuid_results = |
| 548 mojo::Array<mojom::BluetoothUUIDPtr>::New(0); | 1076 mojo::Array<mojom::BluetoothUUIDPtr>::New(0); |
| 549 | 1077 |
| 550 for (size_t i = 0; i < uuids.size(); i++) { | 1078 for (auto& uuid : uuids) { |
| 551 uuid_results.push_back(mojom::BluetoothUUID::From(uuids[i])); | 1079 uuid_results.push_back(mojom::BluetoothUUID::From(uuid)); |
| 552 } | 1080 } |
| 553 | 1081 |
| 554 btp->set_uuids(std::move(uuid_results)); | 1082 btp->set_uuids(std::move(uuid_results)); |
| 555 properties.push_back(std::move(btp)); | 1083 properties.push_back(std::move(btp)); |
| 556 } | 1084 } |
| 557 if (type == mojom::BluetoothPropertyType::ALL || | 1085 if (type == mojom::BluetoothPropertyType::ALL || |
| 558 type == mojom::BluetoothPropertyType::CLASS_OF_DEVICE) { | 1086 type == mojom::BluetoothPropertyType::CLASS_OF_DEVICE) { |
| 559 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); | 1087 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); |
| 560 btp->set_device_class(device->GetBluetoothClass()); | 1088 btp->set_device_class(device->GetBluetoothClass()); |
| 561 properties.push_back(std::move(btp)); | 1089 properties.push_back(std::move(btp)); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 635 properties.push_back(std::move(btp)); | 1163 properties.push_back(std::move(btp)); |
| 636 } | 1164 } |
| 637 if (type == mojom::BluetoothPropertyType::ALL || | 1165 if (type == mojom::BluetoothPropertyType::ALL || |
| 638 type == mojom::BluetoothPropertyType::ADAPTER_BONDED_DEVICES) { | 1166 type == mojom::BluetoothPropertyType::ADAPTER_BONDED_DEVICES) { |
| 639 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); | 1167 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); |
| 640 BluetoothAdapter::DeviceList devices = bluetooth_adapter_->GetDevices(); | 1168 BluetoothAdapter::DeviceList devices = bluetooth_adapter_->GetDevices(); |
| 641 | 1169 |
| 642 mojo::Array<mojom::BluetoothAddressPtr> bonded_devices = | 1170 mojo::Array<mojom::BluetoothAddressPtr> bonded_devices = |
| 643 mojo::Array<mojom::BluetoothAddressPtr>::New(0); | 1171 mojo::Array<mojom::BluetoothAddressPtr>::New(0); |
| 644 | 1172 |
| 645 for (size_t i = 0; i < devices.size(); i++) { | 1173 for (auto device : devices) { |
| 646 if (!devices[i]->IsPaired()) | 1174 if (device->IsPaired()) |
| 647 continue; | 1175 continue; |
| 648 | 1176 |
| 649 mojom::BluetoothAddressPtr addr = | 1177 mojom::BluetoothAddressPtr addr = |
| 650 mojom::BluetoothAddress::From(devices[i]->GetAddress()); | 1178 mojom::BluetoothAddress::From(device->GetAddress()); |
| 651 bonded_devices.push_back(std::move(addr)); | 1179 bonded_devices.push_back(std::move(addr)); |
| 652 } | 1180 } |
| 653 | 1181 |
| 654 btp->set_bonded_devices(std::move(bonded_devices)); | 1182 btp->set_bonded_devices(std::move(bonded_devices)); |
| 655 properties.push_back(std::move(btp)); | 1183 properties.push_back(std::move(btp)); |
| 656 } | 1184 } |
| 657 if (type == mojom::BluetoothPropertyType::ALL || | 1185 if (type == mojom::BluetoothPropertyType::ALL || |
| 658 type == mojom::BluetoothPropertyType::ADAPTER_DISCOVERY_TIMEOUT) { | 1186 type == mojom::BluetoothPropertyType::ADAPTER_DISCOVERY_TIMEOUT) { |
| 659 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); | 1187 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); |
| 660 btp->set_discovery_timeout(120); | 1188 btp->set_discovery_timeout(120); |
| 661 properties.push_back(std::move(btp)); | 1189 properties.push_back(std::move(btp)); |
| 662 } | 1190 } |
| 663 | 1191 |
| 664 return properties; | 1192 return properties; |
| 665 } | 1193 } |
| 666 | 1194 |
| 1195 // Android support 5 types of Advertising Data. |
| 1196 // However Chrome didn't expose AdvertiseFlag and ManufacturerData. |
| 1197 // So we will only expose local_name, service_uuids and service_data. |
| 1198 // TODO(crbug.com/618442) Make Chrome expose missing data. |
| 1199 mojo::Array<mojom::BluetoothAdvertisingDataPtr> |
| 1200 ArcBluetoothBridge::GetAdvertisingData(BluetoothDevice* device) const { |
| 1201 mojo::Array<mojom::BluetoothAdvertisingDataPtr> advertising_data; |
| 1202 |
| 1203 // LocalName |
| 1204 mojom::BluetoothAdvertisingDataPtr local_name = |
| 1205 mojom::BluetoothAdvertisingData::New(); |
| 1206 local_name->set_local_name(base::UTF16ToUTF8(device->GetNameForDisplay())); |
| 1207 advertising_data.push_back(std::move(local_name)); |
| 1208 |
| 1209 // ServiceUuid |
| 1210 BluetoothDevice::UUIDList uuid_list = device->GetServiceDataUUIDs(); |
| 1211 if (uuid_list.size() > 0) { |
| 1212 mojom::BluetoothAdvertisingDataPtr service_uuids = |
| 1213 mojom::BluetoothAdvertisingData::New(); |
| 1214 service_uuids->set_service_uuids( |
| 1215 mojo::Array<mojom::BluetoothUUIDPtr>::From(uuid_list)); |
| 1216 advertising_data.push_back(std::move(service_uuids)); |
| 1217 } |
| 1218 |
| 1219 // Service data |
| 1220 for (auto& uuid : uuid_list) { |
| 1221 base::BinaryValue* data = device->GetServiceData(uuid); |
| 1222 if (data->GetSize() == 0) |
| 1223 continue; |
| 1224 std::string data_str; |
| 1225 if (!data->GetAsString(&data_str)) |
| 1226 continue; |
| 1227 |
| 1228 mojom::BluetoothAdvertisingDataPtr service_data_element = |
| 1229 mojom::BluetoothAdvertisingData::New(); |
| 1230 mojom::BluetoothServiceDataPtr service_data = |
| 1231 mojom::BluetoothServiceData::New(); |
| 1232 |
| 1233 std::string uuid_str = uuid.canonical_value(); |
| 1234 // Convert xxxxyyyy-xxxx-xxxx-xxxx-xxxxxxxxxxxx to int16 yyyy |
| 1235 service_data->uuid_16bit = std::stoi(uuid_str.substr(4, 4), nullptr, 16); |
| 1236 for (auto& c : data_str) { |
| 1237 service_data->data.push_back(c); |
| 1238 } |
| 1239 service_data_element->set_service_data(std::move(service_data)); |
| 1240 advertising_data.push_back(std::move(service_data_element)); |
| 1241 } |
| 1242 |
| 1243 return advertising_data; |
| 1244 } |
| 1245 |
| 667 void ArcBluetoothBridge::SendCachedDevicesFound() const { | 1246 void ArcBluetoothBridge::SendCachedDevicesFound() const { |
| 668 // Send devices that have already been discovered, but aren't connected. | 1247 // Send devices that have already been discovered, but aren't connected. |
| 669 if (!HasBluetoothInstance()) | 1248 if (!HasBluetoothInstance()) |
| 670 return; | 1249 return; |
| 671 | 1250 |
| 672 BluetoothAdapter::DeviceList devices = bluetooth_adapter_->GetDevices(); | 1251 BluetoothAdapter::DeviceList devices = bluetooth_adapter_->GetDevices(); |
| 673 for (size_t i = 0; i < devices.size(); i++) { | 1252 for (auto device : devices) { |
| 674 if (devices[i]->IsPaired()) | 1253 if (device->IsPaired()) |
| 675 continue; | 1254 continue; |
| 676 | 1255 |
| 677 mojo::Array<mojom::BluetoothPropertyPtr> properties = | 1256 mojo::Array<mojom::BluetoothPropertyPtr> properties = |
| 678 GetDeviceProperties(mojom::BluetoothPropertyType::ALL, devices[i]); | 1257 GetDeviceProperties(mojom::BluetoothPropertyType::ALL, device); |
| 679 | 1258 |
| 680 arc_bridge_service()->bluetooth_instance()->OnDeviceFound( | 1259 arc_bridge_service()->bluetooth_instance()->OnDeviceFound( |
| 681 std::move(properties)); | 1260 std::move(properties)); |
| 1261 |
| 1262 if (arc_bridge_service()->bluetooth_version() >= kMinBtleVersion) { |
| 1263 mojom::BluetoothAddressPtr addr = |
| 1264 mojom::BluetoothAddress::From(device->GetAddress()); |
| 1265 int rssi = device->GetInquiryRSSI(); |
| 1266 mojo::Array<mojom::BluetoothAdvertisingDataPtr> adv_data = |
| 1267 GetAdvertisingData(device); |
| 1268 arc_bridge_service()->bluetooth_instance()->OnLEDeviceFound( |
| 1269 std::move(addr), rssi, std::move(adv_data)); |
| 1270 } |
| 682 } | 1271 } |
| 683 } | 1272 } |
| 684 | 1273 |
| 685 bool ArcBluetoothBridge::HasBluetoothInstance() const { | 1274 bool ArcBluetoothBridge::HasBluetoothInstance() const { |
| 686 if (!arc_bridge_service()->bluetooth_instance()) { | 1275 if (!arc_bridge_service()->bluetooth_instance()) { |
| 687 LOG(WARNING) << "no Bluetooth instance available"; | 1276 LOG(WARNING) << "no Bluetooth instance available"; |
| 688 return false; | 1277 return false; |
| 689 } | 1278 } |
| 690 | 1279 |
| 691 return true; | 1280 return true; |
| 692 } | 1281 } |
| 693 | 1282 |
| 694 void ArcBluetoothBridge::SendCachedPairedDevices() const { | 1283 void ArcBluetoothBridge::SendCachedPairedDevices() const { |
| 695 DCHECK(bluetooth_adapter_); | 1284 DCHECK(bluetooth_adapter_); |
| 1285 if (!HasBluetoothInstance()) |
| 1286 return; |
| 696 | 1287 |
| 697 BluetoothAdapter::DeviceList devices = bluetooth_adapter_->GetDevices(); | 1288 BluetoothAdapter::DeviceList devices = bluetooth_adapter_->GetDevices(); |
| 698 for (BluetoothDevice* device : devices) { | 1289 for (auto device : devices) { |
| 699 if (!device->IsPaired()) | 1290 if (!device->IsPaired()) |
| 700 continue; | 1291 continue; |
| 701 | 1292 |
| 702 mojo::Array<mojom::BluetoothPropertyPtr> properties = | 1293 mojo::Array<mojom::BluetoothPropertyPtr> properties = |
| 703 GetDeviceProperties(mojom::BluetoothPropertyType::ALL, device); | 1294 GetDeviceProperties(mojom::BluetoothPropertyType::ALL, device); |
| 704 | 1295 |
| 705 arc_bridge_service()->bluetooth_instance()->OnDeviceFound( | 1296 arc_bridge_service()->bluetooth_instance()->OnDeviceFound( |
| 706 std::move(properties)); | 1297 std::move(properties)); |
| 707 | 1298 |
| 708 mojom::BluetoothAddressPtr addr = | 1299 mojom::BluetoothAddressPtr addr = |
| 709 mojom::BluetoothAddress::From(device->GetAddress()); | 1300 mojom::BluetoothAddress::From(device->GetAddress()); |
| 710 | 1301 |
| 1302 if (arc_bridge_service()->bluetooth_version() >= kMinBtleVersion) { |
| 1303 int rssi = device->GetInquiryRSSI(); |
| 1304 mojo::Array<mojom::BluetoothAdvertisingDataPtr> adv_data = |
| 1305 GetAdvertisingData(device); |
| 1306 arc_bridge_service()->bluetooth_instance()->OnLEDeviceFound( |
| 1307 addr->Clone(), rssi, std::move(adv_data)); |
| 1308 } |
| 1309 |
| 711 // OnBondStateChanged must be called with mojom::BluetoothBondState::BONDING | 1310 // OnBondStateChanged must be called with mojom::BluetoothBondState::BONDING |
| 712 // to | 1311 // to |
| 713 // make sure the bond state machine on Android is ready to take the | 1312 // make sure the bond state machine on Android is ready to take the |
| 714 // pair-done event. Otherwise the pair-done event will be dropped as an | 1313 // pair-done event. Otherwise the pair-done event will be dropped as an |
| 715 // invalid change of paired status. | 1314 // invalid change of paired status. |
| 716 OnPairing(addr->Clone()); | 1315 OnPairing(addr->Clone()); |
| 717 OnPairedDone(std::move(addr)); | 1316 OnPairedDone(std::move(addr)); |
| 718 } | 1317 } |
| 719 } | 1318 } |
| 720 | 1319 |
| 721 } // namespace arc | 1320 } // namespace arc |
| OLD | NEW |