Chromium Code Reviews| 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_string.h" | 10 #include "base/android/jni_string.h" |
| 11 #include "base/bind.h" | |
| 12 #include "base/location.h" | |
| 11 #include "base/sequenced_task_runner.h" | 13 #include "base/sequenced_task_runner.h" |
| 12 #include "base/single_thread_task_runner.h" | 14 #include "base/single_thread_task_runner.h" |
| 13 #include "base/threading/thread_task_runner_handle.h" | 15 #include "base/threading/thread_task_runner_handle.h" |
| 14 #include "device/bluetooth/android/wrappers.h" | 16 #include "device/bluetooth/android/wrappers.h" |
| 15 #include "device/bluetooth/bluetooth_advertisement.h" | 17 #include "device/bluetooth/bluetooth_advertisement.h" |
| 16 #include "device/bluetooth/bluetooth_device_android.h" | 18 #include "device/bluetooth/bluetooth_device_android.h" |
| 17 #include "device/bluetooth/bluetooth_discovery_session_outcome.h" | 19 #include "device/bluetooth/bluetooth_discovery_session_outcome.h" |
| 18 #include "jni/ChromeBluetoothAdapter_jni.h" | 20 #include "jni/ChromeBluetoothAdapter_jni.h" |
| 19 | 21 |
| 20 using base::android::AttachCurrentThread; | 22 using base::android::AttachCurrentThread; |
| 21 using base::android::ConvertJavaStringToUTF8; | 23 using base::android::ConvertJavaStringToUTF8; |
| 22 | 24 |
| 25 namespace { | |
| 26 // The poll interval in ms when there is no active discovery. This | |
| 27 // matches the max allowed advertisting interval for connectable | |
| 28 // devices. | |
| 29 enum { kPassivePollInterval = 11000 }; | |
| 30 // The poll interval in ms when there is an active discovery. | |
| 31 enum { kActivePollInterval = 1000 }; | |
| 32 // The delay in ms to wait before purging devices when a scan starts. | |
| 33 enum { kPurgeDelay = 500 }; | |
| 34 } | |
| 35 | |
| 23 namespace device { | 36 namespace device { |
| 24 | 37 |
| 25 // static | 38 // static |
| 26 base::WeakPtr<BluetoothAdapter> BluetoothAdapter::CreateAdapter( | 39 base::WeakPtr<BluetoothAdapter> BluetoothAdapter::CreateAdapter( |
| 27 const InitCallback& init_callback) { | 40 const InitCallback& init_callback) { |
| 28 return BluetoothAdapterAndroid::Create( | 41 return BluetoothAdapterAndroid::Create( |
| 29 BluetoothAdapterWrapper_CreateWithDefaultAdapter().obj()); | 42 BluetoothAdapterWrapper_CreateWithDefaultAdapter().obj()); |
| 30 } | 43 } |
| 31 | 44 |
| 32 // static | 45 // static |
| 33 base::WeakPtr<BluetoothAdapterAndroid> BluetoothAdapterAndroid::Create( | 46 base::WeakPtr<BluetoothAdapterAndroid> BluetoothAdapterAndroid::Create( |
| 34 jobject bluetooth_adapter_wrapper) { // Java Type: bluetoothAdapterWrapper | 47 jobject bluetooth_adapter_wrapper) { // Java Type: bluetoothAdapterWrapper |
| 35 BluetoothAdapterAndroid* adapter = new BluetoothAdapterAndroid(); | 48 BluetoothAdapterAndroid* adapter = new BluetoothAdapterAndroid(); |
| 36 | 49 |
| 37 adapter->j_adapter_.Reset(Java_ChromeBluetoothAdapter_create( | 50 adapter->j_adapter_.Reset(Java_ChromeBluetoothAdapter_create( |
| 38 AttachCurrentThread(), reinterpret_cast<intptr_t>(adapter), | 51 AttachCurrentThread(), reinterpret_cast<intptr_t>(adapter), |
| 39 bluetooth_adapter_wrapper)); | 52 bluetooth_adapter_wrapper)); |
| 40 | 53 |
| 54 adapter->ui_task_runner_ = base::ThreadTaskRunnerHandle::Get(); | |
| 55 | |
| 41 return adapter->weak_ptr_factory_.GetWeakPtr(); | 56 return adapter->weak_ptr_factory_.GetWeakPtr(); |
| 42 } | 57 } |
| 43 | 58 |
| 44 // static | 59 // static |
| 45 bool BluetoothAdapterAndroid::RegisterJNI(JNIEnv* env) { | 60 bool BluetoothAdapterAndroid::RegisterJNI(JNIEnv* env) { |
| 46 return RegisterNativesImpl(env); // Generated in BluetoothAdapter_jni.h | 61 return RegisterNativesImpl(env); // Generated in BluetoothAdapter_jni.h |
| 47 } | 62 } |
| 48 | 63 |
| 49 std::string BluetoothAdapterAndroid::GetAddress() const { | 64 std::string BluetoothAdapterAndroid::GetAddress() const { |
| 50 return ConvertJavaStringToUTF8(Java_ChromeBluetoothAdapter_getAddress( | 65 return ConvertJavaStringToUTF8(Java_ChromeBluetoothAdapter_getAddress( |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 149 void BluetoothAdapterAndroid::OnAdapterStateChanged( | 164 void BluetoothAdapterAndroid::OnAdapterStateChanged( |
| 150 JNIEnv* env, | 165 JNIEnv* env, |
| 151 const JavaParamRef<jobject>& caller, | 166 const JavaParamRef<jobject>& caller, |
| 152 const bool powered) { | 167 const bool powered) { |
| 153 NotifyAdapterPoweredChanged(powered); | 168 NotifyAdapterPoweredChanged(powered); |
| 154 } | 169 } |
| 155 | 170 |
| 156 void BluetoothAdapterAndroid::OnScanFailed( | 171 void BluetoothAdapterAndroid::OnScanFailed( |
| 157 JNIEnv* env, | 172 JNIEnv* env, |
| 158 const JavaParamRef<jobject>& caller) { | 173 const JavaParamRef<jobject>& caller) { |
| 174 numDiscoverySessions = 0; | |
| 159 MarkDiscoverySessionsAsInactive(); | 175 MarkDiscoverySessionsAsInactive(); |
| 160 } | 176 } |
| 161 | 177 |
| 162 void BluetoothAdapterAndroid::CreateOrUpdateDeviceOnScan( | 178 void BluetoothAdapterAndroid::CreateOrUpdateDeviceOnScan( |
| 163 JNIEnv* env, | 179 JNIEnv* env, |
| 164 const JavaParamRef<jobject>& caller, | 180 const JavaParamRef<jobject>& caller, |
| 165 const JavaParamRef<jstring>& address, | 181 const JavaParamRef<jstring>& address, |
| 166 const JavaParamRef<jobject>& | 182 const JavaParamRef<jobject>& |
| 167 bluetooth_device_wrapper, // Java Type: bluetoothDeviceWrapper | 183 bluetooth_device_wrapper, // Java Type: bluetoothDeviceWrapper |
| 168 const JavaParamRef<jobject>& | 184 const JavaParamRef<jobject>& |
| 169 advertised_uuids) { // Java Type: List<ParcelUuid> | 185 advertised_uuids) { // Java Type: List<ParcelUuid> |
| 170 std::string device_address = ConvertJavaStringToUTF8(env, address); | 186 std::string device_address = ConvertJavaStringToUTF8(env, address); |
| 171 DevicesMap::const_iterator iter = devices_.find(device_address); | 187 DevicesMap::const_iterator iter = devices_.find(device_address); |
| 172 | 188 |
| 173 if (iter == devices_.end()) { | 189 if (iter == devices_.end()) { |
| 174 // New device. | 190 // New device. |
| 175 BluetoothDeviceAndroid* device_android = | 191 BluetoothDeviceAndroid* device_android = |
| 176 BluetoothDeviceAndroid::Create(this, bluetooth_device_wrapper); | 192 BluetoothDeviceAndroid::Create(this, bluetooth_device_wrapper); |
| 177 device_android->UpdateAdvertisedUUIDs(advertised_uuids); | 193 device_android->UpdateAdvertisedUUIDs(advertised_uuids); |
| 194 device_android->UpdateTimestamp(); | |
| 178 devices_.add(device_address, | 195 devices_.add(device_address, |
| 179 std::unique_ptr<BluetoothDevice>(device_android)); | 196 std::unique_ptr<BluetoothDevice>(device_android)); |
| 180 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, | 197 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, |
| 181 DeviceAdded(this, device_android)); | 198 DeviceAdded(this, device_android)); |
| 182 } else { | 199 } else { |
| 183 // Existing device. | 200 // Existing device. |
| 184 BluetoothDeviceAndroid* device_android = | 201 BluetoothDeviceAndroid* device_android = |
| 185 static_cast<BluetoothDeviceAndroid*>(iter->second); | 202 static_cast<BluetoothDeviceAndroid*>(iter->second); |
| 203 device_android->UpdateTimestamp(); | |
| 186 if (device_android->UpdateAdvertisedUUIDs(advertised_uuids)) { | 204 if (device_android->UpdateAdvertisedUUIDs(advertised_uuids)) { |
| 187 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, | 205 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, |
| 188 DeviceChanged(this, device_android)); | 206 DeviceChanged(this, device_android)); |
| 189 } | 207 } |
| 190 } | 208 } |
| 191 } | 209 } |
| 192 | 210 |
| 193 BluetoothAdapterAndroid::BluetoothAdapterAndroid() : weak_ptr_factory_(this) { | 211 BluetoothAdapterAndroid::BluetoothAdapterAndroid() : weak_ptr_factory_(this) { |
| 194 } | 212 } |
| 195 | 213 |
| 196 BluetoothAdapterAndroid::~BluetoothAdapterAndroid() { | 214 BluetoothAdapterAndroid::~BluetoothAdapterAndroid() { |
| 197 Java_ChromeBluetoothAdapter_onBluetoothAdapterAndroidDestruction( | 215 Java_ChromeBluetoothAdapter_onBluetoothAdapterAndroidDestruction( |
| 198 AttachCurrentThread(), j_adapter_.obj()); | 216 AttachCurrentThread(), j_adapter_.obj()); |
| 199 } | 217 } |
| 200 | 218 |
| 219 void BluetoothAdapterAndroid::PurgeTimedOutDevices() { | |
| 220 if (IsDiscovering()) { | |
| 221 RemoveTimedOutDevices(); | |
| 222 ui_task_runner_->PostDelayedTask( | |
| 223 FROM_HERE, base::Bind(&BluetoothAdapterAndroid::PurgeTimedOutDevices, | |
| 224 weak_ptr_factory_.GetWeakPtr()), | |
| 225 base::TimeDelta::FromMilliseconds(kActivePollInterval)); | |
| 226 } else { | |
| 227 ui_task_runner_->PostDelayedTask( | |
| 228 FROM_HERE, base::Bind(&BluetoothAdapterAndroid::RemoveTimedOutDevices, | |
| 229 weak_ptr_factory_.GetWeakPtr()), | |
| 230 base::TimeDelta::FromMilliseconds(kPassivePollInterval)); | |
| 231 } | |
| 232 } | |
| 233 | |
| 201 void BluetoothAdapterAndroid::AddDiscoverySession( | 234 void BluetoothAdapterAndroid::AddDiscoverySession( |
| 202 BluetoothDiscoveryFilter* discovery_filter, | 235 BluetoothDiscoveryFilter* discovery_filter, |
| 203 const base::Closure& callback, | 236 const base::Closure& callback, |
| 204 const DiscoverySessionErrorCallback& error_callback) { | 237 const DiscoverySessionErrorCallback& error_callback) { |
| 205 // TODO(scheib): Support filters crbug.com/490401 | 238 // TODO(scheib): Support filters crbug.com/490401 |
| 206 if (Java_ChromeBluetoothAdapter_addDiscoverySession(AttachCurrentThread(), | 239 bool sessionAdded = false; |
|
ortuno
2016/06/17 19:31:41
session_added
perja
2016/06/22 07:41:52
Done.
| |
| 207 j_adapter_.obj())) { | 240 if (IsPowered()) { |
| 241 if (numDiscoverySessions > 0) { | |
| 242 sessionAdded = true; | |
| 243 } else if (Java_ChromeBluetoothAdapter_startScan(AttachCurrentThread(), | |
| 244 j_adapter_.obj())) { | |
| 245 sessionAdded = true; | |
| 246 | |
| 247 // Using a delayed task in order to give the adapter some time | |
| 248 // to settle before purging devices. | |
| 249 ui_task_runner_->PostDelayedTask( | |
| 250 FROM_HERE, base::Bind(&BluetoothAdapterAndroid::PurgeTimedOutDevices, | |
| 251 weak_ptr_factory_.GetWeakPtr()), | |
| 252 base::TimeDelta::FromMilliseconds(kPurgeDelay)); | |
| 253 } | |
| 254 } else { | |
| 255 VLOG(1) << "AddDiscoverySession: Fails: !isPowered"; | |
| 256 } | |
| 257 | |
| 258 if (sessionAdded) { | |
| 259 numDiscoverySessions++; | |
| 260 VLOG(1) << "AddDiscoverySession: Now " << unsigned(numDiscoverySessions) | |
| 261 << " sessions."; | |
| 208 callback.Run(); | 262 callback.Run(); |
| 209 } else { | 263 } else { |
| 210 // TODO(scheib): Eventually wire the SCAN_FAILED result through to here. | 264 // TODO(scheib): Eventually wire the SCAN_FAILED result through to here. |
| 211 error_callback.Run(UMABluetoothDiscoverySessionOutcome::UNKNOWN); | 265 error_callback.Run(UMABluetoothDiscoverySessionOutcome::UNKNOWN); |
| 212 } | 266 } |
| 213 } | 267 } |
| 214 | 268 |
| 215 void BluetoothAdapterAndroid::RemoveDiscoverySession( | 269 void BluetoothAdapterAndroid::RemoveDiscoverySession( |
| 216 BluetoothDiscoveryFilter* discovery_filter, | 270 BluetoothDiscoveryFilter* discovery_filter, |
| 217 const base::Closure& callback, | 271 const base::Closure& callback, |
| 218 const DiscoverySessionErrorCallback& error_callback) { | 272 const DiscoverySessionErrorCallback& error_callback) { |
| 219 if (Java_ChromeBluetoothAdapter_removeDiscoverySession(AttachCurrentThread(), | 273 bool sessionRemoved = false; |
|
ortuno
2016/06/17 19:31:41
session_removed
perja
2016/06/22 07:41:52
Done.
| |
| 220 j_adapter_.obj())) { | 274 if (numDiscoverySessions == 0) { |
| 275 DCHECK(false); | |
|
ortuno
2016/06/17 19:31:41
Move this below the following line and change it t
perja
2016/06/22 07:41:52
Done.
| |
| 276 VLOG(1) << "RemoveDiscoverySession: No scan in progress."; | |
| 277 } else { | |
| 278 --numDiscoverySessions; | |
| 279 sessionRemoved = true; | |
| 280 if (numDiscoverySessions == 0) { | |
| 281 VLOG(1) << "RemoveDiscoverySession: Now 0 sessions. Stopping scan."; | |
| 282 sessionRemoved = Java_ChromeBluetoothAdapter_stopScan( | |
| 283 AttachCurrentThread(), j_adapter_.obj()); | |
| 284 } else { | |
| 285 VLOG(1) << "RemoveDiscoverySession: Now " | |
| 286 << unsigned(numDiscoverySessions) << " sessions."; | |
| 287 } | |
| 288 } | |
| 289 | |
| 290 if (sessionRemoved) { | |
| 221 callback.Run(); | 291 callback.Run(); |
| 222 } else { | 292 } else { |
| 223 // TODO(scheib): Eventually wire the SCAN_FAILED result through to here. | 293 // TODO(scheib): Eventually wire the SCAN_FAILED result through to here. |
| 224 error_callback.Run(UMABluetoothDiscoverySessionOutcome::UNKNOWN); | 294 error_callback.Run(UMABluetoothDiscoverySessionOutcome::UNKNOWN); |
| 225 } | 295 } |
| 226 } | 296 } |
| 227 | 297 |
| 228 void BluetoothAdapterAndroid::SetDiscoveryFilter( | 298 void BluetoothAdapterAndroid::SetDiscoveryFilter( |
| 229 std::unique_ptr<BluetoothDiscoveryFilter> discovery_filter, | 299 std::unique_ptr<BluetoothDiscoveryFilter> discovery_filter, |
| 230 const base::Closure& callback, | 300 const base::Closure& callback, |
| 231 const DiscoverySessionErrorCallback& error_callback) { | 301 const DiscoverySessionErrorCallback& error_callback) { |
| 232 // TODO(scheib): Support filters crbug.com/490401 | 302 // TODO(scheib): Support filters crbug.com/490401 |
| 233 NOTIMPLEMENTED(); | 303 NOTIMPLEMENTED(); |
| 234 error_callback.Run(UMABluetoothDiscoverySessionOutcome::NOT_IMPLEMENTED); | 304 error_callback.Run(UMABluetoothDiscoverySessionOutcome::NOT_IMPLEMENTED); |
| 235 } | 305 } |
| 236 | 306 |
| 237 void BluetoothAdapterAndroid::RemovePairingDelegateInternal( | 307 void BluetoothAdapterAndroid::RemovePairingDelegateInternal( |
| 238 device::BluetoothDevice::PairingDelegate* pairing_delegate) { | 308 device::BluetoothDevice::PairingDelegate* pairing_delegate) { |
| 239 } | 309 } |
| 240 | 310 |
| 241 } // namespace device | 311 } // namespace device |
| OLD | NEW |