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 // 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 |