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

Side by Side Diff: components/arc/bluetooth/arc_bluetooth_bridge.cc

Issue 1927803002: arc: bluetooth: Add gatt client functionality (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: refactor gatt permission to a const Created 4 years, 6 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 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
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
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
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
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
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
OLDNEW
« no previous file with comments | « components/arc/bluetooth/arc_bluetooth_bridge.h ('k') | components/arc/bluetooth/bluetooth_type_converters.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698