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 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
305 // ready, we should register it now. | 305 // ready, we should register it now. |
306 if (bluetooth_adapter_ && !bluetooth_adapter_->HasObserver(this)) | 306 if (bluetooth_adapter_ && !bluetooth_adapter_->HasObserver(this)) |
307 bluetooth_adapter_->AddObserver(this); | 307 bluetooth_adapter_->AddObserver(this); |
308 } | 308 } |
309 | 309 |
310 void ArcBluetoothBridge::OnInstanceClosed() { | 310 void ArcBluetoothBridge::OnInstanceClosed() { |
311 if (bluetooth_adapter_) | 311 if (bluetooth_adapter_) |
312 bluetooth_adapter_->RemoveObserver(this); | 312 bluetooth_adapter_->RemoveObserver(this); |
313 } | 313 } |
314 | 314 |
315 void ArcBluetoothBridge::DeviceAdded(BluetoothAdapter* adapter, | 315 void ArcBluetoothBridge::SendDevice(const BluetoothDevice* device) const { |
316 BluetoothDevice* device) { | |
317 auto* bluetooth_instance = | 316 auto* bluetooth_instance = |
318 arc_bridge_service()->bluetooth()->GetInstanceForMethod("OnDeviceFound"); | 317 arc_bridge_service()->bluetooth()->GetInstanceForMethod("OnDeviceFound"); |
319 if (!bluetooth_instance) | 318 if (!bluetooth_instance) |
320 return; | 319 return; |
321 | 320 |
322 mojo::Array<mojom::BluetoothPropertyPtr> properties = | 321 mojo::Array<mojom::BluetoothPropertyPtr> properties = |
323 GetDeviceProperties(mojom::BluetoothPropertyType::ALL, device); | 322 GetDeviceProperties(mojom::BluetoothPropertyType::ALL, device); |
324 | 323 |
325 bluetooth_instance->OnDeviceFound(std::move(properties)); | 324 bluetooth_instance->OnDeviceFound(std::move(properties)); |
326 | 325 |
327 auto* btle_instance = arc_bridge_service()->bluetooth()->GetInstanceForMethod( | |
328 "OnLEDeviceFound", kMinBtleVersion); | |
329 if (!btle_instance) | |
330 return; | |
331 | 326 |
332 if (!(device->GetType() & device::BLUETOOTH_TRANSPORT_LE)) | 327 if (!(device->GetType() & device::BLUETOOTH_TRANSPORT_LE)) |
333 return; | 328 return; |
334 | 329 |
335 mojom::BluetoothAddressPtr addr = | |
336 mojom::BluetoothAddress::From(device->GetAddress()); | |
337 base::Optional<int8_t> rssi = device->GetInquiryRSSI(); | 330 base::Optional<int8_t> rssi = device->GetInquiryRSSI(); |
338 mojo::Array<mojom::BluetoothAdvertisingDataPtr> adv_data = | 331 mojom::BluetoothAddressPtr addr; |
339 GetAdvertisingData(device); | 332 |
340 btle_instance->OnLEDeviceFound(std::move(addr), | 333 // We only want to send updated advertise data to Android only when we are |
341 rssi.value_or(mojom::kUnknownPower), | 334 // scanning which is checked by the validity of rssi. Here are the 2 cases |
342 std::move(adv_data)); | 335 // that we don't want to send updated advertise data to Android. |
| 336 // 1) Cached found device and 2) rssi became invalid when we stop scanning. |
| 337 if (rssi.has_value()) { |
| 338 auto* btle_instance = |
| 339 arc_bridge_service()->bluetooth()->GetInstanceForMethod( |
| 340 "OnLEDeviceFound", kMinBtleVersion); |
| 341 if (!btle_instance) |
| 342 return; |
| 343 mojo::Array<mojom::BluetoothAdvertisingDataPtr> adv_data = |
| 344 GetAdvertisingData(device); |
| 345 addr = mojom::BluetoothAddress::From(device->GetAddress()); |
| 346 btle_instance->OnLEDeviceFound(std::move(addr), rssi.value(), |
| 347 std::move(adv_data)); |
| 348 } |
343 | 349 |
344 if (!device->IsConnected()) | 350 if (!device->IsConnected()) |
345 return; | 351 return; |
346 | 352 |
347 addr = mojom::BluetoothAddress::From(device->GetAddress()); | 353 addr = mojom::BluetoothAddress::From(device->GetAddress()); |
348 OnGattConnectStateChanged(std::move(addr), true); | 354 OnGattConnectStateChanged(std::move(addr), true); |
349 } | 355 } |
350 | 356 |
| 357 void ArcBluetoothBridge::DeviceAdded(BluetoothAdapter* adapter, |
| 358 BluetoothDevice* device) { |
| 359 SendDevice(device); |
| 360 } |
| 361 |
351 void ArcBluetoothBridge::DeviceChanged(BluetoothAdapter* adapter, | 362 void ArcBluetoothBridge::DeviceChanged(BluetoothAdapter* adapter, |
352 BluetoothDevice* device) { | 363 BluetoothDevice* device) { |
| 364 SendDevice(device); |
| 365 |
353 if (!(device->GetType() & device::BLUETOOTH_TRANSPORT_LE)) | 366 if (!(device->GetType() & device::BLUETOOTH_TRANSPORT_LE)) |
354 return; | 367 return; |
355 | 368 |
356 auto it = gatt_connection_cache_.find(device->GetAddress()); | 369 auto it = gatt_connection_cache_.find(device->GetAddress()); |
357 bool was_connected = it != gatt_connection_cache_.end(); | 370 bool was_connected = it != gatt_connection_cache_.end(); |
358 bool is_connected = device->IsConnected(); | 371 bool is_connected = device->IsConnected(); |
359 | 372 |
360 if (is_connected == was_connected) | 373 if (is_connected == was_connected) |
361 return; | 374 return; |
362 | 375 |
(...skipping 1335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1698 mojom::BluetoothBondState bond_state = mojom::BluetoothBondState::NONE; | 1711 mojom::BluetoothBondState bond_state = mojom::BluetoothBondState::NONE; |
1699 if (device && device->IsPaired()) { | 1712 if (device && device->IsPaired()) { |
1700 bond_state = mojom::BluetoothBondState::BONDED; | 1713 bond_state = mojom::BluetoothBondState::BONDED; |
1701 } | 1714 } |
1702 bluetooth_instance->OnBondStateChanged(mojom::BluetoothStatus::FAIL, | 1715 bluetooth_instance->OnBondStateChanged(mojom::BluetoothStatus::FAIL, |
1703 std::move(addr), bond_state); | 1716 std::move(addr), bond_state); |
1704 } | 1717 } |
1705 | 1718 |
1706 mojo::Array<mojom::BluetoothPropertyPtr> | 1719 mojo::Array<mojom::BluetoothPropertyPtr> |
1707 ArcBluetoothBridge::GetDeviceProperties(mojom::BluetoothPropertyType type, | 1720 ArcBluetoothBridge::GetDeviceProperties(mojom::BluetoothPropertyType type, |
1708 BluetoothDevice* device) const { | 1721 const BluetoothDevice* device) const { |
1709 mojo::Array<mojom::BluetoothPropertyPtr> properties; | 1722 mojo::Array<mojom::BluetoothPropertyPtr> properties; |
1710 | 1723 |
1711 if (!device) { | 1724 if (!device) { |
1712 return properties; | 1725 return properties; |
1713 } | 1726 } |
1714 | 1727 |
1715 if (type == mojom::BluetoothPropertyType::ALL || | 1728 if (type == mojom::BluetoothPropertyType::ALL || |
1716 type == mojom::BluetoothPropertyType::BDNAME) { | 1729 type == mojom::BluetoothPropertyType::BDNAME) { |
1717 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); | 1730 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); |
1718 btp->set_bdname(device->GetName() ? device->GetName().value() : nullptr); | 1731 btp->set_bdname(device->GetName() ? device->GetName().value() : nullptr); |
1719 properties.push_back(std::move(btp)); | 1732 properties.push_back(std::move(btp)); |
1720 } | 1733 } |
1721 if (type == mojom::BluetoothPropertyType::ALL || | 1734 if (type == mojom::BluetoothPropertyType::ALL || |
1722 type == mojom::BluetoothPropertyType::BDADDR) { | 1735 type == mojom::BluetoothPropertyType::BDADDR) { |
1723 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); | 1736 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); |
1724 btp->set_bdaddr(mojom::BluetoothAddress::From(device->GetAddress())); | 1737 btp->set_bdaddr(mojom::BluetoothAddress::From(device->GetAddress())); |
1725 properties.push_back(std::move(btp)); | 1738 properties.push_back(std::move(btp)); |
1726 } | 1739 } |
1727 if (type == mojom::BluetoothPropertyType::ALL || | 1740 if (type == mojom::BluetoothPropertyType::ALL || |
1728 type == mojom::BluetoothPropertyType::UUIDS) { | 1741 type == mojom::BluetoothPropertyType::UUIDS) { |
1729 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); | |
1730 BluetoothDevice::UUIDSet uuids = device->GetUUIDs(); | 1742 BluetoothDevice::UUIDSet uuids = device->GetUUIDs(); |
1731 btp->set_uuids(std::vector<BluetoothUUID>(uuids.begin(), uuids.end())); | 1743 if (uuids.size() > 0) { |
1732 properties.push_back(std::move(btp)); | 1744 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); |
| 1745 btp->set_uuids(std::vector<BluetoothUUID>(uuids.begin(), uuids.end())); |
| 1746 properties.push_back(std::move(btp)); |
| 1747 } |
1733 } | 1748 } |
1734 if (type == mojom::BluetoothPropertyType::ALL || | 1749 if (type == mojom::BluetoothPropertyType::ALL || |
1735 type == mojom::BluetoothPropertyType::CLASS_OF_DEVICE) { | 1750 type == mojom::BluetoothPropertyType::CLASS_OF_DEVICE) { |
1736 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); | 1751 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); |
1737 btp->set_device_class(device->GetBluetoothClass()); | 1752 btp->set_device_class(device->GetBluetoothClass()); |
1738 properties.push_back(std::move(btp)); | 1753 properties.push_back(std::move(btp)); |
1739 } | 1754 } |
1740 if (type == mojom::BluetoothPropertyType::ALL || | 1755 if (type == mojom::BluetoothPropertyType::ALL || |
1741 type == mojom::BluetoothPropertyType::TYPE_OF_DEVICE) { | 1756 type == mojom::BluetoothPropertyType::TYPE_OF_DEVICE) { |
1742 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); | 1757 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); |
1743 btp->set_device_type(device->GetType()); | 1758 btp->set_device_type(device->GetType()); |
1744 properties.push_back(std::move(btp)); | 1759 properties.push_back(std::move(btp)); |
1745 } | 1760 } |
1746 if (type == mojom::BluetoothPropertyType::ALL || | 1761 if (type == mojom::BluetoothPropertyType::ALL || |
1747 type == mojom::BluetoothPropertyType::REMOTE_FRIENDLY_NAME) { | 1762 type == mojom::BluetoothPropertyType::REMOTE_FRIENDLY_NAME) { |
1748 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); | 1763 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); |
1749 btp->set_remote_friendly_name( | 1764 btp->set_remote_friendly_name( |
1750 mojo::String::From(base::UTF16ToUTF8(device->GetNameForDisplay()))); | 1765 mojo::String::From(base::UTF16ToUTF8(device->GetNameForDisplay()))); |
1751 properties.push_back(std::move(btp)); | 1766 properties.push_back(std::move(btp)); |
1752 } | 1767 } |
1753 if (type == mojom::BluetoothPropertyType::ALL || | 1768 if (type == mojom::BluetoothPropertyType::ALL || |
1754 type == mojom::BluetoothPropertyType::REMOTE_RSSI) { | 1769 type == mojom::BluetoothPropertyType::REMOTE_RSSI) { |
1755 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); | |
1756 base::Optional<int8_t> rssi = device->GetInquiryRSSI(); | 1770 base::Optional<int8_t> rssi = device->GetInquiryRSSI(); |
1757 btp->set_remote_rssi(rssi.value_or(mojom::kUnknownPower)); | 1771 if (rssi.has_value()) { |
1758 properties.push_back(std::move(btp)); | 1772 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); |
| 1773 btp->set_remote_rssi(rssi.value()); |
| 1774 properties.push_back(std::move(btp)); |
| 1775 } |
1759 } | 1776 } |
1760 // TODO(smbarber): Add remote version info | 1777 // TODO(smbarber): Add remote version info |
1761 | 1778 |
1762 return properties; | 1779 return properties; |
1763 } | 1780 } |
1764 | 1781 |
1765 mojo::Array<mojom::BluetoothPropertyPtr> | 1782 mojo::Array<mojom::BluetoothPropertyPtr> |
1766 ArcBluetoothBridge::GetAdapterProperties( | 1783 ArcBluetoothBridge::GetAdapterProperties( |
1767 mojom::BluetoothPropertyType type) const { | 1784 mojom::BluetoothPropertyType type) const { |
1768 mojo::Array<mojom::BluetoothPropertyPtr> properties; | 1785 mojo::Array<mojom::BluetoothPropertyPtr> properties; |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1862 return properties; | 1879 return properties; |
1863 } | 1880 } |
1864 | 1881 |
1865 // Android support 5 types of Advertising Data. | 1882 // Android support 5 types of Advertising Data. |
1866 // However Chrome didn't expose AdvertiseFlag and ManufacturerData. | 1883 // However Chrome didn't expose AdvertiseFlag and ManufacturerData. |
1867 // So we will only expose local_name, service_uuids and service_data. | 1884 // So we will only expose local_name, service_uuids and service_data. |
1868 // Note that we need to use UUID 16 bits in service_data section | 1885 // Note that we need to use UUID 16 bits in service_data section |
1869 // because Android does not support UUID 128 bits there. | 1886 // because Android does not support UUID 128 bits there. |
1870 // TODO(crbug.com/618442) Make Chrome expose missing data. | 1887 // TODO(crbug.com/618442) Make Chrome expose missing data. |
1871 mojo::Array<mojom::BluetoothAdvertisingDataPtr> | 1888 mojo::Array<mojom::BluetoothAdvertisingDataPtr> |
1872 ArcBluetoothBridge::GetAdvertisingData(BluetoothDevice* device) const { | 1889 ArcBluetoothBridge::GetAdvertisingData(const BluetoothDevice* device) const { |
1873 mojo::Array<mojom::BluetoothAdvertisingDataPtr> advertising_data; | 1890 mojo::Array<mojom::BluetoothAdvertisingDataPtr> advertising_data; |
1874 | 1891 |
1875 // LocalName | 1892 // LocalName |
1876 mojom::BluetoothAdvertisingDataPtr local_name = | 1893 mojom::BluetoothAdvertisingDataPtr local_name = |
1877 mojom::BluetoothAdvertisingData::New(); | 1894 mojom::BluetoothAdvertisingData::New(); |
1878 local_name->set_local_name(device->GetName() ? device->GetName().value() | 1895 local_name->set_local_name(device->GetName() ? device->GetName().value() |
1879 : nullptr); | 1896 : nullptr); |
1880 advertising_data.push_back(std::move(local_name)); | 1897 advertising_data.push_back(std::move(local_name)); |
1881 | 1898 |
1882 // ServiceUuid | 1899 // ServiceUuid |
(...skipping 23 matching lines...) Expand all Loading... |
1906 service_data->data.Swap(&data_copy); | 1923 service_data->data.Swap(&data_copy); |
1907 | 1924 |
1908 service_data_element->set_service_data(std::move(service_data)); | 1925 service_data_element->set_service_data(std::move(service_data)); |
1909 advertising_data.push_back(std::move(service_data_element)); | 1926 advertising_data.push_back(std::move(service_data_element)); |
1910 } | 1927 } |
1911 | 1928 |
1912 return advertising_data; | 1929 return advertising_data; |
1913 } | 1930 } |
1914 | 1931 |
1915 void ArcBluetoothBridge::SendCachedDevicesFound() const { | 1932 void ArcBluetoothBridge::SendCachedDevicesFound() const { |
| 1933 DCHECK(bluetooth_adapter_); |
| 1934 |
1916 // Send devices that have already been discovered, but aren't connected. | 1935 // Send devices that have already been discovered, but aren't connected. |
1917 auto* bluetooth_instance = | |
1918 arc_bridge_service()->bluetooth()->GetInstanceForMethod("OnDeviceFound"); | |
1919 if (!bluetooth_instance) | |
1920 return; | |
1921 auto* btle_instance = arc_bridge_service()->bluetooth()->GetInstanceForMethod( | |
1922 "OnLEDeviceFound", kMinBtleVersion); | |
1923 | |
1924 BluetoothAdapter::DeviceList devices = bluetooth_adapter_->GetDevices(); | 1936 BluetoothAdapter::DeviceList devices = bluetooth_adapter_->GetDevices(); |
1925 for (auto* device : devices) { | 1937 for (auto* device : devices) { |
1926 if (device->IsPaired()) | 1938 if (device->IsPaired()) |
1927 continue; | 1939 continue; |
1928 | 1940 |
1929 mojo::Array<mojom::BluetoothPropertyPtr> properties = | 1941 SendDevice(device); |
1930 GetDeviceProperties(mojom::BluetoothPropertyType::ALL, device); | |
1931 | |
1932 bluetooth_instance->OnDeviceFound(std::move(properties)); | |
1933 | |
1934 if (btle_instance) { | |
1935 mojom::BluetoothAddressPtr addr = | |
1936 mojom::BluetoothAddress::From(device->GetAddress()); | |
1937 base::Optional<int8_t> rssi = device->GetInquiryRSSI(); | |
1938 mojo::Array<mojom::BluetoothAdvertisingDataPtr> adv_data = | |
1939 GetAdvertisingData(device); | |
1940 btle_instance->OnLEDeviceFound(std::move(addr), | |
1941 rssi.value_or(mojom::kUnknownPower), | |
1942 std::move(adv_data)); | |
1943 } | |
1944 } | 1942 } |
1945 } | 1943 } |
1946 | 1944 |
1947 void ArcBluetoothBridge::SendCachedPairedDevices() const { | 1945 void ArcBluetoothBridge::SendCachedPairedDevices() const { |
1948 DCHECK(bluetooth_adapter_); | 1946 DCHECK(bluetooth_adapter_); |
1949 auto* bluetooth_instance = | |
1950 arc_bridge_service()->bluetooth()->GetInstanceForMethod("OnDeviceFound"); | |
1951 if (!bluetooth_instance) | |
1952 return; | |
1953 auto* btle_instance = arc_bridge_service()->bluetooth()->GetInstanceForMethod( | |
1954 "OnLEDeviceFound", kMinBtleVersion); | |
1955 | 1947 |
1956 BluetoothAdapter::DeviceList devices = bluetooth_adapter_->GetDevices(); | 1948 BluetoothAdapter::DeviceList devices = bluetooth_adapter_->GetDevices(); |
1957 for (auto* device : devices) { | 1949 for (auto* device : devices) { |
1958 if (!device->IsPaired()) | 1950 if (!device->IsPaired()) |
1959 continue; | 1951 continue; |
1960 | 1952 |
1961 mojo::Array<mojom::BluetoothPropertyPtr> properties = | 1953 SendDevice(device); |
1962 GetDeviceProperties(mojom::BluetoothPropertyType::ALL, device); | |
1963 | |
1964 bluetooth_instance->OnDeviceFound(std::move(properties)); | |
1965 | |
1966 mojom::BluetoothAddressPtr addr = | |
1967 mojom::BluetoothAddress::From(device->GetAddress()); | |
1968 | |
1969 if (btle_instance) { | |
1970 base::Optional<int8_t> rssi = device->GetInquiryRSSI(); | |
1971 mojo::Array<mojom::BluetoothAdvertisingDataPtr> adv_data = | |
1972 GetAdvertisingData(device); | |
1973 btle_instance->OnLEDeviceFound(addr->Clone(), | |
1974 rssi.value_or(mojom::kUnknownPower), | |
1975 std::move(adv_data)); | |
1976 } | |
1977 | 1954 |
1978 // OnBondStateChanged must be called with mojom::BluetoothBondState::BONDING | 1955 // OnBondStateChanged must be called with mojom::BluetoothBondState::BONDING |
1979 // to make sure the bond state machine on Android is ready to take the | 1956 // to make sure the bond state machine on Android is ready to take the |
1980 // pair-done event. Otherwise the pair-done event will be dropped as an | 1957 // pair-done event. Otherwise the pair-done event will be dropped as an |
1981 // invalid change of paired status. | 1958 // invalid change of paired status. |
| 1959 mojom::BluetoothAddressPtr addr = |
| 1960 mojom::BluetoothAddress::From(device->GetAddress()); |
1982 OnPairing(addr->Clone()); | 1961 OnPairing(addr->Clone()); |
1983 OnPairedDone(std::move(addr)); | 1962 OnPairedDone(std::move(addr)); |
1984 } | 1963 } |
1985 } | 1964 } |
1986 | 1965 |
1987 void ArcBluetoothBridge::OnGetServiceRecordsDone( | 1966 void ArcBluetoothBridge::OnGetServiceRecordsDone( |
1988 mojom::BluetoothAddressPtr remote_addr, | 1967 mojom::BluetoothAddressPtr remote_addr, |
1989 const BluetoothUUID& target_uuid, | 1968 const BluetoothUUID& target_uuid, |
1990 const std::vector<bluez::BluetoothServiceRecordBlueZ>& records_bluez) { | 1969 const std::vector<bluez::BluetoothServiceRecordBlueZ>& records_bluez) { |
1991 auto* sdp_bluetooth_instance = | 1970 auto* sdp_bluetooth_instance = |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2027 sdp_bluetooth_instance->OnGetSdpRecords( | 2006 sdp_bluetooth_instance->OnGetSdpRecords( |
2028 status, std::move(remote_addr), target_uuid, | 2007 status, std::move(remote_addr), target_uuid, |
2029 mojo::Array<mojom::BluetoothSdpRecordPtr>::New(0)); | 2008 mojo::Array<mojom::BluetoothSdpRecordPtr>::New(0)); |
2030 } | 2009 } |
2031 | 2010 |
2032 bool ArcBluetoothBridge::CalledOnValidThread() { | 2011 bool ArcBluetoothBridge::CalledOnValidThread() { |
2033 return thread_checker_.CalledOnValidThread(); | 2012 return thread_checker_.CalledOnValidThread(); |
2034 } | 2013 } |
2035 | 2014 |
2036 } // namespace arc | 2015 } // namespace arc |
OLD | NEW |