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 1463 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1826 mojom::BluetoothBondState bond_state = mojom::BluetoothBondState::NONE; | 1839 mojom::BluetoothBondState bond_state = mojom::BluetoothBondState::NONE; |
1827 if (device && device->IsPaired()) { | 1840 if (device && device->IsPaired()) { |
1828 bond_state = mojom::BluetoothBondState::BONDED; | 1841 bond_state = mojom::BluetoothBondState::BONDED; |
1829 } | 1842 } |
1830 bluetooth_instance->OnBondStateChanged(mojom::BluetoothStatus::FAIL, | 1843 bluetooth_instance->OnBondStateChanged(mojom::BluetoothStatus::FAIL, |
1831 std::move(addr), bond_state); | 1844 std::move(addr), bond_state); |
1832 } | 1845 } |
1833 | 1846 |
1834 mojo::Array<mojom::BluetoothPropertyPtr> | 1847 mojo::Array<mojom::BluetoothPropertyPtr> |
1835 ArcBluetoothBridge::GetDeviceProperties(mojom::BluetoothPropertyType type, | 1848 ArcBluetoothBridge::GetDeviceProperties(mojom::BluetoothPropertyType type, |
1836 BluetoothDevice* device) const { | 1849 const BluetoothDevice* device) const { |
1837 mojo::Array<mojom::BluetoothPropertyPtr> properties; | 1850 mojo::Array<mojom::BluetoothPropertyPtr> properties; |
1838 | 1851 |
1839 if (!device) { | 1852 if (!device) { |
1840 return properties; | 1853 return properties; |
1841 } | 1854 } |
1842 | 1855 |
1843 if (type == mojom::BluetoothPropertyType::ALL || | 1856 if (type == mojom::BluetoothPropertyType::ALL || |
1844 type == mojom::BluetoothPropertyType::BDNAME) { | 1857 type == mojom::BluetoothPropertyType::BDNAME) { |
1845 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); | 1858 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); |
1846 btp->set_bdname(device->GetName() ? device->GetName().value() : nullptr); | 1859 btp->set_bdname(device->GetName() ? device->GetName().value() : nullptr); |
1847 properties.push_back(std::move(btp)); | 1860 properties.push_back(std::move(btp)); |
1848 } | 1861 } |
1849 if (type == mojom::BluetoothPropertyType::ALL || | 1862 if (type == mojom::BluetoothPropertyType::ALL || |
1850 type == mojom::BluetoothPropertyType::BDADDR) { | 1863 type == mojom::BluetoothPropertyType::BDADDR) { |
1851 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); | 1864 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); |
1852 btp->set_bdaddr(mojom::BluetoothAddress::From(device->GetAddress())); | 1865 btp->set_bdaddr(mojom::BluetoothAddress::From(device->GetAddress())); |
1853 properties.push_back(std::move(btp)); | 1866 properties.push_back(std::move(btp)); |
1854 } | 1867 } |
1855 if (type == mojom::BluetoothPropertyType::ALL || | 1868 if (type == mojom::BluetoothPropertyType::ALL || |
1856 type == mojom::BluetoothPropertyType::UUIDS) { | 1869 type == mojom::BluetoothPropertyType::UUIDS) { |
1857 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); | |
1858 BluetoothDevice::UUIDSet uuids = device->GetUUIDs(); | 1870 BluetoothDevice::UUIDSet uuids = device->GetUUIDs(); |
1859 btp->set_uuids(std::vector<BluetoothUUID>(uuids.begin(), uuids.end())); | 1871 if (uuids.size() > 0) { |
1860 properties.push_back(std::move(btp)); | 1872 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); |
| 1873 btp->set_uuids(std::vector<BluetoothUUID>(uuids.begin(), uuids.end())); |
| 1874 properties.push_back(std::move(btp)); |
| 1875 } |
1861 } | 1876 } |
1862 if (type == mojom::BluetoothPropertyType::ALL || | 1877 if (type == mojom::BluetoothPropertyType::ALL || |
1863 type == mojom::BluetoothPropertyType::CLASS_OF_DEVICE) { | 1878 type == mojom::BluetoothPropertyType::CLASS_OF_DEVICE) { |
1864 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); | 1879 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); |
1865 btp->set_device_class(device->GetBluetoothClass()); | 1880 btp->set_device_class(device->GetBluetoothClass()); |
1866 properties.push_back(std::move(btp)); | 1881 properties.push_back(std::move(btp)); |
1867 } | 1882 } |
1868 if (type == mojom::BluetoothPropertyType::ALL || | 1883 if (type == mojom::BluetoothPropertyType::ALL || |
1869 type == mojom::BluetoothPropertyType::TYPE_OF_DEVICE) { | 1884 type == mojom::BluetoothPropertyType::TYPE_OF_DEVICE) { |
1870 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); | 1885 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); |
1871 btp->set_device_type(device->GetType()); | 1886 btp->set_device_type(device->GetType()); |
1872 properties.push_back(std::move(btp)); | 1887 properties.push_back(std::move(btp)); |
1873 } | 1888 } |
1874 if (type == mojom::BluetoothPropertyType::ALL || | 1889 if (type == mojom::BluetoothPropertyType::ALL || |
1875 type == mojom::BluetoothPropertyType::REMOTE_FRIENDLY_NAME) { | 1890 type == mojom::BluetoothPropertyType::REMOTE_FRIENDLY_NAME) { |
1876 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); | 1891 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); |
1877 btp->set_remote_friendly_name( | 1892 btp->set_remote_friendly_name( |
1878 mojo::String::From(base::UTF16ToUTF8(device->GetNameForDisplay()))); | 1893 mojo::String::From(base::UTF16ToUTF8(device->GetNameForDisplay()))); |
1879 properties.push_back(std::move(btp)); | 1894 properties.push_back(std::move(btp)); |
1880 } | 1895 } |
1881 if (type == mojom::BluetoothPropertyType::ALL || | 1896 if (type == mojom::BluetoothPropertyType::ALL || |
1882 type == mojom::BluetoothPropertyType::REMOTE_RSSI) { | 1897 type == mojom::BluetoothPropertyType::REMOTE_RSSI) { |
1883 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); | |
1884 base::Optional<int8_t> rssi = device->GetInquiryRSSI(); | 1898 base::Optional<int8_t> rssi = device->GetInquiryRSSI(); |
1885 btp->set_remote_rssi(rssi.value_or(mojom::kUnknownPower)); | 1899 if (rssi.has_value()) { |
1886 properties.push_back(std::move(btp)); | 1900 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); |
| 1901 btp->set_remote_rssi(rssi.value()); |
| 1902 properties.push_back(std::move(btp)); |
| 1903 } |
1887 } | 1904 } |
1888 // TODO(smbarber): Add remote version info | 1905 // TODO(smbarber): Add remote version info |
1889 | 1906 |
1890 return properties; | 1907 return properties; |
1891 } | 1908 } |
1892 | 1909 |
1893 mojo::Array<mojom::BluetoothPropertyPtr> | 1910 mojo::Array<mojom::BluetoothPropertyPtr> |
1894 ArcBluetoothBridge::GetAdapterProperties( | 1911 ArcBluetoothBridge::GetAdapterProperties( |
1895 mojom::BluetoothPropertyType type) const { | 1912 mojom::BluetoothPropertyType type) const { |
1896 mojo::Array<mojom::BluetoothPropertyPtr> properties; | 1913 mojo::Array<mojom::BluetoothPropertyPtr> properties; |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1990 return properties; | 2007 return properties; |
1991 } | 2008 } |
1992 | 2009 |
1993 // Android support 5 types of Advertising Data. | 2010 // Android support 5 types of Advertising Data. |
1994 // However Chrome didn't expose AdvertiseFlag and ManufacturerData. | 2011 // However Chrome didn't expose AdvertiseFlag and ManufacturerData. |
1995 // So we will only expose local_name, service_uuids and service_data. | 2012 // So we will only expose local_name, service_uuids and service_data. |
1996 // Note that we need to use UUID 16 bits in service_data section | 2013 // Note that we need to use UUID 16 bits in service_data section |
1997 // because Android does not support UUID 128 bits there. | 2014 // because Android does not support UUID 128 bits there. |
1998 // TODO(crbug.com/618442) Make Chrome expose missing data. | 2015 // TODO(crbug.com/618442) Make Chrome expose missing data. |
1999 mojo::Array<mojom::BluetoothAdvertisingDataPtr> | 2016 mojo::Array<mojom::BluetoothAdvertisingDataPtr> |
2000 ArcBluetoothBridge::GetAdvertisingData(BluetoothDevice* device) const { | 2017 ArcBluetoothBridge::GetAdvertisingData(const BluetoothDevice* device) const { |
2001 mojo::Array<mojom::BluetoothAdvertisingDataPtr> advertising_data; | 2018 mojo::Array<mojom::BluetoothAdvertisingDataPtr> advertising_data; |
2002 | 2019 |
2003 // LocalName | 2020 // LocalName |
2004 mojom::BluetoothAdvertisingDataPtr local_name = | 2021 mojom::BluetoothAdvertisingDataPtr local_name = |
2005 mojom::BluetoothAdvertisingData::New(); | 2022 mojom::BluetoothAdvertisingData::New(); |
2006 local_name->set_local_name(device->GetName() ? device->GetName().value() | 2023 local_name->set_local_name(device->GetName() ? device->GetName().value() |
2007 : nullptr); | 2024 : nullptr); |
2008 advertising_data.push_back(std::move(local_name)); | 2025 advertising_data.push_back(std::move(local_name)); |
2009 | 2026 |
2010 // ServiceUuid | 2027 // ServiceUuid |
(...skipping 23 matching lines...) Expand all Loading... |
2034 service_data->data.Swap(&data_copy); | 2051 service_data->data.Swap(&data_copy); |
2035 | 2052 |
2036 service_data_element->set_service_data(std::move(service_data)); | 2053 service_data_element->set_service_data(std::move(service_data)); |
2037 advertising_data.push_back(std::move(service_data_element)); | 2054 advertising_data.push_back(std::move(service_data_element)); |
2038 } | 2055 } |
2039 | 2056 |
2040 return advertising_data; | 2057 return advertising_data; |
2041 } | 2058 } |
2042 | 2059 |
2043 void ArcBluetoothBridge::SendCachedDevicesFound() const { | 2060 void ArcBluetoothBridge::SendCachedDevicesFound() const { |
| 2061 DCHECK(bluetooth_adapter_); |
| 2062 |
2044 // Send devices that have already been discovered, but aren't connected. | 2063 // Send devices that have already been discovered, but aren't connected. |
2045 auto* bluetooth_instance = | |
2046 arc_bridge_service()->bluetooth()->GetInstanceForMethod("OnDeviceFound"); | |
2047 if (!bluetooth_instance) | |
2048 return; | |
2049 auto* btle_instance = arc_bridge_service()->bluetooth()->GetInstanceForMethod( | |
2050 "OnLEDeviceFound", kMinBtleVersion); | |
2051 | |
2052 BluetoothAdapter::DeviceList devices = bluetooth_adapter_->GetDevices(); | 2064 BluetoothAdapter::DeviceList devices = bluetooth_adapter_->GetDevices(); |
2053 for (auto* device : devices) { | 2065 for (auto* device : devices) { |
2054 if (device->IsPaired()) | 2066 if (device->IsPaired()) |
2055 continue; | 2067 continue; |
2056 | 2068 |
2057 mojo::Array<mojom::BluetoothPropertyPtr> properties = | 2069 SendDevice(device); |
2058 GetDeviceProperties(mojom::BluetoothPropertyType::ALL, device); | |
2059 | |
2060 bluetooth_instance->OnDeviceFound(std::move(properties)); | |
2061 | |
2062 if (btle_instance) { | |
2063 mojom::BluetoothAddressPtr addr = | |
2064 mojom::BluetoothAddress::From(device->GetAddress()); | |
2065 base::Optional<int8_t> rssi = device->GetInquiryRSSI(); | |
2066 mojo::Array<mojom::BluetoothAdvertisingDataPtr> adv_data = | |
2067 GetAdvertisingData(device); | |
2068 btle_instance->OnLEDeviceFound(std::move(addr), | |
2069 rssi.value_or(mojom::kUnknownPower), | |
2070 std::move(adv_data)); | |
2071 } | |
2072 } | 2070 } |
2073 } | 2071 } |
2074 | 2072 |
2075 void ArcBluetoothBridge::SendCachedPairedDevices() const { | 2073 void ArcBluetoothBridge::SendCachedPairedDevices() const { |
2076 DCHECK(bluetooth_adapter_); | 2074 DCHECK(bluetooth_adapter_); |
2077 auto* bluetooth_instance = | |
2078 arc_bridge_service()->bluetooth()->GetInstanceForMethod("OnDeviceFound"); | |
2079 if (!bluetooth_instance) | |
2080 return; | |
2081 auto* btle_instance = arc_bridge_service()->bluetooth()->GetInstanceForMethod( | |
2082 "OnLEDeviceFound", kMinBtleVersion); | |
2083 | 2075 |
2084 BluetoothAdapter::DeviceList devices = bluetooth_adapter_->GetDevices(); | 2076 BluetoothAdapter::DeviceList devices = bluetooth_adapter_->GetDevices(); |
2085 for (auto* device : devices) { | 2077 for (auto* device : devices) { |
2086 if (!device->IsPaired()) | 2078 if (!device->IsPaired()) |
2087 continue; | 2079 continue; |
2088 | 2080 |
2089 mojo::Array<mojom::BluetoothPropertyPtr> properties = | 2081 SendDevice(device); |
2090 GetDeviceProperties(mojom::BluetoothPropertyType::ALL, device); | |
2091 | |
2092 bluetooth_instance->OnDeviceFound(std::move(properties)); | |
2093 | |
2094 mojom::BluetoothAddressPtr addr = | |
2095 mojom::BluetoothAddress::From(device->GetAddress()); | |
2096 | |
2097 if (btle_instance) { | |
2098 base::Optional<int8_t> rssi = device->GetInquiryRSSI(); | |
2099 mojo::Array<mojom::BluetoothAdvertisingDataPtr> adv_data = | |
2100 GetAdvertisingData(device); | |
2101 btle_instance->OnLEDeviceFound(addr->Clone(), | |
2102 rssi.value_or(mojom::kUnknownPower), | |
2103 std::move(adv_data)); | |
2104 } | |
2105 | 2082 |
2106 // OnBondStateChanged must be called with mojom::BluetoothBondState::BONDING | 2083 // OnBondStateChanged must be called with mojom::BluetoothBondState::BONDING |
2107 // to make sure the bond state machine on Android is ready to take the | 2084 // to make sure the bond state machine on Android is ready to take the |
2108 // pair-done event. Otherwise the pair-done event will be dropped as an | 2085 // pair-done event. Otherwise the pair-done event will be dropped as an |
2109 // invalid change of paired status. | 2086 // invalid change of paired status. |
| 2087 mojom::BluetoothAddressPtr addr = |
| 2088 mojom::BluetoothAddress::From(device->GetAddress()); |
2110 OnPairing(addr->Clone()); | 2089 OnPairing(addr->Clone()); |
2111 OnPairedDone(std::move(addr)); | 2090 OnPairedDone(std::move(addr)); |
2112 } | 2091 } |
2113 } | 2092 } |
2114 | 2093 |
2115 void ArcBluetoothBridge::OnGetServiceRecordsDone( | 2094 void ArcBluetoothBridge::OnGetServiceRecordsDone( |
2116 mojom::BluetoothAddressPtr remote_addr, | 2095 mojom::BluetoothAddressPtr remote_addr, |
2117 const BluetoothUUID& target_uuid, | 2096 const BluetoothUUID& target_uuid, |
2118 const std::vector<bluez::BluetoothServiceRecordBlueZ>& records_bluez) { | 2097 const std::vector<bluez::BluetoothServiceRecordBlueZ>& records_bluez) { |
2119 auto* sdp_bluetooth_instance = | 2098 auto* sdp_bluetooth_instance = |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2155 sdp_bluetooth_instance->OnGetSdpRecords( | 2134 sdp_bluetooth_instance->OnGetSdpRecords( |
2156 status, std::move(remote_addr), target_uuid, | 2135 status, std::move(remote_addr), target_uuid, |
2157 mojo::Array<mojom::BluetoothSdpRecordPtr>::New(0)); | 2136 mojo::Array<mojom::BluetoothSdpRecordPtr>::New(0)); |
2158 } | 2137 } |
2159 | 2138 |
2160 bool ArcBluetoothBridge::CalledOnValidThread() { | 2139 bool ArcBluetoothBridge::CalledOnValidThread() { |
2161 return thread_checker_.CalledOnValidThread(); | 2140 return thread_checker_.CalledOnValidThread(); |
2162 } | 2141 } |
2163 | 2142 |
2164 } // namespace arc | 2143 } // namespace arc |
OLD | NEW |