| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "device/bluetooth/bluetooth_adapter_android.h" | 5 #include "device/bluetooth/bluetooth_adapter_android.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 | 8 |
| 9 #include "base/android/jni_android.h" | 9 #include "base/android/jni_android.h" |
| 10 #include "base/android/jni_array.h" | 10 #include "base/android/jni_array.h" |
| 11 #include "base/android/jni_string.h" | 11 #include "base/android/jni_string.h" |
| 12 #include "base/bind.h" | 12 #include "base/bind.h" |
| 13 #include "base/location.h" | 13 #include "base/location.h" |
| 14 #include "base/sequenced_task_runner.h" | 14 #include "base/sequenced_task_runner.h" |
| 15 #include "base/single_thread_task_runner.h" | 15 #include "base/single_thread_task_runner.h" |
| 16 #include "base/threading/thread_task_runner_handle.h" | 16 #include "base/threading/thread_task_runner_handle.h" |
| 17 #include "device/bluetooth/android/wrappers.h" | 17 #include "device/bluetooth/android/wrappers.h" |
| 18 #include "device/bluetooth/bluetooth_advertisement.h" | 18 #include "device/bluetooth/bluetooth_advertisement.h" |
| 19 #include "device/bluetooth/bluetooth_device_android.h" | 19 #include "device/bluetooth/bluetooth_device_android.h" |
| 20 #include "device/bluetooth/bluetooth_discovery_filter.h" |
| 20 #include "device/bluetooth/bluetooth_discovery_session_outcome.h" | 21 #include "device/bluetooth/bluetooth_discovery_session_outcome.h" |
| 21 #include "jni/ChromeBluetoothAdapter_jni.h" | 22 #include "jni/ChromeBluetoothAdapter_jni.h" |
| 23 #include "jni/ChromeBluetoothManager_jni.h" |
| 22 | 24 |
| 23 using base::android::AttachCurrentThread; | 25 using base::android::AttachCurrentThread; |
| 24 using base::android::ConvertJavaStringToUTF8; | 26 using base::android::ConvertJavaStringToUTF8; |
| 25 using base::android::AppendJavaStringArrayToStringVector; | 27 using base::android::AppendJavaStringArrayToStringVector; |
| 26 using base::android::JavaParamRef; | 28 using base::android::JavaParamRef; |
| 27 using base::android::JavaRef; | 29 using base::android::JavaRef; |
| 28 | 30 |
| 31 namespace device { |
| 32 |
| 29 namespace { | 33 namespace { |
| 30 // The poll interval in ms when there is no active discovery. This | 34 // The poll interval in ms when there is no active discovery. This |
| 31 // matches the max allowed advertisting interval for connectable | 35 // matches the max allowed advertisting interval for connectable |
| 32 // devices. | 36 // devices. |
| 33 enum { kPassivePollInterval = 11000 }; | 37 enum { kPassivePollInterval = 11000 }; |
| 34 // The poll interval in ms when there is an active discovery. | 38 // The poll interval in ms when there is an active discovery. |
| 35 enum { kActivePollInterval = 1000 }; | 39 enum { kActivePollInterval = 1000 }; |
| 36 // The delay in ms to wait before purging devices when a scan starts. | 40 // The delay in ms to wait before purging devices when a scan starts. |
| 37 enum { kPurgeDelay = 500 }; | 41 enum { kPurgeDelay = 500 }; |
| 42 |
| 43 BluetoothDevice::UUIDList ConvertJavaStringArrayToUUIDList( |
| 44 JNIEnv* env, |
| 45 const JavaRef<jobjectArray>& j_uuids) { |
| 46 std::vector<std::string> uuids_strings; |
| 47 AppendJavaStringArrayToStringVector(env, j_uuids.obj(), &uuids_strings); |
| 48 |
| 49 BluetoothDevice::UUIDList uuids; |
| 50 for (std::string& uuid : uuids_strings) { |
| 51 uuids.push_back(BluetoothUUID(std::move(uuid))); |
| 52 } |
| 53 |
| 54 return uuids; |
| 38 } | 55 } |
| 39 | 56 |
| 40 namespace device { | 57 } // namespace |
| 41 | 58 |
| 42 // static | 59 // static |
| 43 base::WeakPtr<BluetoothAdapter> BluetoothAdapter::CreateAdapter( | 60 base::WeakPtr<BluetoothAdapter> BluetoothAdapter::CreateAdapter( |
| 44 const InitCallback& init_callback) { | 61 const InitCallback& init_callback) { |
| 45 return BluetoothAdapterAndroid::Create( | 62 return BluetoothAdapterAndroid::Create( |
| 46 BluetoothAdapterWrapper_CreateWithDefaultAdapter()); | 63 BluetoothAdapterWrapper_CreateWithDefaultAdapter(), |
| 64 BluetoothManagerWrapper_CreateWithDefaultManager()); |
| 47 } | 65 } |
| 48 | 66 |
| 49 // static | 67 // static |
| 50 base::WeakPtr<BluetoothAdapterAndroid> BluetoothAdapterAndroid::Create( | 68 base::WeakPtr<BluetoothAdapterAndroid> BluetoothAdapterAndroid::Create( |
| 51 const JavaRef<jobject>& | 69 const JavaRef<jobject>& |
| 52 bluetooth_adapter_wrapper) { // Java Type: bluetoothAdapterWrapper | 70 bluetooth_adapter_wrapper, // Java Type: BluetoothAdapterWrapper |
| 71 const JavaRef<jobject>& |
| 72 bluetooth_manager_wrapper) { // Java Type: BluetoothManagerWrapper |
| 53 BluetoothAdapterAndroid* adapter = new BluetoothAdapterAndroid(); | 73 BluetoothAdapterAndroid* adapter = new BluetoothAdapterAndroid(); |
| 54 | 74 |
| 55 adapter->j_adapter_.Reset(Java_ChromeBluetoothAdapter_create( | 75 adapter->j_adapter_.Reset(Java_ChromeBluetoothAdapter_create( |
| 56 AttachCurrentThread(), reinterpret_cast<intptr_t>(adapter), | 76 AttachCurrentThread(), reinterpret_cast<intptr_t>(adapter), |
| 57 bluetooth_adapter_wrapper)); | 77 bluetooth_adapter_wrapper)); |
| 58 | 78 |
| 79 adapter->j_manager_.Reset(Java_ChromeBluetoothManager_create( |
| 80 AttachCurrentThread(), bluetooth_manager_wrapper)); |
| 81 |
| 59 adapter->ui_task_runner_ = base::ThreadTaskRunnerHandle::Get(); | 82 adapter->ui_task_runner_ = base::ThreadTaskRunnerHandle::Get(); |
| 60 | 83 |
| 61 return adapter->weak_ptr_factory_.GetWeakPtr(); | 84 return adapter->weak_ptr_factory_.GetWeakPtr(); |
| 62 } | 85 } |
| 63 | 86 |
| 64 // static | 87 // static |
| 65 bool BluetoothAdapterAndroid::RegisterJNI(JNIEnv* env) { | 88 bool BluetoothAdapterAndroid::RegisterJNI(JNIEnv* env) { |
| 66 return RegisterNativesImpl(env); // Generated in BluetoothAdapter_jni.h | 89 return RegisterNativesImpl(env); // Generated in BluetoothAdapter_jni.h |
| 67 } | 90 } |
| 68 | 91 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 const base::Closure& callback, | 140 const base::Closure& callback, |
| 118 const ErrorCallback& error_callback) { | 141 const ErrorCallback& error_callback) { |
| 119 NOTIMPLEMENTED(); | 142 NOTIMPLEMENTED(); |
| 120 } | 143 } |
| 121 | 144 |
| 122 bool BluetoothAdapterAndroid::IsDiscovering() const { | 145 bool BluetoothAdapterAndroid::IsDiscovering() const { |
| 123 return Java_ChromeBluetoothAdapter_isDiscovering(AttachCurrentThread(), | 146 return Java_ChromeBluetoothAdapter_isDiscovering(AttachCurrentThread(), |
| 124 j_adapter_); | 147 j_adapter_); |
| 125 } | 148 } |
| 126 | 149 |
| 150 std::unordered_map<BluetoothDevice*, BluetoothDevice::UUIDSet> |
| 151 BluetoothAdapterAndroid::RetrieveGattConnectedDevicesWithDiscoveryFilter( |
| 152 const BluetoothDiscoveryFilter& discovery_filter) { |
| 153 JNIEnv* env = AttachCurrentThread(); |
| 154 ScopedJavaLocalRef<jobjectArray> j_devices_and_uuids = |
| 155 Java_ChromeBluetoothManager_retrieveGattConnectedDevices(env, j_manager_); |
| 156 |
| 157 std::unordered_map<BluetoothDevice*, BluetoothDevice::UUIDSet> |
| 158 connected_devices; |
| 159 std::set<BluetoothUUID> filter_uuids; |
| 160 discovery_filter.GetUUIDs(filter_uuids); |
| 161 |
| 162 jsize size = env->GetArrayLength(j_devices_and_uuids.obj()); |
| 163 for (jsize i = 0; i < size; i++) { |
| 164 ScopedJavaLocalRef<jobject> j_device_and_uuids( |
| 165 env, env->GetObjectArrayElement(j_devices_and_uuids.obj(), i)); |
| 166 |
| 167 ScopedJavaLocalRef<jobject> j_device = |
| 168 Java_DeviceAndUUIDs_getDevice(env, j_device_and_uuids.obj()); |
| 169 |
| 170 std::string address = ConvertJavaStringToUTF8( |
| 171 Java_DeviceAndUUIDs_getAddress(env, j_device_and_uuids.obj())); |
| 172 |
| 173 std::unique_ptr<BluetoothDeviceAndroid> device; |
| 174 BluetoothDeviceAndroid* device_ptr = nullptr; |
| 175 |
| 176 auto iter = devices_.find(address); |
| 177 const bool new_device = iter == devices_.end(); |
| 178 if (new_device) { |
| 179 device.reset(BluetoothDeviceAndroid::Create(this, j_device)); |
| 180 device_ptr = device.get(); |
| 181 } else { |
| 182 device_ptr = static_cast<BluetoothDeviceAndroid*>(iter->second); |
| 183 } |
| 184 |
| 185 DCHECK(device_ptr); |
| 186 |
| 187 ScopedJavaLocalRef<jobjectArray> j_device_uuids = |
| 188 Java_DeviceAndUUIDs_getUuids(env, j_device_and_uuids.obj()); |
| 189 |
| 190 BluetoothDevice::UUIDList device_uuids_list = |
| 191 ConvertJavaStringArrayToUUIDList(env, j_device_uuids); |
| 192 BluetoothDevice::UUIDSet intersection; |
| 193 for (BluetoothUUID& uuid : device_uuids_list) { |
| 194 if (base::ContainsKey(filter_uuids, uuid)) { |
| 195 intersection.insert(uuid); |
| 196 } |
| 197 } |
| 198 |
| 199 if (!filter_uuids.empty() && intersection.empty()) { |
| 200 continue; |
| 201 } |
| 202 |
| 203 connected_devices[device_ptr] = std::move(intersection); |
| 204 |
| 205 if (new_device) { |
| 206 devices_.add(device_ptr->GetAddress(), std::move(device)); |
| 207 for (auto& observer : observers_) |
| 208 observer.DeviceAdded(this, device_ptr); |
| 209 } |
| 210 } |
| 211 |
| 212 return connected_devices; |
| 213 } |
| 214 |
| 127 BluetoothAdapter::UUIDList BluetoothAdapterAndroid::GetUUIDs() const { | 215 BluetoothAdapter::UUIDList BluetoothAdapterAndroid::GetUUIDs() const { |
| 128 NOTIMPLEMENTED(); | 216 NOTIMPLEMENTED(); |
| 129 return UUIDList(); | 217 return UUIDList(); |
| 130 } | 218 } |
| 131 | 219 |
| 132 void BluetoothAdapterAndroid::CreateRfcommService( | 220 void BluetoothAdapterAndroid::CreateRfcommService( |
| 133 const BluetoothUUID& uuid, | 221 const BluetoothUUID& uuid, |
| 134 const ServiceOptions& options, | 222 const ServiceOptions& options, |
| 135 const CreateServiceCallback& callback, | 223 const CreateServiceCallback& callback, |
| 136 const CreateServiceErrorCallback& error_callback) { | 224 const CreateServiceErrorCallback& error_callback) { |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 194 is_new_device = true; | 282 is_new_device = true; |
| 195 device_android_owner.reset( | 283 device_android_owner.reset( |
| 196 BluetoothDeviceAndroid::Create(this, bluetooth_device_wrapper)); | 284 BluetoothDeviceAndroid::Create(this, bluetooth_device_wrapper)); |
| 197 device_android = device_android_owner.get(); | 285 device_android = device_android_owner.get(); |
| 198 } else { | 286 } else { |
| 199 // Existing device. | 287 // Existing device. |
| 200 device_android = static_cast<BluetoothDeviceAndroid*>(iter->second); | 288 device_android = static_cast<BluetoothDeviceAndroid*>(iter->second); |
| 201 } | 289 } |
| 202 DCHECK(device_android); | 290 DCHECK(device_android); |
| 203 | 291 |
| 204 std::vector<std::string> advertised_uuids_strings; | 292 BluetoothDevice::UUIDList advertised_bluetooth_uuids = |
| 205 AppendJavaStringArrayToStringVector(env, advertised_uuids, | 293 ConvertJavaStringArrayToUUIDList(env, advertised_uuids); |
| 206 &advertised_uuids_strings); | |
| 207 BluetoothDevice::UUIDList advertised_bluetooth_uuids; | |
| 208 for (std::string& uuid : advertised_uuids_strings) { | |
| 209 advertised_bluetooth_uuids.push_back(BluetoothUUID(std::move(uuid))); | |
| 210 } | |
| 211 | 294 |
| 212 int8_t clamped_tx_power = BluetoothDevice::ClampPower(tx_power); | 295 int8_t clamped_tx_power = BluetoothDevice::ClampPower(tx_power); |
| 213 | 296 |
| 214 device_android->UpdateAdvertisementData( | 297 device_android->UpdateAdvertisementData( |
| 215 BluetoothDevice::ClampPower(rssi), std::move(advertised_bluetooth_uuids), | 298 BluetoothDevice::ClampPower(rssi), std::move(advertised_bluetooth_uuids), |
| 216 {} /* service_data */, | 299 {} /* service_data */, |
| 217 // Android uses INT32_MIN to indicate no Advertised Tx Power. | 300 // Android uses INT32_MIN to indicate no Advertised Tx Power. |
| 218 // https://developer.android.com/reference/android/bluetooth/le/ScanRecord
.html#getTxPowerLevel() | 301 // https://developer.android.com/reference/android/bluetooth/le/ScanRecord
.html#getTxPowerLevel() |
| 219 tx_power == INT32_MIN ? nullptr : &clamped_tx_power); | 302 tx_power == INT32_MIN ? nullptr : &clamped_tx_power); |
| 220 | 303 |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 325 // TODO(scheib): Support filters crbug.com/490401 | 408 // TODO(scheib): Support filters crbug.com/490401 |
| 326 NOTIMPLEMENTED(); | 409 NOTIMPLEMENTED(); |
| 327 error_callback.Run(UMABluetoothDiscoverySessionOutcome::NOT_IMPLEMENTED); | 410 error_callback.Run(UMABluetoothDiscoverySessionOutcome::NOT_IMPLEMENTED); |
| 328 } | 411 } |
| 329 | 412 |
| 330 void BluetoothAdapterAndroid::RemovePairingDelegateInternal( | 413 void BluetoothAdapterAndroid::RemovePairingDelegateInternal( |
| 331 device::BluetoothDevice::PairingDelegate* pairing_delegate) { | 414 device::BluetoothDevice::PairingDelegate* pairing_delegate) { |
| 332 } | 415 } |
| 333 | 416 |
| 334 } // namespace device | 417 } // namespace device |
| OLD | NEW |