| Index: device/bluetooth/bluetooth_adapter_android.cc
|
| diff --git a/device/bluetooth/bluetooth_adapter_android.cc b/device/bluetooth/bluetooth_adapter_android.cc
|
| index c642e03a005a21ed06fa744274e98da7af34edb0..780ced05e32cc55490b73b81407698c26ecf0bea 100644
|
| --- a/device/bluetooth/bluetooth_adapter_android.cc
|
| +++ b/device/bluetooth/bluetooth_adapter_android.cc
|
| @@ -8,6 +8,8 @@
|
|
|
| #include "base/android/jni_android.h"
|
| #include "base/android/jni_string.h"
|
| +#include "base/bind.h"
|
| +#include "base/location.h"
|
| #include "base/sequenced_task_runner.h"
|
| #include "base/single_thread_task_runner.h"
|
| #include "base/threading/thread_task_runner_handle.h"
|
| @@ -20,6 +22,17 @@
|
| using base::android::AttachCurrentThread;
|
| using base::android::ConvertJavaStringToUTF8;
|
|
|
| +namespace {
|
| +// The poll interval in ms when there is no active discovery. This
|
| +// matches the max allowed advertisting interval for connectable
|
| +// devices.
|
| +enum { kPassivePollInterval = 11000 };
|
| +// The poll interval in ms when there is an active discovery.
|
| +enum { kActivePollInterval = 1000 };
|
| +// The delay in ms to wait before purging devices when a scan starts.
|
| +enum { kPurgeDelay = 500 };
|
| +}
|
| +
|
| namespace device {
|
|
|
| // static
|
| @@ -38,6 +51,8 @@ base::WeakPtr<BluetoothAdapterAndroid> BluetoothAdapterAndroid::Create(
|
| AttachCurrentThread(), reinterpret_cast<intptr_t>(adapter),
|
| bluetooth_adapter_wrapper));
|
|
|
| + adapter->ui_task_runner_ = base::ThreadTaskRunnerHandle::Get();
|
| +
|
| return adapter->weak_ptr_factory_.GetWeakPtr();
|
| }
|
|
|
| @@ -156,6 +171,7 @@ void BluetoothAdapterAndroid::OnAdapterStateChanged(
|
| void BluetoothAdapterAndroid::OnScanFailed(
|
| JNIEnv* env,
|
| const JavaParamRef<jobject>& caller) {
|
| + num_discovery_sessions_ = 0;
|
| MarkDiscoverySessionsAsInactive();
|
| }
|
|
|
| @@ -175,6 +191,7 @@ void BluetoothAdapterAndroid::CreateOrUpdateDeviceOnScan(
|
| BluetoothDeviceAndroid* device_android =
|
| BluetoothDeviceAndroid::Create(this, bluetooth_device_wrapper);
|
| device_android->UpdateAdvertisedUUIDs(advertised_uuids);
|
| + device_android->UpdateTimestamp();
|
| devices_.add(device_address,
|
| std::unique_ptr<BluetoothDevice>(device_android));
|
| FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
|
| @@ -183,6 +200,7 @@ void BluetoothAdapterAndroid::CreateOrUpdateDeviceOnScan(
|
| // Existing device.
|
| BluetoothDeviceAndroid* device_android =
|
| static_cast<BluetoothDeviceAndroid*>(iter->second);
|
| + device_android->UpdateTimestamp();
|
| if (device_android->UpdateAdvertisedUUIDs(advertised_uuids)) {
|
| FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
|
| DeviceChanged(this, device_android));
|
| @@ -198,13 +216,49 @@ BluetoothAdapterAndroid::~BluetoothAdapterAndroid() {
|
| AttachCurrentThread(), j_adapter_.obj());
|
| }
|
|
|
| +void BluetoothAdapterAndroid::PurgeTimedOutDevices() {
|
| + RemoveTimedOutDevices();
|
| + if (IsDiscovering()) {
|
| + ui_task_runner_->PostDelayedTask(
|
| + FROM_HERE, base::Bind(&BluetoothAdapterAndroid::PurgeTimedOutDevices,
|
| + weak_ptr_factory_.GetWeakPtr()),
|
| + base::TimeDelta::FromMilliseconds(kActivePollInterval));
|
| + } else {
|
| + ui_task_runner_->PostDelayedTask(
|
| + FROM_HERE, base::Bind(&BluetoothAdapterAndroid::RemoveTimedOutDevices,
|
| + weak_ptr_factory_.GetWeakPtr()),
|
| + base::TimeDelta::FromMilliseconds(kPassivePollInterval));
|
| + }
|
| +}
|
| +
|
| void BluetoothAdapterAndroid::AddDiscoverySession(
|
| BluetoothDiscoveryFilter* discovery_filter,
|
| const base::Closure& callback,
|
| const DiscoverySessionErrorCallback& error_callback) {
|
| // TODO(scheib): Support filters crbug.com/490401
|
| - if (Java_ChromeBluetoothAdapter_addDiscoverySession(AttachCurrentThread(),
|
| - j_adapter_.obj())) {
|
| + bool session_added = false;
|
| + if (IsPowered()) {
|
| + if (num_discovery_sessions_ > 0) {
|
| + session_added = true;
|
| + } else if (Java_ChromeBluetoothAdapter_startScan(AttachCurrentThread(),
|
| + j_adapter_.obj())) {
|
| + session_added = true;
|
| +
|
| + // Using a delayed task in order to give the adapter some time
|
| + // to settle before purging devices.
|
| + ui_task_runner_->PostDelayedTask(
|
| + FROM_HERE, base::Bind(&BluetoothAdapterAndroid::PurgeTimedOutDevices,
|
| + weak_ptr_factory_.GetWeakPtr()),
|
| + base::TimeDelta::FromMilliseconds(kPurgeDelay));
|
| + }
|
| + } else {
|
| + VLOG(1) << "AddDiscoverySession: Fails: !isPowered";
|
| + }
|
| +
|
| + if (session_added) {
|
| + num_discovery_sessions_++;
|
| + VLOG(1) << "AddDiscoverySession: Now " << unsigned(num_discovery_sessions_)
|
| + << " sessions.";
|
| callback.Run();
|
| } else {
|
| // TODO(scheib): Eventually wire the SCAN_FAILED result through to here.
|
| @@ -216,8 +270,24 @@ void BluetoothAdapterAndroid::RemoveDiscoverySession(
|
| BluetoothDiscoveryFilter* discovery_filter,
|
| const base::Closure& callback,
|
| const DiscoverySessionErrorCallback& error_callback) {
|
| - if (Java_ChromeBluetoothAdapter_removeDiscoverySession(AttachCurrentThread(),
|
| - j_adapter_.obj())) {
|
| + bool session_removed = false;
|
| + if (num_discovery_sessions_ == 0) {
|
| + VLOG(1) << "RemoveDiscoverySession: No scan in progress.";
|
| + NOTREACHED();
|
| + } else {
|
| + --num_discovery_sessions_;
|
| + session_removed = true;
|
| + if (num_discovery_sessions_ == 0) {
|
| + VLOG(1) << "RemoveDiscoverySession: Now 0 sessions. Stopping scan.";
|
| + session_removed = Java_ChromeBluetoothAdapter_stopScan(
|
| + AttachCurrentThread(), j_adapter_.obj());
|
| + } else {
|
| + VLOG(1) << "RemoveDiscoverySession: Now "
|
| + << unsigned(num_discovery_sessions_) << " sessions.";
|
| + }
|
| + }
|
| +
|
| + if (session_removed) {
|
| callback.Run();
|
| } else {
|
| // TODO(scheib): Eventually wire the SCAN_FAILED result through to here.
|
|
|