Chromium Code Reviews| 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 // Time out for Bluetooth Discovery (scan) | |
| 85 constexpr uint32_t kDiscoveryTimeout = 120; | |
|
Luis Héctor Chávez
2016/09/20 20:23:11
nit: base::TimeDelta::FromSeconds() is constexpr,
puthik_chromium
2016/09/20 20:55:39
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, | |
| 835 base::TimeDelta::FromSeconds(kDiscoveryTimeout), | |
| 836 base::Bind(&ArcBluetoothBridge::CancelDiscovery, | |
| 837 weak_factory_.GetWeakPtr())); | |
| 833 SendCachedDevicesFound(); | 838 SendCachedDevicesFound(); |
| 834 return; | 839 return; |
| 835 } | 840 } |
| 836 | 841 |
| 837 bluetooth_adapter_->StartDiscoverySession( | 842 bluetooth_adapter_->StartDiscoverySession( |
| 838 base::Bind(&ArcBluetoothBridge::OnDiscoveryStarted, | 843 base::Bind(&ArcBluetoothBridge::OnDiscoveryStarted, |
| 839 weak_factory_.GetWeakPtr()), | 844 weak_factory_.GetWeakPtr()), |
| 840 base::Bind(&ArcBluetoothBridge::OnDiscoveryError, | 845 base::Bind(&ArcBluetoothBridge::OnDiscoveryError, |
| 841 weak_factory_.GetWeakPtr())); | 846 weak_factory_.GetWeakPtr())); |
| 842 } | 847 } |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 873 } | 878 } |
| 874 | 879 |
| 875 void ArcBluetoothBridge::OnDiscoveryStarted( | 880 void ArcBluetoothBridge::OnDiscoveryStarted( |
| 876 std::unique_ptr<BluetoothDiscoverySession> session) { | 881 std::unique_ptr<BluetoothDiscoverySession> session) { |
| 877 auto* bluetooth_instance = | 882 auto* bluetooth_instance = |
| 878 arc_bridge_service()->bluetooth()->GetInstanceForMethod( | 883 arc_bridge_service()->bluetooth()->GetInstanceForMethod( |
| 879 "OnDiscoveryStateChanged"); | 884 "OnDiscoveryStateChanged"); |
| 880 if (!bluetooth_instance) | 885 if (!bluetooth_instance) |
| 881 return; | 886 return; |
| 882 | 887 |
| 888 DCHECK(CalledOnValidThread()); | |
|
Luis Héctor Chávez
2016/09/20 20:23:11
nit: move to beginning of function.
puthik_chromium
2016/09/20 20:55:39
Done.
| |
| 889 | |
| 883 discovery_session_ = std::move(session); | 890 discovery_session_ = std::move(session); |
| 884 | 891 |
| 892 discovery_off_timer_.Start(FROM_HERE, | |
| 893 base::TimeDelta::FromSeconds(kDiscoveryTimeout), | |
| 894 base::Bind(&ArcBluetoothBridge::CancelDiscovery, | |
| 895 weak_factory_.GetWeakPtr())); | |
| 896 | |
| 885 bluetooth_instance->OnDiscoveryStateChanged( | 897 bluetooth_instance->OnDiscoveryStateChanged( |
| 886 mojom::BluetoothDiscoveryState::STARTED); | 898 mojom::BluetoothDiscoveryState::STARTED); |
| 887 | 899 |
| 888 SendCachedDevicesFound(); | 900 SendCachedDevicesFound(); |
| 889 } | 901 } |
| 890 | 902 |
| 891 void ArcBluetoothBridge::OnDiscoveryStopped() { | 903 void ArcBluetoothBridge::OnDiscoveryStopped() { |
| 892 auto* bluetooth_instance = | 904 auto* bluetooth_instance = |
| 893 arc_bridge_service()->bluetooth()->GetInstanceForMethod( | 905 arc_bridge_service()->bluetooth()->GetInstanceForMethod( |
| 894 "OnDiscoveryStateChanged"); | 906 "OnDiscoveryStateChanged"); |
| 895 if (!bluetooth_instance) | 907 if (!bluetooth_instance) |
| 896 return; | 908 return; |
| 897 | 909 |
| 898 discovery_session_.reset(); | 910 discovery_session_.reset(); |
| 911 discovery_off_timer_.Stop(); | |
| 899 | 912 |
| 900 bluetooth_instance->OnDiscoveryStateChanged( | 913 bluetooth_instance->OnDiscoveryStateChanged( |
| 901 mojom::BluetoothDiscoveryState::STOPPED); | 914 mojom::BluetoothDiscoveryState::STOPPED); |
| 902 } | 915 } |
| 903 | 916 |
| 904 void ArcBluetoothBridge::CreateBond(mojom::BluetoothAddressPtr addr, | 917 void ArcBluetoothBridge::CreateBond(mojom::BluetoothAddressPtr addr, |
| 905 int32_t transport) { | 918 int32_t transport) { |
| 906 std::string addr_str = addr->To<std::string>(); | 919 std::string addr_str = addr->To<std::string>(); |
| 907 BluetoothDevice* device = bluetooth_adapter_->GetDevice(addr_str); | 920 BluetoothDevice* device = bluetooth_adapter_->GetDevice(addr_str); |
| 908 if (!device || !device->IsPairable()) { | 921 if (!device || !device->IsPairable()) { |
| (...skipping 845 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1754 } | 1767 } |
| 1755 if (type == mojom::BluetoothPropertyType::ALL || | 1768 if (type == mojom::BluetoothPropertyType::ALL || |
| 1756 type == mojom::BluetoothPropertyType::BDADDR) { | 1769 type == mojom::BluetoothPropertyType::BDADDR) { |
| 1757 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); | 1770 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); |
| 1758 btp->set_bdaddr( | 1771 btp->set_bdaddr( |
| 1759 mojom::BluetoothAddress::From(bluetooth_adapter_->GetAddress())); | 1772 mojom::BluetoothAddress::From(bluetooth_adapter_->GetAddress())); |
| 1760 properties.push_back(std::move(btp)); | 1773 properties.push_back(std::move(btp)); |
| 1761 } | 1774 } |
| 1762 if (type == mojom::BluetoothPropertyType::ALL || | 1775 if (type == mojom::BluetoothPropertyType::ALL || |
| 1763 type == mojom::BluetoothPropertyType::UUIDS) { | 1776 type == mojom::BluetoothPropertyType::UUIDS) { |
| 1764 // TODO(smbarber): Fill in once GetUUIDs is available for the adapter. | 1777 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); |
| 1778 btp->set_uuids( | |
| 1779 mojo::Array<BluetoothUUID>::From(bluetooth_adapter_->GetUUIDs())); | |
| 1780 properties.push_back(std::move(btp)); | |
| 1765 } | 1781 } |
| 1766 if (type == mojom::BluetoothPropertyType::ALL || | 1782 if (type == mojom::BluetoothPropertyType::ALL || |
| 1767 type == mojom::BluetoothPropertyType::CLASS_OF_DEVICE) { | 1783 type == mojom::BluetoothPropertyType::CLASS_OF_DEVICE) { |
| 1768 // TODO(smbarber): Populate with the actual adapter class | |
| 1769 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); | 1784 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); |
| 1770 btp->set_device_class(0); | 1785 btp->set_device_class(kBluetoothComputerClass); |
| 1771 properties.push_back(std::move(btp)); | 1786 properties.push_back(std::move(btp)); |
| 1772 } | 1787 } |
| 1773 if (type == mojom::BluetoothPropertyType::ALL || | 1788 if (type == mojom::BluetoothPropertyType::ALL || |
| 1774 type == mojom::BluetoothPropertyType::TYPE_OF_DEVICE) { | 1789 type == mojom::BluetoothPropertyType::TYPE_OF_DEVICE) { |
| 1775 // TODO(smbarber): Populate with the actual adapter type | 1790 // Assume that all ChromeOS devices are dual mode Bluetooth device. |
| 1776 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); | 1791 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); |
| 1777 btp->set_device_type(device::BLUETOOTH_TRANSPORT_DUAL); | 1792 btp->set_device_type(device::BLUETOOTH_TRANSPORT_DUAL); |
| 1778 properties.push_back(std::move(btp)); | 1793 properties.push_back(std::move(btp)); |
| 1779 } | 1794 } |
| 1780 if (type == mojom::BluetoothPropertyType::ALL || | 1795 if (type == mojom::BluetoothPropertyType::ALL || |
| 1781 type == mojom::BluetoothPropertyType::ADAPTER_SCAN_MODE) { | 1796 type == mojom::BluetoothPropertyType::ADAPTER_SCAN_MODE) { |
| 1782 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); | 1797 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); |
| 1783 mojom::BluetoothScanMode scan_mode = mojom::BluetoothScanMode::CONNECTABLE; | 1798 mojom::BluetoothScanMode scan_mode = mojom::BluetoothScanMode::CONNECTABLE; |
| 1784 | 1799 |
| 1785 if (bluetooth_adapter_->IsDiscoverable()) | 1800 if (bluetooth_adapter_->IsDiscoverable()) |
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2007 sdp_bluetooth_instance->OnGetSdpRecords( | 2022 sdp_bluetooth_instance->OnGetSdpRecords( |
| 2008 status, std::move(remote_addr), target_uuid, | 2023 status, std::move(remote_addr), target_uuid, |
| 2009 mojo::Array<mojom::BluetoothSdpRecordPtr>::New(0)); | 2024 mojo::Array<mojom::BluetoothSdpRecordPtr>::New(0)); |
| 2010 } | 2025 } |
| 2011 | 2026 |
| 2012 bool ArcBluetoothBridge::CalledOnValidThread() { | 2027 bool ArcBluetoothBridge::CalledOnValidThread() { |
| 2013 return thread_checker_.CalledOnValidThread(); | 2028 return thread_checker_.CalledOnValidThread(); |
| 2014 } | 2029 } |
| 2015 | 2030 |
| 2016 } // namespace arc | 2031 } // namespace arc |
| OLD | NEW |