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 <bluetooth/bluetooth.h> | 7 #include <bluetooth/bluetooth.h> |
8 #include <fcntl.h> | 8 #include <fcntl.h> |
9 #include <stddef.h> | 9 #include <stddef.h> |
10 #include <sys/socket.h> | 10 #include <sys/socket.h> |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
74 constexpr int32_t kMaxGattAttributeHandle = 0xFFFF; | 74 constexpr int32_t kMaxGattAttributeHandle = 0xFFFF; |
75 // Bluetooth Specification Version 4.2 Vol 3 Part F Section 3.2.9 | 75 // Bluetooth Specification Version 4.2 Vol 3 Part F Section 3.2.9 |
76 // The maximum length of an attribute value shall be 512 octets. | 76 // The maximum length of an attribute value shall be 512 octets. |
77 constexpr int kMaxGattAttributeLength = 512; | 77 constexpr int kMaxGattAttributeLength = 512; |
78 // Copied from Android at system/bt/stack/btm/btm_ble_int.h | 78 // Copied from Android at system/bt/stack/btm/btm_ble_int.h |
79 // https://goo.gl/k7PM6u | 79 // https://goo.gl/k7PM6u |
80 constexpr uint16_t kAndroidMBluetoothVersionNumber = 95; | 80 constexpr uint16_t kAndroidMBluetoothVersionNumber = 95; |
81 constexpr uint16_t kMaxAdvertisement = 5; | 81 constexpr uint16_t kMaxAdvertisement = 5; |
82 // Bluetooth SDP Service Class ID List Attribute identifier | 82 // Bluetooth SDP Service Class ID List Attribute identifier |
83 constexpr uint16_t kServiceClassIDListAttributeID = 0x0001; | 83 constexpr uint16_t kServiceClassIDListAttributeID = 0x0001; |
84 // Timeout for Bluetooth Discovery (scan) | |
85 constexpr base::TimeDelta kDiscoveryTimeout = base::TimeDelta::FromSeconds(120); | |
Rahul Chaturvedi
2016/09/21 22:40:26
Mention in comment why 2 minutes.
puthik_chromium
2016/09/22 00:26:55
Done.
| |
86 // From https://www.bluetooth.com/specifications/assigned-numbers/baseband | |
87 // The Class of Device for generic computer. | |
88 constexpr uint32_t kBluetoothComputerClass = 0x100; | |
84 | 89 |
85 using GattStatusCallback = | 90 using GattStatusCallback = |
86 base::Callback<void(arc::mojom::BluetoothGattStatus)>; | 91 base::Callback<void(arc::mojom::BluetoothGattStatus)>; |
87 using GattReadCallback = | 92 using GattReadCallback = |
88 base::Callback<void(arc::mojom::BluetoothGattValuePtr)>; | 93 base::Callback<void(arc::mojom::BluetoothGattValuePtr)>; |
89 using CreateSdpRecordCallback = | 94 using CreateSdpRecordCallback = |
90 base::Callback<void(arc::mojom::BluetoothCreateSdpRecordResultPtr)>; | 95 base::Callback<void(arc::mojom::BluetoothCreateSdpRecordResultPtr)>; |
91 using RemoveSdpRecordCallback = | 96 using RemoveSdpRecordCallback = |
92 base::Callback<void(arc::mojom::BluetoothStatus)>; | 97 base::Callback<void(arc::mojom::BluetoothStatus)>; |
93 | 98 |
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
303 // ready, we should register it now. | 308 // ready, we should register it now. |
304 if (bluetooth_adapter_ && !bluetooth_adapter_->HasObserver(this)) | 309 if (bluetooth_adapter_ && !bluetooth_adapter_->HasObserver(this)) |
305 bluetooth_adapter_->AddObserver(this); | 310 bluetooth_adapter_->AddObserver(this); |
306 } | 311 } |
307 | 312 |
308 void ArcBluetoothBridge::OnInstanceClosed() { | 313 void ArcBluetoothBridge::OnInstanceClosed() { |
309 if (bluetooth_adapter_) | 314 if (bluetooth_adapter_) |
310 bluetooth_adapter_->RemoveObserver(this); | 315 bluetooth_adapter_->RemoveObserver(this); |
311 } | 316 } |
312 | 317 |
313 void ArcBluetoothBridge::AdapterPoweredChanged(BluetoothAdapter* adapter, | |
314 bool powered) { | |
315 // TODO(smbarber): Invoke EnableAdapter or DisableAdapter via ARC bridge | |
316 // service. | |
317 } | |
318 | |
319 void ArcBluetoothBridge::DeviceAdded(BluetoothAdapter* adapter, | 318 void ArcBluetoothBridge::DeviceAdded(BluetoothAdapter* adapter, |
320 BluetoothDevice* device) { | 319 BluetoothDevice* device) { |
321 auto* bluetooth_instance = | 320 auto* bluetooth_instance = |
322 arc_bridge_service()->bluetooth()->GetInstanceForMethod("OnDeviceFound"); | 321 arc_bridge_service()->bluetooth()->GetInstanceForMethod("OnDeviceFound"); |
323 if (!bluetooth_instance) | 322 if (!bluetooth_instance) |
324 return; | 323 return; |
325 | 324 |
326 mojo::Array<mojom::BluetoothPropertyPtr> properties = | 325 mojo::Array<mojom::BluetoothPropertyPtr> properties = |
327 GetDeviceProperties(mojom::BluetoothPropertyType::ALL, device); | 326 GetDeviceProperties(mojom::BluetoothPropertyType::ALL, device); |
328 | 327 |
(...skipping 472 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
801 void ArcBluetoothBridge::SetRemoteDeviceProperty( | 800 void ArcBluetoothBridge::SetRemoteDeviceProperty( |
802 mojom::BluetoothAddressPtr remote_addr, | 801 mojom::BluetoothAddressPtr remote_addr, |
803 mojom::BluetoothPropertyPtr property) { | 802 mojom::BluetoothPropertyPtr property) { |
804 DCHECK(bluetooth_adapter_); | 803 DCHECK(bluetooth_adapter_); |
805 auto* bluetooth_instance = | 804 auto* bluetooth_instance = |
806 arc_bridge_service()->bluetooth()->GetInstanceForMethod( | 805 arc_bridge_service()->bluetooth()->GetInstanceForMethod( |
807 "OnRemoteDeviceProperties"); | 806 "OnRemoteDeviceProperties"); |
808 if (!bluetooth_instance) | 807 if (!bluetooth_instance) |
809 return; | 808 return; |
810 | 809 |
811 // TODO(smbarber): Implement SetRemoteDeviceProperty | 810 // Unsupported. Only used by Android hidden API, BluetoothDevice.SetAlias(). |
811 // And only Android Settings App / Android TV / NFC used that. | |
812 bluetooth_instance->OnRemoteDeviceProperties( | 812 bluetooth_instance->OnRemoteDeviceProperties( |
813 mojom::BluetoothStatus::FAIL, std::move(remote_addr), | 813 mojom::BluetoothStatus::UNSUPPORTED, std::move(remote_addr), |
814 mojo::Array<mojom::BluetoothPropertyPtr>::New(0)); | 814 mojo::Array<mojom::BluetoothPropertyPtr>::New(0)); |
815 } | 815 } |
816 | 816 |
817 void ArcBluetoothBridge::GetRemoteServiceRecord( | 817 void ArcBluetoothBridge::GetRemoteServiceRecord( |
818 mojom::BluetoothAddressPtr remote_addr, | 818 mojom::BluetoothAddressPtr remote_addr, |
819 const BluetoothUUID& uuid) { | 819 const BluetoothUUID& uuid) { |
820 // TODO(smbarber): Implement GetRemoteServiceRecord | 820 // TODO(smbarber): Implement GetRemoteServiceRecord |
821 } | 821 } |
822 | 822 |
823 void ArcBluetoothBridge::GetRemoteServices( | 823 void ArcBluetoothBridge::GetRemoteServices( |
824 mojom::BluetoothAddressPtr remote_addr) { | 824 mojom::BluetoothAddressPtr remote_addr) { |
825 // TODO(smbarber): Implement GetRemoteServices | 825 // TODO(smbarber): Implement GetRemoteServices |
826 } | 826 } |
827 | 827 |
828 void ArcBluetoothBridge::StartDiscovery() { | 828 void ArcBluetoothBridge::StartDiscovery() { |
829 DCHECK(bluetooth_adapter_); | 829 DCHECK(bluetooth_adapter_); |
830 // TODO(smbarber): Add timeout | 830 DCHECK(CalledOnValidThread()); |
831 | |
831 if (discovery_session_) { | 832 if (discovery_session_) { |
832 LOG(ERROR) << "Discovery session already running; leaving alone"; | 833 LOG(ERROR) << "Discovery session already running; Reset timeout."; |
834 discovery_off_timer_.Start(FROM_HERE, kDiscoveryTimeout, | |
835 base::Bind(&ArcBluetoothBridge::CancelDiscovery, | |
836 weak_factory_.GetWeakPtr())); | |
833 SendCachedDevicesFound(); | 837 SendCachedDevicesFound(); |
834 return; | 838 return; |
835 } | 839 } |
836 | 840 |
837 bluetooth_adapter_->StartDiscoverySession( | 841 bluetooth_adapter_->StartDiscoverySession( |
838 base::Bind(&ArcBluetoothBridge::OnDiscoveryStarted, | 842 base::Bind(&ArcBluetoothBridge::OnDiscoveryStarted, |
839 weak_factory_.GetWeakPtr()), | 843 weak_factory_.GetWeakPtr()), |
840 base::Bind(&ArcBluetoothBridge::OnDiscoveryError, | 844 base::Bind(&ArcBluetoothBridge::OnDiscoveryError, |
841 weak_factory_.GetWeakPtr())); | 845 weak_factory_.GetWeakPtr())); |
842 } | 846 } |
(...skipping 24 matching lines...) Expand all Loading... | |
867 const base::Callback<void(mojom::BluetoothAdapterState)>& callback) const { | 871 const base::Callback<void(mojom::BluetoothAdapterState)>& callback) const { |
868 LOG(WARNING) << "failed to change power state"; | 872 LOG(WARNING) << "failed to change power state"; |
869 | 873 |
870 callback.Run(bluetooth_adapter_->IsPowered() | 874 callback.Run(bluetooth_adapter_->IsPowered() |
871 ? mojom::BluetoothAdapterState::ON | 875 ? mojom::BluetoothAdapterState::ON |
872 : mojom::BluetoothAdapterState::OFF); | 876 : mojom::BluetoothAdapterState::OFF); |
873 } | 877 } |
874 | 878 |
875 void ArcBluetoothBridge::OnDiscoveryStarted( | 879 void ArcBluetoothBridge::OnDiscoveryStarted( |
876 std::unique_ptr<BluetoothDiscoverySession> session) { | 880 std::unique_ptr<BluetoothDiscoverySession> session) { |
881 DCHECK(CalledOnValidThread()); | |
882 | |
877 auto* bluetooth_instance = | 883 auto* bluetooth_instance = |
878 arc_bridge_service()->bluetooth()->GetInstanceForMethod( | 884 arc_bridge_service()->bluetooth()->GetInstanceForMethod( |
879 "OnDiscoveryStateChanged"); | 885 "OnDiscoveryStateChanged"); |
880 if (!bluetooth_instance) | 886 if (!bluetooth_instance) |
881 return; | 887 return; |
882 | 888 |
883 discovery_session_ = std::move(session); | 889 discovery_session_ = std::move(session); |
884 | 890 |
891 discovery_off_timer_.Start(FROM_HERE, kDiscoveryTimeout, | |
892 base::Bind(&ArcBluetoothBridge::CancelDiscovery, | |
893 weak_factory_.GetWeakPtr())); | |
894 | |
885 bluetooth_instance->OnDiscoveryStateChanged( | 895 bluetooth_instance->OnDiscoveryStateChanged( |
886 mojom::BluetoothDiscoveryState::STARTED); | 896 mojom::BluetoothDiscoveryState::STARTED); |
887 | 897 |
888 SendCachedDevicesFound(); | 898 SendCachedDevicesFound(); |
889 } | 899 } |
890 | 900 |
891 void ArcBluetoothBridge::OnDiscoveryStopped() { | 901 void ArcBluetoothBridge::OnDiscoveryStopped() { |
892 auto* bluetooth_instance = | 902 auto* bluetooth_instance = |
893 arc_bridge_service()->bluetooth()->GetInstanceForMethod( | 903 arc_bridge_service()->bluetooth()->GetInstanceForMethod( |
894 "OnDiscoveryStateChanged"); | 904 "OnDiscoveryStateChanged"); |
895 if (!bluetooth_instance) | 905 if (!bluetooth_instance) |
896 return; | 906 return; |
897 | 907 |
898 discovery_session_.reset(); | 908 discovery_session_.reset(); |
909 discovery_off_timer_.Stop(); | |
899 | 910 |
900 bluetooth_instance->OnDiscoveryStateChanged( | 911 bluetooth_instance->OnDiscoveryStateChanged( |
901 mojom::BluetoothDiscoveryState::STOPPED); | 912 mojom::BluetoothDiscoveryState::STOPPED); |
902 } | 913 } |
903 | 914 |
904 void ArcBluetoothBridge::CreateBond(mojom::BluetoothAddressPtr addr, | 915 void ArcBluetoothBridge::CreateBond(mojom::BluetoothAddressPtr addr, |
905 int32_t transport) { | 916 int32_t transport) { |
906 std::string addr_str = addr->To<std::string>(); | 917 std::string addr_str = addr->To<std::string>(); |
907 BluetoothDevice* device = bluetooth_adapter_->GetDevice(addr_str); | 918 BluetoothDevice* device = bluetooth_adapter_->GetDevice(addr_str); |
908 if (!device || !device->IsPairable()) { | 919 if (!device || !device->IsPairable()) { |
(...skipping 845 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1754 } | 1765 } |
1755 if (type == mojom::BluetoothPropertyType::ALL || | 1766 if (type == mojom::BluetoothPropertyType::ALL || |
1756 type == mojom::BluetoothPropertyType::BDADDR) { | 1767 type == mojom::BluetoothPropertyType::BDADDR) { |
1757 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); | 1768 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); |
1758 btp->set_bdaddr( | 1769 btp->set_bdaddr( |
1759 mojom::BluetoothAddress::From(bluetooth_adapter_->GetAddress())); | 1770 mojom::BluetoothAddress::From(bluetooth_adapter_->GetAddress())); |
1760 properties.push_back(std::move(btp)); | 1771 properties.push_back(std::move(btp)); |
1761 } | 1772 } |
1762 if (type == mojom::BluetoothPropertyType::ALL || | 1773 if (type == mojom::BluetoothPropertyType::ALL || |
1763 type == mojom::BluetoothPropertyType::UUIDS) { | 1774 type == mojom::BluetoothPropertyType::UUIDS) { |
1764 // TODO(smbarber): Fill in once GetUUIDs is available for the adapter. | 1775 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); |
1776 btp->set_uuids( | |
1777 mojo::Array<BluetoothUUID>::From(bluetooth_adapter_->GetUUIDs())); | |
1778 properties.push_back(std::move(btp)); | |
1765 } | 1779 } |
1766 if (type == mojom::BluetoothPropertyType::ALL || | 1780 if (type == mojom::BluetoothPropertyType::ALL || |
1767 type == mojom::BluetoothPropertyType::CLASS_OF_DEVICE) { | 1781 type == mojom::BluetoothPropertyType::CLASS_OF_DEVICE) { |
1768 // TODO(smbarber): Populate with the actual adapter class | |
1769 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); | 1782 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); |
1770 btp->set_device_class(0); | 1783 btp->set_device_class(kBluetoothComputerClass); |
1771 properties.push_back(std::move(btp)); | 1784 properties.push_back(std::move(btp)); |
1772 } | 1785 } |
1773 if (type == mojom::BluetoothPropertyType::ALL || | 1786 if (type == mojom::BluetoothPropertyType::ALL || |
1774 type == mojom::BluetoothPropertyType::TYPE_OF_DEVICE) { | 1787 type == mojom::BluetoothPropertyType::TYPE_OF_DEVICE) { |
1775 // TODO(smbarber): Populate with the actual adapter type | 1788 // Assume that all ChromeOS devices are dual mode Bluetooth device. |
1776 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); | 1789 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); |
1777 btp->set_device_type(device::BLUETOOTH_TRANSPORT_DUAL); | 1790 btp->set_device_type(device::BLUETOOTH_TRANSPORT_DUAL); |
1778 properties.push_back(std::move(btp)); | 1791 properties.push_back(std::move(btp)); |
1779 } | 1792 } |
1780 if (type == mojom::BluetoothPropertyType::ALL || | 1793 if (type == mojom::BluetoothPropertyType::ALL || |
1781 type == mojom::BluetoothPropertyType::ADAPTER_SCAN_MODE) { | 1794 type == mojom::BluetoothPropertyType::ADAPTER_SCAN_MODE) { |
1782 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); | 1795 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); |
1783 mojom::BluetoothScanMode scan_mode = mojom::BluetoothScanMode::CONNECTABLE; | 1796 mojom::BluetoothScanMode scan_mode = mojom::BluetoothScanMode::CONNECTABLE; |
1784 | 1797 |
1785 if (bluetooth_adapter_->IsDiscoverable()) | 1798 if (bluetooth_adapter_->IsDiscoverable()) |
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2007 sdp_bluetooth_instance->OnGetSdpRecords( | 2020 sdp_bluetooth_instance->OnGetSdpRecords( |
2008 status, std::move(remote_addr), target_uuid, | 2021 status, std::move(remote_addr), target_uuid, |
2009 mojo::Array<mojom::BluetoothSdpRecordPtr>::New(0)); | 2022 mojo::Array<mojom::BluetoothSdpRecordPtr>::New(0)); |
2010 } | 2023 } |
2011 | 2024 |
2012 bool ArcBluetoothBridge::CalledOnValidThread() { | 2025 bool ArcBluetoothBridge::CalledOnValidThread() { |
2013 return thread_checker_.CalledOnValidThread(); | 2026 return thread_checker_.CalledOnValidThread(); |
2014 } | 2027 } |
2015 | 2028 |
2016 } // namespace arc | 2029 } // namespace arc |
OLD | NEW |