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

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: Address palmer / dcheng comment 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 } // namespace
35 49
36 namespace arc { 50 namespace arc {
37 51
38 ArcBluetoothBridge::ArcBluetoothBridge(ArcBridgeService* bridge_service) 52 ArcBluetoothBridge::ArcBluetoothBridge(ArcBridgeService* bridge_service)
39 : ArcService(bridge_service), binding_(this), weak_factory_(this) { 53 : ArcService(bridge_service), binding_(this), weak_factory_(this) {
40 if (BluetoothAdapterFactory::IsBluetoothAdapterAvailable()) { 54 if (BluetoothAdapterFactory::IsBluetoothAdapterAvailable()) {
41 VLOG(1) << "registering bluetooth adapter"; 55 VLOG(1) << "registering bluetooth adapter";
42 BluetoothAdapterFactory::GetAdapter(base::Bind( 56 BluetoothAdapterFactory::GetAdapter(base::Bind(
43 &ArcBluetoothBridge::OnAdapterInitialized, weak_factory_.GetWeakPtr())); 57 &ArcBluetoothBridge::OnAdapterInitialized, weak_factory_.GetWeakPtr()));
44 } else { 58 } else {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 return; 112 return;
99 113
100 if (device->IsConnected()) 114 if (device->IsConnected())
101 return; 115 return;
102 116
103 mojo::Array<mojom::BluetoothPropertyPtr> properties = 117 mojo::Array<mojom::BluetoothPropertyPtr> properties =
104 GetDeviceProperties(mojom::BluetoothPropertyType::ALL, device); 118 GetDeviceProperties(mojom::BluetoothPropertyType::ALL, device);
105 119
106 arc_bridge_service()->bluetooth_instance()->OnDeviceFound( 120 arc_bridge_service()->bluetooth_instance()->OnDeviceFound(
107 std::move(properties)); 121 std::move(properties));
122
123 if (arc_bridge_service()->bluetooth_version() < kMinBtleVersion) {
124 LOG(WARNING) << "Bluetooth instance is too old and does not support BTLE";
125 return;
126 }
127
128 mojom::BluetoothAddressPtr addr =
129 mojom::BluetoothAddress::From(device->GetAddress());
130 int rssi = device->GetInquiryRSSI();
131 mojo::Array<mojom::BluetoothAdvertisingDataPtr> adv_data =
132 GetAdvertisingData(device);
133 arc_bridge_service()->bluetooth_instance()->OnLEDeviceFound(
134 std::move(addr), rssi, std::move(adv_data));
108 } 135 }
109 136
110 void ArcBluetoothBridge::DeviceChanged(BluetoothAdapter* adapter, 137 void ArcBluetoothBridge::DeviceChanged(BluetoothAdapter* adapter,
111 BluetoothDevice* device) { 138 BluetoothDevice* device) {
112 // TODO(smbarber): device properties changed; inform the container. 139 // TODO(smbarber): device properties changed; inform the container.
113 } 140 }
114 141
115 void ArcBluetoothBridge::DeviceAddressChanged(BluetoothAdapter* adapter, 142 void ArcBluetoothBridge::DeviceAddressChanged(BluetoothAdapter* adapter,
116 BluetoothDevice* device, 143 BluetoothDevice* device,
117 const std::string& old_address) { 144 const std::string& old_address) {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
157 184
158 void ArcBluetoothBridge::GattServiceRemoved( 185 void ArcBluetoothBridge::GattServiceRemoved(
159 BluetoothAdapter* adapter, 186 BluetoothAdapter* adapter,
160 BluetoothDevice* device, 187 BluetoothDevice* device,
161 BluetoothRemoteGattService* service) { 188 BluetoothRemoteGattService* service) {
162 // Placeholder for GATT client functionality 189 // Placeholder for GATT client functionality
163 } 190 }
164 191
165 void ArcBluetoothBridge::GattServicesDiscovered(BluetoothAdapter* adapter, 192 void ArcBluetoothBridge::GattServicesDiscovered(BluetoothAdapter* adapter,
166 BluetoothDevice* device) { 193 BluetoothDevice* device) {
167 // Placeholder for GATT client functionality 194 if (!HasBluetoothInstance())
195 return;
196
197 if (arc_bridge_service()->bluetooth_version() < kMinBtleVersion) {
198 LOG(WARNING) << "Bluetooth instance is too old and does not support BTLE";
199 return;
200 }
201
202 mojom::BluetoothAddressPtr addr =
203 mojom::BluetoothAddress::From(device->GetAddress());
204
205 arc_bridge_service()->bluetooth_instance()->OnSearchComplete(
206 std::move(addr), mojom::BluetoothGattStatus::GATT_SUCCESS);
168 } 207 }
169 208
170 void ArcBluetoothBridge::GattDiscoveryCompleteForService( 209 void ArcBluetoothBridge::GattDiscoveryCompleteForService(
171 BluetoothAdapter* adapter, 210 BluetoothAdapter* adapter,
172 BluetoothRemoteGattService* service) { 211 BluetoothRemoteGattService* service) {
173 // Placeholder for GATT client functionality 212 // Placeholder for GATT client functionality
174 } 213 }
175 214
176 void ArcBluetoothBridge::GattServiceChanged( 215 void ArcBluetoothBridge::GattServiceChanged(
177 BluetoothAdapter* adapter, 216 BluetoothAdapter* adapter,
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
454 BluetoothDevice* device = 493 BluetoothDevice* device =
455 bluetooth_adapter_->GetDevice(addr->To<std::string>()); 494 bluetooth_adapter_->GetDevice(addr->To<std::string>());
456 if (!device) { 495 if (!device) {
457 callback.Run(false); 496 callback.Run(false);
458 return; 497 return;
459 } 498 }
460 499
461 callback.Run(device->IsConnected()); 500 callback.Run(device->IsConnected());
462 } 501 }
463 502
503 void ArcBluetoothBridge::StartLEScan() {
504 DCHECK(bluetooth_adapter_);
505 if (discovery_session_) {
506 LOG(WARNING) << "Discovery session already running; leaving alone";
507 SendCachedDevicesFound();
508 return;
509 }
510 bluetooth_adapter_->StartDiscoverySessionWithFilter(
511 base::WrapUnique(new BluetoothDiscoveryFilter(
512 BluetoothDiscoveryFilter::Transport::TRANSPORT_LE)),
513 base::Bind(&ArcBluetoothBridge::OnDiscoveryStarted,
514 weak_factory_.GetWeakPtr()),
515 base::Bind(&ArcBluetoothBridge::OnDiscoveryError,
516 weak_factory_.GetWeakPtr()));
517 }
518
519 void ArcBluetoothBridge::StopLEScan() {
520 CancelDiscovery();
521 }
522
523 void ArcBluetoothBridge::OnGattConnected(
524 mojom::BluetoothAddressPtr addr,
525 std::unique_ptr<BluetoothGattConnection> connection) const {
526 if (!HasBluetoothInstance())
527 return;
528
529 if (arc_bridge_service()->bluetooth_version() < kMinBtleVersion) {
530 LOG(WARNING) << "Bluetooth instance is too old and does not support BTLE";
531 return;
532 }
533
534 DCHECK(addr);
palmer 2016/06/14 23:08:25 Nit/Bikeshed: I'd rather use complete words, e.g.
puthik_chromium 2016/06/15 18:06:33 The |addr| name is used in Android side API. So I
535
536 arc_bridge_service()->bluetooth_instance()->OnLEConnectionStateChange(
537 std::move(addr), true);
538 }
539
540 void ArcBluetoothBridge::OnGattConnectError(
palmer 2016/06/14 23:08:25 The only difference between this function and |OnG
puthik_chromium 2016/06/15 18:06:34 Done.
541 mojom::BluetoothAddressPtr addr,
542 BluetoothDevice::ConnectErrorCode error_code) const {
543 if (!HasBluetoothInstance())
544 return;
545
546 if (arc_bridge_service()->bluetooth_version() < kMinBtleVersion) {
547 LOG(WARNING) << "Bluetooth instance is too old and does not support BTLE";
548 return;
549 }
550
551 DCHECK(addr);
552
553 arc_bridge_service()->bluetooth_instance()->OnLEConnectionStateChange(
554 std::move(addr), false);
555 }
556
557 void ArcBluetoothBridge::OnGattDisconnected(
palmer 2016/06/14 23:08:25 This function is identical to |OnGattConnectError|
puthik_chromium 2016/06/15 18:06:33 Done.
558 mojom::BluetoothAddressPtr addr) const {
559 if (!HasBluetoothInstance())
560 return;
561
562 if (arc_bridge_service()->bluetooth_version() < kMinBtleVersion) {
563 LOG(WARNING) << "Bluetooth instance is too old and does not support BTLE";
564 return;
565 }
566
567 DCHECK(addr);
568
569 arc_bridge_service()->bluetooth_instance()->OnLEConnectionStateChange(
570 std::move(addr), false);
571 }
572
573 void ArcBluetoothBridge::ConnectLEDevice(
574 mojom::BluetoothAddressPtr remote_addr) {
575 if (!HasBluetoothInstance())
576 return;
577
578 BluetoothDevice* device =
579 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>());
580 DCHECK(device);
581
582 if (device->IsConnected()) {
583 arc_bridge_service()->bluetooth_instance()->OnLEConnectionStateChange(
584 std::move(remote_addr), true);
585 return;
586 }
587
588 // Also pass disconnect callback in error case
589 // since it would be disconnected anyway.
590 mojom::BluetoothAddressPtr remote_addr_clone = remote_addr.Clone();
591 device->CreateGattConnection(
592 base::Bind(&ArcBluetoothBridge::OnGattConnected,
593 weak_factory_.GetWeakPtr(), base::Passed(&remote_addr)),
594 base::Bind(&ArcBluetoothBridge::OnGattConnectError,
595 weak_factory_.GetWeakPtr(), base::Passed(&remote_addr_clone)));
596 }
597
598 void ArcBluetoothBridge::DisconnectLEDevice(
599 mojom::BluetoothAddressPtr remote_addr) {
600 if (!HasBluetoothInstance())
601 return;
602
603 BluetoothDevice* device =
604 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>());
605 DCHECK(device);
606
607 if (!device->IsConnected()) {
608 arc_bridge_service()->bluetooth_instance()->OnLEConnectionStateChange(
609 std::move(remote_addr), false);
610 return;
611 }
612
613 mojom::BluetoothAddressPtr remote_addr_clone = remote_addr.Clone();
614 device->Disconnect(
615 base::Bind(&ArcBluetoothBridge::OnGattDisconnected,
616 weak_factory_.GetWeakPtr(), base::Passed(&remote_addr)),
617 base::Bind(&ArcBluetoothBridge::OnGattDisconnected,
618 weak_factory_.GetWeakPtr(), base::Passed(&remote_addr_clone)));
619 }
620
621 void ArcBluetoothBridge::SearchService(mojom::BluetoothAddressPtr remote_addr) {
622 if (!HasBluetoothInstance())
palmer 2016/06/14 23:08:25 Again, 622 if (!HasBluetoothInstance()) 623
puthik_chromium 2016/06/15 18:06:33 I don't agree with this. The code has very differe
rkc 2016/06/15 20:40:00 I agree with Opal. Additionally this code also ser
623 return;
624
625 BluetoothDevice* device =
626 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>());
627 DCHECK(device);
628
629 // Call the callback if discovery is completed
630 if (device->IsGattServicesDiscoveryComplete()) {
631 arc_bridge_service()->bluetooth_instance()->OnSearchComplete(
632 std::move(remote_addr), mojom::BluetoothGattStatus::GATT_SUCCESS);
633 return;
634 }
635
636 // Discard result. Will call the callback when discovery is completed.
637 device->GetGattServices();
638 }
639
640 void ArcBluetoothBridge::OnStartLEListenDone(
641 const StartLEListenCallback& callback,
642 scoped_refptr<BluetoothAdvertisement> adv) {
palmer 2016/06/14 23:08:26 Same nit/bikeshed as before: Disprefer terse names
puthik_chromium 2016/06/15 18:06:34 Done.
643 advertisment_ = adv;
644 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
645 }
646
647 void ArcBluetoothBridge::OnStartLEListenError(
648 const StartLEListenCallback& callback,
649 BluetoothAdvertisement::ErrorCode error_code) {
650 advertisment_ = nullptr;
651 callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE);
652 }
653
654 void ArcBluetoothBridge::StartLEListen(const StartLEListenCallback& callback) {
655 std::unique_ptr<BluetoothAdvertisement::Data> adv_data =
656 base::WrapUnique(new BluetoothAdvertisement::Data(
657 BluetoothAdvertisement::ADVERTISEMENT_TYPE_BROADCAST));
658 bluetooth_adapter_->RegisterAdvertisement(
659 std::move(adv_data), base::Bind(&ArcBluetoothBridge::OnStartLEListenDone,
660 weak_factory_.GetWeakPtr(), callback),
661 base::Bind(&ArcBluetoothBridge::OnStartLEListenError,
662 weak_factory_.GetWeakPtr(), callback));
663 }
664
665 void ArcBluetoothBridge::OnStopLEListenDone(
666 const StopLEListenCallback& callback) {
667 advertisment_ = nullptr;
668 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
669 }
670
671 void ArcBluetoothBridge::OnStopLEListenError(
672 const StopLEListenCallback& callback,
673 BluetoothAdvertisement::ErrorCode error_code) {
674 advertisment_ = nullptr;
675 callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE);
676 }
677
678 void ArcBluetoothBridge::StopLEListen(const StopLEListenCallback& callback) {
679 if (!advertisment_) {
680 OnStopLEListenError(
681 callback,
682 BluetoothAdvertisement::ErrorCode::ERROR_ADVERTISEMENT_DOES_NOT_EXIST);
683 return;
684 }
685 advertisment_->Unregister(base::Bind(&ArcBluetoothBridge::OnStopLEListenDone,
686 weak_factory_.GetWeakPtr(), callback),
687 base::Bind(&ArcBluetoothBridge::OnStopLEListenError,
688 weak_factory_.GetWeakPtr(), callback));
689 }
690
691 void ArcBluetoothBridge::GetGattDB(mojom::BluetoothAddressPtr remote_addr) {
692 if (!HasBluetoothInstance())
693 return;
694
695 BluetoothDevice* device =
696 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>());
697 mojo::Array<mojom::BluetoothGattDBElementPtr> db;
698 for (auto service : device->GetGattServices()) {
699 mojom::BluetoothGattDBElementPtr service_element =
700 mojom::BluetoothGattDBElement::New();
701
702 // Example: /org/bluez/hci0/dev_E0_CF_65_8C_86_1A/service001a
703 std::string id_str = service->GetIdentifier();
704
705 // Convert last digit of service id to int in base 16
706 int id = std::stoi(id_str.substr(id_str.size() - 4), nullptr, 16);
707
708 service_element->id = id;
709 service_element->uuid = mojom::BluetoothUUID::From(service->GetUUID());
710 if (service->IsPrimary()) {
711 service_element->type =
712 mojom::BluetoothGattDBAttributeType::BTGATT_DB_PRIMARY_SERVICE;
713 } else {
714 service_element->type =
715 mojom::BluetoothGattDBAttributeType::BTGATT_DB_SECONDARY_SERVICE;
716 }
717 service_element->attribute_handle = id;
718 const auto& characteristics = service->GetCharacteristics();
719 if (characteristics.size() > 0) {
720 std::string first_id_str = characteristics.front()->GetIdentifier();
721 int first_id =
722 std::stoi(first_id_str.substr(first_id_str.size() - 4), nullptr, 16);
723
724 const auto& descriptors = characteristics.back()->GetDescriptors();
725 std::string last_id_str;
palmer 2016/06/14 23:08:25 Nit: You could reduce these lines: int last_i
puthik_chromium 2016/06/15 18:06:34 Done.
726 if (descriptors.size() > 0) {
727 last_id_str = descriptors.back()->GetIdentifier();
728 } else {
729 last_id_str = characteristics.back()->GetIdentifier();
730 }
731 int last_id =
732 std::stoi(last_id_str.substr(last_id_str.size() - 4), nullptr, 16);
palmer 2016/06/14 23:08:25 This is the 3rd instance of this not-quite-obvious
puthik_chromium 2016/06/15 18:06:34 Done.
733 service_element->start_handle = first_id;
734 service_element->end_handle = last_id;
735 }
736 db.push_back(std::move(service_element));
737
738 for (auto characteristic : characteristics) {
palmer 2016/06/14 23:08:25 Lines 738 – 766 are dense and repetetive. I sugges
puthik_chromium 2016/06/15 18:06:34 I added a helper function to allocate the element
739 mojom::BluetoothGattDBElementPtr characteristic_element =
740 mojom::BluetoothGattDBElement::New();
741 std::string id_str = characteristic->GetIdentifier();
742 int id = std::stoi(id_str.substr(id_str.size() - 4), nullptr, 16);
743 characteristic_element->id = id;
744 characteristic_element->uuid =
745 mojom::BluetoothUUID::From(characteristic->GetUUID());
746 characteristic_element->type =
747 mojom::BluetoothGattDBAttributeType::BTGATT_DB_CHARACTERISTIC;
748 characteristic_element->attribute_handle = id;
749 characteristic_element->properties = characteristic->GetProperties();
750 db.push_back(std::move(characteristic_element));
751
752 for (auto descriptor : characteristic->GetDescriptors()) {
753 mojom::BluetoothGattDBElementPtr descriptor_element =
754 mojom::BluetoothGattDBElement::New();
755 std::string id_str = descriptor->GetIdentifier();
756 int id = std::stoi(id_str.substr(id_str.size() - 4), nullptr, 16);
757 descriptor_element->id = id;
758 descriptor_element->uuid =
759 mojom::BluetoothUUID::From(descriptor->GetUUID());
760 descriptor_element->type =
761 mojom::BluetoothGattDBAttributeType::BTGATT_DB_DESCRIPTOR;
762 descriptor_element->attribute_handle = id;
763 db.push_back(std::move(descriptor_element));
764 }
765 }
766 }
767
768 arc_bridge_service()->bluetooth_instance()->OnGetGattDB(
769 std::move(remote_addr), std::move(db));
770 }
771
772 BluetoothRemoteGattCharacteristic* ArcBluetoothBridge::FindGattCharacteristic(
773 mojom::BluetoothAddressPtr remote_addr,
774 mojom::BluetoothGattServiceIDPtr service_id,
775 mojom::BluetoothGattIDPtr char_id) const {
776 DCHECK(remote_addr);
777 DCHECK(service_id);
778 DCHECK(char_id);
779
780 BluetoothDevice* device =
781 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>());
782 if (!device)
783 return nullptr;
784
785 BluetoothUUID serv_uuid = service_id->id->uuid.To<BluetoothUUID>();
786 const auto& services = device->GetGattServices();
787 auto service_it = std::find_if(
788 services.begin(), services.end(),
789 [&](BluetoothRemoteGattService* s) { return s->GetUUID() == serv_uuid; });
790 if (service_it == services.end())
791 return nullptr;
792
793 BluetoothUUID char_uuid = char_id->uuid.To<BluetoothUUID>();
794 const auto& characteristics = (*service_it)->GetCharacteristics();
795 auto characteristic_it =
796 std::find_if(characteristics.begin(), characteristics.end(),
797 [&](BluetoothRemoteGattCharacteristic* c) {
798 return c->GetUUID() == char_uuid;
799 });
800 if (characteristic_it == characteristics.end())
801 return nullptr;
802 return *characteristic_it;
803 }
804
805 BluetoothRemoteGattDescriptor* ArcBluetoothBridge::FindGattDescriptor(
806 mojom::BluetoothAddressPtr remote_addr,
807 mojom::BluetoothGattServiceIDPtr service_id,
808 mojom::BluetoothGattIDPtr char_id,
809 mojom::BluetoothGattIDPtr desc_id) const {
810 BluetoothRemoteGattCharacteristic* characteristic = FindGattCharacteristic(
811 std::move(remote_addr), std::move(service_id), std::move(char_id));
812
813 if (!characteristic)
814 return nullptr;
815
816 BluetoothUUID desc_uuid = desc_id->uuid.To<BluetoothUUID>();
817 const auto& descriptors = characteristic->GetDescriptors();
818 auto descriptor_it = std::find_if(descriptors.begin(), descriptors.end(),
819 [&](BluetoothRemoteGattDescriptor* d) {
820 return d->GetUUID() == desc_uuid;
821 });
822 if (descriptor_it == descriptors.end())
823 return nullptr;
824 return *descriptor_it;
825 }
826
827 // Same callback for both ReadGattCharacteristic and ReadGattDescriptor
828 void ArcBluetoothBridge::OnGattReadDone(
829 const GattReadCallback& callback,
830 const std::vector<uint8_t>& result) const {
831 mojom::BluetoothGattValuePtr gattValue = mojom::BluetoothGattValue::New();
832 gattValue->status = mojom::BluetoothGattStatus::GATT_SUCCESS;
833 gattValue->value = mojo::Array<uint8_t>::From(result);
834 callback.Run(std::move(gattValue));
835 }
836
837 void ArcBluetoothBridge::OnGattReadError(
838 const GattReadCallback& callback,
839 BluetoothGattService::GattErrorCode error_code) const {
840 mojom::BluetoothGattValuePtr gattValue = mojom::BluetoothGattValue::New();
841 gattValue->status = mojo::ConvertTo<mojom::BluetoothGattStatus>(error_code);
842 gattValue->value = nullptr;
843
844 callback.Run(std::move(gattValue));
845 }
846
847 // same callback for both WriteGattCharacteristic and WriteGattDescriptor
848 void ArcBluetoothBridge::OnGattWriteDone(
849 const GattWriteCallback& callback) const {
850 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
851 }
852
853 void ArcBluetoothBridge::OnGattWriteError(
854 const GattWriteCallback& callback,
855 BluetoothGattService::GattErrorCode error_code) const {
856 callback.Run(mojo::ConvertTo<mojom::BluetoothGattStatus>(error_code));
857 }
858
859 void ArcBluetoothBridge::ReadGattCharacteristic(
860 mojom::BluetoothAddressPtr remote_addr,
861 mojom::BluetoothGattServiceIDPtr service_id,
862 mojom::BluetoothGattIDPtr char_id,
863 const ReadGattCharacteristicCallback& callback) {
864 BluetoothRemoteGattCharacteristic* characteristic = FindGattCharacteristic(
865 std::move(remote_addr), std::move(service_id), std::move(char_id));
866
867 DCHECK(characteristic);
868
869 DCHECK(characteristic->GetPermissions() &
870 (BluetoothGattCharacteristic::Permission::PERMISSION_READ |
871 BluetoothGattCharacteristic::Permission::PERMISSION_READ_ENCRYPTED |
872 BluetoothGattCharacteristic::Permission::
873 PERMISSION_READ_ENCRYPTED_AUTHENTICATED));
874
875 characteristic->ReadRemoteCharacteristic(
876 base::Bind(&ArcBluetoothBridge::OnGattReadDone,
877 weak_factory_.GetWeakPtr(), callback),
878 base::Bind(&ArcBluetoothBridge::OnGattReadError,
879 weak_factory_.GetWeakPtr(), callback));
880 }
881
882 void ArcBluetoothBridge::WriteGattCharacteristic(
883 mojom::BluetoothAddressPtr remote_addr,
884 mojom::BluetoothGattServiceIDPtr service_id,
885 mojom::BluetoothGattIDPtr char_id,
886 mojom::BluetoothGattValuePtr value,
887 const WriteGattCharacteristicCallback& callback) {
888 BluetoothRemoteGattCharacteristic* characteristic = FindGattCharacteristic(
889 std::move(remote_addr), std::move(service_id), std::move(char_id));
890
891 DCHECK(characteristic);
892
893 DCHECK(characteristic->GetPermissions() &
894 (BluetoothGattCharacteristic::Permission::PERMISSION_WRITE |
895 BluetoothGattCharacteristic::Permission::PERMISSION_WRITE_ENCRYPTED |
896 BluetoothGattCharacteristic::Permission::
897 PERMISSION_WRITE_ENCRYPTED_AUTHENTICATED));
898
899 characteristic->WriteRemoteCharacteristic(
900 value->value.To<std::vector<uint8_t>>(),
901 base::Bind(&ArcBluetoothBridge::OnGattWriteDone,
902 weak_factory_.GetWeakPtr(), callback),
903 base::Bind(&ArcBluetoothBridge::OnGattWriteError,
904 weak_factory_.GetWeakPtr(), callback));
905 }
906
907 void ArcBluetoothBridge::ReadGattDescriptor(
908 mojom::BluetoothAddressPtr remote_addr,
909 mojom::BluetoothGattServiceIDPtr service_id,
910 mojom::BluetoothGattIDPtr char_id,
911 mojom::BluetoothGattIDPtr desc_id,
912 const ReadGattDescriptorCallback& callback) {
913 BluetoothRemoteGattDescriptor* descriptor =
914 FindGattDescriptor(std::move(remote_addr), std::move(service_id),
915 std::move(char_id), std::move(desc_id));
916 DCHECK(descriptor);
917
918 DCHECK(descriptor->GetPermissions() &
919 (BluetoothGattCharacteristic::Permission::PERMISSION_READ |
920 BluetoothGattCharacteristic::Permission::PERMISSION_READ_ENCRYPTED |
921 BluetoothGattCharacteristic::Permission::
922 PERMISSION_READ_ENCRYPTED_AUTHENTICATED));
923
924 descriptor->ReadRemoteDescriptor(
925 base::Bind(&ArcBluetoothBridge::OnGattReadDone,
926 weak_factory_.GetWeakPtr(), callback),
927 base::Bind(&ArcBluetoothBridge::OnGattReadError,
928 weak_factory_.GetWeakPtr(), callback));
929 }
930
931 void ArcBluetoothBridge::WriteGattDescriptor(
932 mojom::BluetoothAddressPtr remote_addr,
933 mojom::BluetoothGattServiceIDPtr service_id,
934 mojom::BluetoothGattIDPtr char_id,
935 mojom::BluetoothGattIDPtr desc_id,
936 mojom::BluetoothGattValuePtr value,
937 const WriteGattDescriptorCallback& callback) {
938 BluetoothRemoteGattDescriptor* descriptor =
939 FindGattDescriptor(std::move(remote_addr), std::move(service_id),
940 std::move(char_id), std::move(desc_id));
941 DCHECK(descriptor);
942
943 DCHECK(descriptor->GetPermissions() &
944 (BluetoothGattCharacteristic::Permission::PERMISSION_WRITE |
945 BluetoothGattCharacteristic::Permission::PERMISSION_WRITE_ENCRYPTED |
946 BluetoothGattCharacteristic::Permission::
947 PERMISSION_WRITE_ENCRYPTED_AUTHENTICATED));
948
949 descriptor->WriteRemoteDescriptor(
950 value->value.To<std::vector<uint8_t>>(),
951 base::Bind(&ArcBluetoothBridge::OnGattWriteDone,
952 weak_factory_.GetWeakPtr(), callback),
953 base::Bind(&ArcBluetoothBridge::OnGattWriteError,
954 weak_factory_.GetWeakPtr(), callback));
955 }
956
957 void ArcBluetoothBridge::OnGattNotifyStartDone(
958 const RegisterForGattNotificationCallback& callback,
959 const std::string char_string_id,
960 std::unique_ptr<BluetoothGattNotifySession> notify_session) {
961 notification_session_[char_string_id] = std::move(notify_session);
962 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
963 }
964
965 void ArcBluetoothBridge::OnGattNotifyStartError(
966 const RegisterForGattNotificationCallback& callback,
967 BluetoothGattService::GattErrorCode error_code) const {
968 callback.Run(mojo::ConvertTo<mojom::BluetoothGattStatus>(error_code));
969 }
970
971 void ArcBluetoothBridge::OnGattNotifyStopDone(
972 const DeregisterForGattNotificationCallback& callback) const {
973 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
974 }
975
976 void ArcBluetoothBridge::RegisterForGattNotification(
977 mojom::BluetoothAddressPtr remote_addr,
978 mojom::BluetoothGattServiceIDPtr service_id,
979 mojom::BluetoothGattIDPtr char_id,
980 const RegisterForGattNotificationCallback& callback) {
981 BluetoothRemoteGattCharacteristic* characteristic = FindGattCharacteristic(
982 std::move(remote_addr), std::move(service_id), std::move(char_id));
983
984 if (!characteristic) {
985 LOG(WARNING) << __func__ << " Characteristic is not existed.";
986 return;
987 }
988
989 if (characteristic->IsNotifying()) {
990 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
991 return;
992 }
993
994 characteristic->StartNotifySession(
995 base::Bind(&ArcBluetoothBridge::OnGattNotifyStartDone,
996 weak_factory_.GetWeakPtr(), callback,
997 characteristic->GetIdentifier()),
998 base::Bind(&ArcBluetoothBridge::OnGattNotifyStartError,
999 weak_factory_.GetWeakPtr(), callback));
1000 }
1001
1002 void ArcBluetoothBridge::DeregisterForGattNotification(
1003 mojom::BluetoothAddressPtr remote_addr,
1004 mojom::BluetoothGattServiceIDPtr service_id,
1005 mojom::BluetoothGattIDPtr char_id,
1006 const DeregisterForGattNotificationCallback& callback) {
1007 BluetoothRemoteGattCharacteristic* characteristic = FindGattCharacteristic(
1008 std::move(remote_addr), std::move(service_id), std::move(char_id));
1009
1010 if (!characteristic) {
1011 LOG(WARNING) << __func__ << " Characteristic is not existed.";
1012 return;
1013 }
1014
1015 if (!characteristic->IsNotifying()) {
1016 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
1017 return;
1018 }
1019
1020 std::string char_id_str = characteristic->GetIdentifier();
1021 std::unique_ptr<BluetoothGattNotifySession> notify =
1022 std::move(notification_session_[char_id_str]);
1023 notification_session_.erase(char_id_str);
1024 notify->Stop(base::Bind(&ArcBluetoothBridge::OnGattNotifyStopDone,
1025 weak_factory_.GetWeakPtr(), callback));
1026 }
1027
1028 void ArcBluetoothBridge::ReadRemoteRssi(
1029 mojom::BluetoothAddressPtr remote_addr,
1030 const ReadRemoteRssiCallback& callback) {
1031 BluetoothDevice* device =
1032 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>());
1033 int rssi = device->GetInquiryRSSI();
1034 callback.Run(rssi);
1035 }
1036
464 void ArcBluetoothBridge::OnDiscoveryError() { 1037 void ArcBluetoothBridge::OnDiscoveryError() {
465 LOG(WARNING) << "failed to change discovery state"; 1038 LOG(WARNING) << "failed to change discovery state";
466 } 1039 }
467 1040
468 void ArcBluetoothBridge::OnPairing(mojom::BluetoothAddressPtr addr) const { 1041 void ArcBluetoothBridge::OnPairing(mojom::BluetoothAddressPtr addr) const {
469 if (!HasBluetoothInstance()) 1042 if (!HasBluetoothInstance())
470 return; 1043 return;
471 1044
472 arc_bridge_service()->bluetooth_instance()->OnBondStateChanged( 1045 arc_bridge_service()->bluetooth_instance()->OnBondStateChanged(
473 mojom::BluetoothStatus::SUCCESS, std::move(addr), 1046 mojom::BluetoothStatus::SUCCESS, std::move(addr),
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
536 } 1109 }
537 if (type == mojom::BluetoothPropertyType::ALL || 1110 if (type == mojom::BluetoothPropertyType::ALL ||
538 type == mojom::BluetoothPropertyType::BDADDR) { 1111 type == mojom::BluetoothPropertyType::BDADDR) {
539 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); 1112 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New();
540 btp->set_bdaddr(mojom::BluetoothAddress::From(device->GetAddress())); 1113 btp->set_bdaddr(mojom::BluetoothAddress::From(device->GetAddress()));
541 properties.push_back(std::move(btp)); 1114 properties.push_back(std::move(btp));
542 } 1115 }
543 if (type == mojom::BluetoothPropertyType::ALL || 1116 if (type == mojom::BluetoothPropertyType::ALL ||
544 type == mojom::BluetoothPropertyType::UUIDS) { 1117 type == mojom::BluetoothPropertyType::UUIDS) {
545 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); 1118 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New();
546 std::vector<device::BluetoothUUID> uuids = device->GetUUIDs(); 1119 std::vector<BluetoothUUID> uuids = device->GetUUIDs();
547 mojo::Array<mojom::BluetoothUUIDPtr> uuid_results = 1120 mojo::Array<mojom::BluetoothUUIDPtr> uuid_results =
548 mojo::Array<mojom::BluetoothUUIDPtr>::New(0); 1121 mojo::Array<mojom::BluetoothUUIDPtr>::New(0);
549 1122
550 for (size_t i = 0; i < uuids.size(); i++) { 1123 for (auto& uuid : uuids) {
551 uuid_results.push_back(mojom::BluetoothUUID::From(uuids[i])); 1124 uuid_results.push_back(mojom::BluetoothUUID::From(uuid));
552 } 1125 }
553 1126
554 btp->set_uuids(std::move(uuid_results)); 1127 btp->set_uuids(std::move(uuid_results));
555 properties.push_back(std::move(btp)); 1128 properties.push_back(std::move(btp));
556 } 1129 }
557 if (type == mojom::BluetoothPropertyType::ALL || 1130 if (type == mojom::BluetoothPropertyType::ALL ||
558 type == mojom::BluetoothPropertyType::CLASS_OF_DEVICE) { 1131 type == mojom::BluetoothPropertyType::CLASS_OF_DEVICE) {
559 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); 1132 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New();
560 btp->set_device_class(device->GetBluetoothClass()); 1133 btp->set_device_class(device->GetBluetoothClass());
561 properties.push_back(std::move(btp)); 1134 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)); 1208 properties.push_back(std::move(btp));
636 } 1209 }
637 if (type == mojom::BluetoothPropertyType::ALL || 1210 if (type == mojom::BluetoothPropertyType::ALL ||
638 type == mojom::BluetoothPropertyType::ADAPTER_BONDED_DEVICES) { 1211 type == mojom::BluetoothPropertyType::ADAPTER_BONDED_DEVICES) {
639 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); 1212 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New();
640 BluetoothAdapter::DeviceList devices = bluetooth_adapter_->GetDevices(); 1213 BluetoothAdapter::DeviceList devices = bluetooth_adapter_->GetDevices();
641 1214
642 mojo::Array<mojom::BluetoothAddressPtr> bonded_devices = 1215 mojo::Array<mojom::BluetoothAddressPtr> bonded_devices =
643 mojo::Array<mojom::BluetoothAddressPtr>::New(0); 1216 mojo::Array<mojom::BluetoothAddressPtr>::New(0);
644 1217
645 for (size_t i = 0; i < devices.size(); i++) { 1218 for (auto device : devices) {
646 if (!devices[i]->IsPaired()) 1219 if (device->IsPaired())
647 continue; 1220 continue;
648 1221
649 mojom::BluetoothAddressPtr addr = 1222 mojom::BluetoothAddressPtr addr =
650 mojom::BluetoothAddress::From(devices[i]->GetAddress()); 1223 mojom::BluetoothAddress::From(device->GetAddress());
651 bonded_devices.push_back(std::move(addr)); 1224 bonded_devices.push_back(std::move(addr));
652 } 1225 }
653 1226
654 btp->set_bonded_devices(std::move(bonded_devices)); 1227 btp->set_bonded_devices(std::move(bonded_devices));
655 properties.push_back(std::move(btp)); 1228 properties.push_back(std::move(btp));
656 } 1229 }
657 if (type == mojom::BluetoothPropertyType::ALL || 1230 if (type == mojom::BluetoothPropertyType::ALL ||
658 type == mojom::BluetoothPropertyType::ADAPTER_DISCOVERY_TIMEOUT) { 1231 type == mojom::BluetoothPropertyType::ADAPTER_DISCOVERY_TIMEOUT) {
659 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); 1232 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New();
660 btp->set_discovery_timeout(120); 1233 btp->set_discovery_timeout(120);
661 properties.push_back(std::move(btp)); 1234 properties.push_back(std::move(btp));
662 } 1235 }
663 1236
664 return properties; 1237 return properties;
665 } 1238 }
666 1239
1240 // Android support 5 types of Advertising Data.
1241 // However Chrome didn't expose AdvertiseFlag and ManufacturerData.
1242 // So we will only expose local_name, service_uuids and service_data.
1243 // TODO(crbug.com/618442) Make Chrome expose missing data.
1244 mojo::Array<mojom::BluetoothAdvertisingDataPtr>
1245 ArcBluetoothBridge::GetAdvertisingData(BluetoothDevice* device) const {
1246 mojo::Array<mojom::BluetoothAdvertisingDataPtr> advertising_data;
1247
1248 // LocalName
1249 mojom::BluetoothAdvertisingDataPtr local_name =
1250 mojom::BluetoothAdvertisingData::New();
1251 local_name->set_local_name(base::UTF16ToUTF8(device->GetNameForDisplay()));
1252 advertising_data.push_back(std::move(local_name));
1253
1254 // ServiceUuid
1255 BluetoothDevice::UUIDList uuid_list = device->GetServiceDataUUIDs();
1256 if (uuid_list.size() > 0) {
1257 mojom::BluetoothAdvertisingDataPtr service_uuids =
1258 mojom::BluetoothAdvertisingData::New();
1259 service_uuids->set_service_uuids(
1260 mojo::Array<mojom::BluetoothUUIDPtr>::From(uuid_list));
1261 advertising_data.push_back(std::move(service_uuids));
1262 }
1263
1264 // Service data
1265 for (auto& uuid : uuid_list) {
1266 base::BinaryValue* data = device->GetServiceData(uuid);
1267 if (data->GetSize() == 0)
1268 continue;
1269 std::string data_str;
1270 if (!data->GetAsString(&data_str))
1271 continue;
1272
1273 mojom::BluetoothAdvertisingDataPtr service_data_element =
1274 mojom::BluetoothAdvertisingData::New();
1275 mojom::BluetoothServiceDataPtr service_data =
1276 mojom::BluetoothServiceData::New();
1277
1278 std::string uuid_str = uuid.canonical_value();
1279 // Convert xxxxyyyy-xxxx-xxxx-xxxx-xxxxxxxxxxxx to int16 yyyy
1280 service_data->uuid_16bit = std::stoi(uuid_str.substr(4, 4), nullptr, 16);
1281 for (auto& c : data_str) {
1282 service_data->data.push_back(c);
1283 }
1284 service_data_element->set_service_data(std::move(service_data));
1285 advertising_data.push_back(std::move(service_data_element));
1286 }
1287
1288 return advertising_data;
1289 }
1290
667 void ArcBluetoothBridge::SendCachedDevicesFound() const { 1291 void ArcBluetoothBridge::SendCachedDevicesFound() const {
668 // Send devices that have already been discovered, but aren't connected. 1292 // Send devices that have already been discovered, but aren't connected.
669 if (!HasBluetoothInstance()) 1293 if (!HasBluetoothInstance())
670 return; 1294 return;
671 1295
672 BluetoothAdapter::DeviceList devices = bluetooth_adapter_->GetDevices(); 1296 BluetoothAdapter::DeviceList devices = bluetooth_adapter_->GetDevices();
673 for (size_t i = 0; i < devices.size(); i++) { 1297 for (auto device : devices) {
674 if (devices[i]->IsPaired()) 1298 if (device->IsPaired())
675 continue; 1299 continue;
676 1300
677 mojo::Array<mojom::BluetoothPropertyPtr> properties = 1301 mojo::Array<mojom::BluetoothPropertyPtr> properties =
678 GetDeviceProperties(mojom::BluetoothPropertyType::ALL, devices[i]); 1302 GetDeviceProperties(mojom::BluetoothPropertyType::ALL, device);
679 1303
680 arc_bridge_service()->bluetooth_instance()->OnDeviceFound( 1304 arc_bridge_service()->bluetooth_instance()->OnDeviceFound(
681 std::move(properties)); 1305 std::move(properties));
1306
1307 if (arc_bridge_service()->bluetooth_version() >= kMinBtleVersion) {
1308 mojom::BluetoothAddressPtr addr =
1309 mojom::BluetoothAddress::From(device->GetAddress());
1310 int rssi = device->GetInquiryRSSI();
1311 mojo::Array<mojom::BluetoothAdvertisingDataPtr> adv_data =
1312 GetAdvertisingData(device);
1313 arc_bridge_service()->bluetooth_instance()->OnLEDeviceFound(
1314 std::move(addr), rssi, std::move(adv_data));
1315 }
682 } 1316 }
683 } 1317 }
684 1318
685 bool ArcBluetoothBridge::HasBluetoothInstance() const { 1319 bool ArcBluetoothBridge::HasBluetoothInstance() const {
686 if (!arc_bridge_service()->bluetooth_instance()) { 1320 if (!arc_bridge_service()->bluetooth_instance()) {
687 LOG(WARNING) << "no Bluetooth instance available"; 1321 LOG(WARNING) << "no Bluetooth instance available";
688 return false; 1322 return false;
689 } 1323 }
690 1324
691 return true; 1325 return true;
692 } 1326 }
693 1327
694 void ArcBluetoothBridge::SendCachedPairedDevices() const { 1328 void ArcBluetoothBridge::SendCachedPairedDevices() const {
695 DCHECK(bluetooth_adapter_); 1329 DCHECK(bluetooth_adapter_);
1330 if (!HasBluetoothInstance())
1331 return;
696 1332
697 BluetoothAdapter::DeviceList devices = bluetooth_adapter_->GetDevices(); 1333 BluetoothAdapter::DeviceList devices = bluetooth_adapter_->GetDevices();
698 for (BluetoothDevice* device : devices) { 1334 for (auto device : devices) {
699 if (!device->IsPaired()) 1335 if (!device->IsPaired())
700 continue; 1336 continue;
701 1337
702 mojo::Array<mojom::BluetoothPropertyPtr> properties = 1338 mojo::Array<mojom::BluetoothPropertyPtr> properties =
703 GetDeviceProperties(mojom::BluetoothPropertyType::ALL, device); 1339 GetDeviceProperties(mojom::BluetoothPropertyType::ALL, device);
704 1340
705 arc_bridge_service()->bluetooth_instance()->OnDeviceFound( 1341 arc_bridge_service()->bluetooth_instance()->OnDeviceFound(
706 std::move(properties)); 1342 std::move(properties));
707 1343
708 mojom::BluetoothAddressPtr addr = 1344 mojom::BluetoothAddressPtr addr =
709 mojom::BluetoothAddress::From(device->GetAddress()); 1345 mojom::BluetoothAddress::From(device->GetAddress());
710 1346
1347 if (arc_bridge_service()->bluetooth_version() >= kMinBtleVersion) {
1348 int rssi = device->GetInquiryRSSI();
1349 mojo::Array<mojom::BluetoothAdvertisingDataPtr> adv_data =
1350 GetAdvertisingData(device);
1351 arc_bridge_service()->bluetooth_instance()->OnLEDeviceFound(
1352 addr->Clone(), rssi, std::move(adv_data));
1353 }
1354
711 // OnBondStateChanged must be called with mojom::BluetoothBondState::BONDING 1355 // OnBondStateChanged must be called with mojom::BluetoothBondState::BONDING
712 // to 1356 // to
713 // make sure the bond state machine on Android is ready to take the 1357 // 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 1358 // pair-done event. Otherwise the pair-done event will be dropped as an
715 // invalid change of paired status. 1359 // invalid change of paired status.
716 OnPairing(addr->Clone()); 1360 OnPairing(addr->Clone());
717 OnPairedDone(std::move(addr)); 1361 OnPairedDone(std::move(addr));
718 } 1362 }
719 } 1363 }
720 1364
721 } // namespace arc 1365 } // 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