summaryrefslogtreecommitdiffstats
path: root/device
diff options
context:
space:
mode:
authorjpawlowski <jpawlowski@chromium.org>2015-04-13 15:24:43 -0700
committerCommit bot <commit-bot@chromium.org>2015-04-13 22:24:58 +0000
commitf54d0154bf4e1b1e91168cb88a87d73eb19e5e32 (patch)
tree40be17eb5c78b799c9479478409196eb78146b8c /device
parentcaad96239b443ba1ba113414bafd89aa2f264149 (diff)
downloadchromium_src-f54d0154bf4e1b1e91168cb88a87d73eb19e5e32.zip
chromium_src-f54d0154bf4e1b1e91168cb88a87d73eb19e5e32.tar.gz
chromium_src-f54d0154bf4e1b1e91168cb88a87d73eb19e5e32.tar.bz2
Add SetDiscoveryFilter to Bluetooth Adapter.
This patch adds SetDiscoveryFilter method to BluetoothAdapter. Implementation for ChromeOS platform together with tests will follow. BUG=407773 R=armansito@chromium.org Review URL: https://codereview.chromium.org/1068473002 Cr-Commit-Position: refs/heads/master@{#324922}
Diffstat (limited to 'device')
-rw-r--r--device/BUILD.gn1
-rw-r--r--device/bluetooth/bluetooth_adapter.cc70
-rw-r--r--device/bluetooth/bluetooth_adapter.h40
-rw-r--r--device/bluetooth/bluetooth_adapter_chromeos.cc12
-rw-r--r--device/bluetooth/bluetooth_adapter_chromeos.h14
-rw-r--r--device/bluetooth/bluetooth_adapter_mac.h9
-rw-r--r--device/bluetooth/bluetooth_adapter_mac.mm10
-rw-r--r--device/bluetooth/bluetooth_adapter_unittest.cc239
-rw-r--r--device/bluetooth/bluetooth_adapter_win.cc10
-rw-r--r--device/bluetooth/bluetooth_adapter_win.h7
-rw-r--r--device/bluetooth/bluetooth_adapter_win_unittest.cc4
-rw-r--r--device/bluetooth/bluetooth_chromeos_unittest.cc30
-rw-r--r--device/bluetooth/bluetooth_discovery_filter_unittest.cc181
-rw-r--r--device/bluetooth/bluetooth_discovery_session.cc194
-rw-r--r--device/bluetooth/bluetooth_discovery_session.h72
-rw-r--r--device/bluetooth/test/mock_bluetooth_adapter.cc14
-rw-r--r--device/bluetooth/test/mock_bluetooth_adapter.h14
-rw-r--r--device/bluetooth/test/mock_bluetooth_discovery_session.cc6
-rw-r--r--device/device_tests.gyp1
19 files changed, 883 insertions, 45 deletions
diff --git a/device/BUILD.gn b/device/BUILD.gn
index bd83abe..3bf6fa7 100644
--- a/device/BUILD.gn
+++ b/device/BUILD.gn
@@ -20,6 +20,7 @@ test("device_unittests") {
"bluetooth/bluetooth_chromeos_unittest.cc",
"bluetooth/bluetooth_device_unittest.cc",
"bluetooth/bluetooth_device_win_unittest.cc",
+ "bluetooth/bluetooth_discovery_filter_unittest.cc",
"bluetooth/bluetooth_gatt_chromeos_unittest.cc",
"bluetooth/bluetooth_low_energy_win_unittest.cc",
"bluetooth/bluetooth_service_record_win_unittest.cc",
diff --git a/device/bluetooth/bluetooth_adapter.cc b/device/bluetooth/bluetooth_adapter.cc
index 52c2d74..fd2e29b3 100644
--- a/device/bluetooth/bluetooth_adapter.cc
+++ b/device/bluetooth/bluetooth_adapter.cc
@@ -42,14 +42,70 @@ base::WeakPtr<BluetoothAdapter> BluetoothAdapter::GetWeakPtrForTesting() {
return weak_ptr_factory_.GetWeakPtr();
}
+void BluetoothAdapter::StartDiscoverySessionWithFilter(
+ scoped_ptr<BluetoothDiscoveryFilter> discovery_filter,
+ const DiscoverySessionCallback& callback,
+ const ErrorCallback& error_callback) {
+ AddDiscoverySession(discovery_filter.get(),
+ base::Bind(&BluetoothAdapter::OnStartDiscoverySession,
+ weak_ptr_factory_.GetWeakPtr(),
+ base::Passed(&discovery_filter), callback),
+ error_callback);
+}
+
void BluetoothAdapter::StartDiscoverySession(
const DiscoverySessionCallback& callback,
const ErrorCallback& error_callback) {
- AddDiscoverySession(
- base::Bind(&BluetoothAdapter::OnStartDiscoverySession,
- weak_ptr_factory_.GetWeakPtr(),
- callback),
- error_callback);
+ StartDiscoverySessionWithFilter(nullptr, callback, error_callback);
+}
+
+scoped_ptr<BluetoothDiscoveryFilter>
+BluetoothAdapter::GetMergedDiscoveryFilterHelper(
+ const BluetoothDiscoveryFilter* masked_filter,
+ bool omit) const {
+ scoped_ptr<BluetoothDiscoveryFilter> result;
+ bool first_merge = true;
+
+ std::set<BluetoothDiscoverySession*> temp(discovery_sessions_);
+ for (const auto& iter : temp) {
+ const BluetoothDiscoveryFilter* curr_filter = iter->GetDiscoveryFilter();
+
+ if (!iter->IsActive())
+ continue;
+
+ if (omit && curr_filter == masked_filter) {
+ // if masked_filter is pointing to empty filter, and there are
+ // multiple empty filters in discovery_sessions_, make sure we'll
+ // process next empty sessions.
+ omit = false;
+ continue;
+ }
+
+ if (first_merge) {
+ first_merge = false;
+ if (curr_filter) {
+ result.reset(new BluetoothDiscoveryFilter(
+ BluetoothDiscoveryFilter::Transport::TRANSPORT_DUAL));
+ result->CopyFrom(*curr_filter);
+ }
+ continue;
+ }
+
+ result = BluetoothDiscoveryFilter::Merge(result.get(), curr_filter);
+ }
+
+ return result.Pass();
+}
+
+scoped_ptr<BluetoothDiscoveryFilter>
+BluetoothAdapter::GetMergedDiscoveryFilter() const {
+ return GetMergedDiscoveryFilterHelper(nullptr, false);
+}
+
+scoped_ptr<BluetoothDiscoveryFilter>
+BluetoothAdapter::GetMergedDiscoveryFilterMasked(
+ BluetoothDiscoveryFilter* masked_filter) const {
+ return GetMergedDiscoveryFilterHelper(masked_filter, true);
}
BluetoothAdapter::DeviceList BluetoothAdapter::GetDevices() {
@@ -128,10 +184,12 @@ BluetoothDevice::PairingDelegate* BluetoothAdapter::DefaultPairingDelegate() {
}
void BluetoothAdapter::OnStartDiscoverySession(
+ scoped_ptr<BluetoothDiscoveryFilter> discovery_filter,
const DiscoverySessionCallback& callback) {
VLOG(1) << "Discovery session started!";
scoped_ptr<BluetoothDiscoverySession> discovery_session(
- new BluetoothDiscoverySession(scoped_refptr<BluetoothAdapter>(this)));
+ new BluetoothDiscoverySession(scoped_refptr<BluetoothAdapter>(this),
+ discovery_filter.Pass()));
discovery_sessions_.insert(discovery_session.get());
callback.Run(discovery_session.Pass());
}
diff --git a/device/bluetooth/bluetooth_adapter.h b/device/bluetooth/bluetooth_adapter.h
index 77c64ee..d764ae9 100644
--- a/device/bluetooth/bluetooth_adapter.h
+++ b/device/bluetooth/bluetooth_adapter.h
@@ -20,6 +20,7 @@
namespace device {
+class BluetoothDiscoveryFilter;
class BluetoothDiscoverySession;
class BluetoothGattCharacteristic;
class BluetoothGattDescriptor;
@@ -273,6 +274,19 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapter
DiscoverySessionCallback;
virtual void StartDiscoverySession(const DiscoverySessionCallback& callback,
const ErrorCallback& error_callback);
+ virtual void StartDiscoverySessionWithFilter(
+ scoped_ptr<BluetoothDiscoveryFilter> discovery_filter,
+ const DiscoverySessionCallback& callback,
+ const ErrorCallback& error_callback);
+
+ // Return all discovery filters assigned to this adapter merged together.
+ scoped_ptr<BluetoothDiscoveryFilter> GetMergedDiscoveryFilter() const;
+
+ // Works like GetMergedDiscoveryFilter, but doesn't take |masked_filter| into
+ // account. |masked_filter| is compared by pointer, and must be a member of
+ // active session.
+ scoped_ptr<BluetoothDiscoveryFilter> GetMergedDiscoveryFilterMasked(
+ BluetoothDiscoveryFilter* masked_filter) const;
// Requests the list of devices from the adapter. All devices are returned,
// including those currently connected and those paired. Use the returned
@@ -395,12 +409,22 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapter
// - If the count is greater than 1, decrement the count and return
// success.
//
+ // |discovery_filter| passed to AddDiscoverySession and RemoveDiscoverySession
+ // is owned by other objects and shall not be freed.
+ //
// These methods invoke |callback| for success and |error_callback| for
// failures.
- virtual void AddDiscoverySession(const base::Closure& callback,
+ virtual void AddDiscoverySession(BluetoothDiscoveryFilter* discovery_filter,
+ const base::Closure& callback,
const ErrorCallback& error_callback) = 0;
- virtual void RemoveDiscoverySession(const base::Closure& callback,
- const ErrorCallback& error_callback) = 0;
+ virtual void RemoveDiscoverySession(
+ BluetoothDiscoveryFilter* discovery_filter,
+ const base::Closure& callback,
+ const ErrorCallback& error_callback) = 0;
+ virtual void SetDiscoveryFilter(
+ scoped_ptr<BluetoothDiscoveryFilter> discovery_filter,
+ const base::Closure& callback,
+ const ErrorCallback& error_callback) = 0;
// Called by RemovePairingDelegate() in order to perform any class-specific
// internal functionality necessary to remove the pairing delegate, such as
@@ -409,7 +433,9 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapter
BluetoothDevice::PairingDelegate* pairing_delegate) = 0;
// Success callback passed to AddDiscoverySession by StartDiscoverySession.
- void OnStartDiscoverySession(const DiscoverySessionCallback& callback);
+ void OnStartDiscoverySession(
+ scoped_ptr<BluetoothDiscoveryFilter> discovery_filter,
+ const DiscoverySessionCallback& callback);
// Marks all known DiscoverySession instances as inactive. Called by
// BluetoothAdapter in the event that the adapter unexpectedly stops
@@ -435,6 +461,12 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapter
std::list<PairingDelegatePair> pairing_delegates_;
private:
+ // Return all discovery filters assigned to this adapter merged together.
+ // If |omit| is true, |discovery_filter| will not be processed.
+ scoped_ptr<BluetoothDiscoveryFilter> GetMergedDiscoveryFilterHelper(
+ const BluetoothDiscoveryFilter* discovery_filter,
+ bool omit) const;
+
// List of active DiscoverySession objects. This is used to notify sessions to
// become inactive in case of an unexpected change to the adapter discovery
// state. We keep raw pointers, with the invariant that a DiscoverySession
diff --git a/device/bluetooth/bluetooth_adapter_chromeos.cc b/device/bluetooth/bluetooth_adapter_chromeos.cc
index edd0f01..fce8f8b 100644
--- a/device/bluetooth/bluetooth_adapter_chromeos.cc
+++ b/device/bluetooth/bluetooth_adapter_chromeos.cc
@@ -36,6 +36,7 @@
using device::BluetoothAdapter;
using device::BluetoothAudioSink;
using device::BluetoothDevice;
+using device::BluetoothDiscoveryFilter;
using device::BluetoothSocket;
using device::BluetoothUUID;
@@ -1091,6 +1092,7 @@ void BluetoothAdapterChromeOS::OnPropertyChangeCompleted(
}
void BluetoothAdapterChromeOS::AddDiscoverySession(
+ BluetoothDiscoveryFilter* discovery_filter,
const base::Closure& callback,
const ErrorCallback& error_callback) {
if (!IsPresent()) {
@@ -1131,6 +1133,7 @@ void BluetoothAdapterChromeOS::AddDiscoverySession(
}
void BluetoothAdapterChromeOS::RemoveDiscoverySession(
+ BluetoothDiscoveryFilter* discovery_filter,
const base::Closure& callback,
const ErrorCallback& error_callback) {
if (!IsPresent()) {
@@ -1181,6 +1184,13 @@ void BluetoothAdapterChromeOS::RemoveDiscoverySession(
error_callback));
}
+void BluetoothAdapterChromeOS::SetDiscoveryFilter(
+ scoped_ptr<BluetoothDiscoveryFilter> discovery_filter,
+ const base::Closure& callback,
+ const ErrorCallback& error_callback) {
+ // TODO(jpawlowski): Implement
+}
+
void BluetoothAdapterChromeOS::OnStartDiscovery(
const base::Closure& callback,
const ErrorCallback& error_callback) {
@@ -1263,7 +1273,7 @@ void BluetoothAdapterChromeOS::ProcessQueuedDiscoveryRequests() {
VLOG(1) << "Process queued discovery request.";
DiscoveryCallbackPair callbacks = discovery_request_queue_.front();
discovery_request_queue_.pop();
- AddDiscoverySession(callbacks.first, callbacks.second);
+ AddDiscoverySession(nullptr, callbacks.first, callbacks.second);
// If the queued request resulted in a pending call, then let it
// asynchonously process the remaining queued requests once the pending
diff --git a/device/bluetooth/bluetooth_adapter_chromeos.h b/device/bluetooth/bluetooth_adapter_chromeos.h
index d8c1d9b..39a23de 100644
--- a/device/bluetooth/bluetooth_adapter_chromeos.h
+++ b/device/bluetooth/bluetooth_adapter_chromeos.h
@@ -23,6 +23,7 @@
#include "device/bluetooth/bluetooth_adapter.h"
#include "device/bluetooth/bluetooth_audio_sink.h"
#include "device/bluetooth/bluetooth_device.h"
+#include "device/bluetooth/bluetooth_discovery_session.h"
#include "device/bluetooth/bluetooth_export.h"
namespace device {
@@ -263,10 +264,17 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterChromeOS
bool success);
// BluetoothAdapter:
- void AddDiscoverySession(const base::Closure& callback,
+ void AddDiscoverySession(device::BluetoothDiscoveryFilter* discovery_filter,
+ const base::Closure& callback,
const ErrorCallback& error_callback) override;
- void RemoveDiscoverySession(const base::Closure& callback,
- const ErrorCallback& error_callback) override;
+ void RemoveDiscoverySession(
+ device::BluetoothDiscoveryFilter* discovery_filter,
+ const base::Closure& callback,
+ const ErrorCallback& error_callback) override;
+ void SetDiscoveryFilter(
+ scoped_ptr<device::BluetoothDiscoveryFilter> discovery_filter,
+ const base::Closure& callback,
+ const ErrorCallback& error_callback) override;
// Called by dbus:: on completion of the D-Bus method call to start discovery.
void OnStartDiscovery(const base::Closure& callback,
diff --git a/device/bluetooth/bluetooth_adapter_mac.h b/device/bluetooth/bluetooth_adapter_mac.h
index 52567b0..bca4389 100644
--- a/device/bluetooth/bluetooth_adapter_mac.h
+++ b/device/bluetooth/bluetooth_adapter_mac.h
@@ -95,10 +95,15 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterMac
// BluetoothAdapter:
void DeleteOnCorrectThread() const override;
- void AddDiscoverySession(const base::Closure& callback,
+ void AddDiscoverySession(BluetoothDiscoveryFilter* discovery_filter,
+ const base::Closure& callback,
const ErrorCallback& error_callback) override;
- void RemoveDiscoverySession(const base::Closure& callback,
+ void RemoveDiscoverySession(BluetoothDiscoveryFilter* discovery_filter,
+ const base::Closure& callback,
const ErrorCallback& error_callback) override;
+ void SetDiscoveryFilter(scoped_ptr<BluetoothDiscoveryFilter> discovery_filter,
+ const base::Closure& callback,
+ const ErrorCallback& error_callback) override;
void Init();
void InitForTest(scoped_refptr<base::SequencedTaskRunner> ui_task_runner);
diff --git a/device/bluetooth/bluetooth_adapter_mac.mm b/device/bluetooth/bluetooth_adapter_mac.mm
index fc75414..7c04a43 100644
--- a/device/bluetooth/bluetooth_adapter_mac.mm
+++ b/device/bluetooth/bluetooth_adapter_mac.mm
@@ -180,6 +180,7 @@ void BluetoothAdapterMac::DeleteOnCorrectThread() const {
}
void BluetoothAdapterMac::AddDiscoverySession(
+ BluetoothDiscoveryFilter* discovery_filter,
const base::Closure& callback,
const ErrorCallback& error_callback) {
DVLOG(1) << __func__;
@@ -207,6 +208,7 @@ void BluetoothAdapterMac::AddDiscoverySession(
}
void BluetoothAdapterMac::RemoveDiscoverySession(
+ BluetoothDiscoveryFilter* discovery_filter,
const base::Closure& callback,
const ErrorCallback& error_callback) {
DVLOG(1) << __func__;
@@ -236,6 +238,14 @@ void BluetoothAdapterMac::RemoveDiscoverySession(
callback.Run();
}
+void BluetoothAdapterMac::SetDiscoveryFilter(
+ scoped_ptr<BluetoothDiscoveryFilter> discovery_filter,
+ const base::Closure& callback,
+ const ErrorCallback& error_callback) {
+ NOTIMPLEMENTED();
+ error_callback.Run();
+}
+
void BluetoothAdapterMac::RemovePairingDelegateInternal(
BluetoothDevice::PairingDelegate* pairing_delegate) {
}
diff --git a/device/bluetooth/bluetooth_adapter_unittest.cc b/device/bluetooth/bluetooth_adapter_unittest.cc
index 5dd10b1..81e2dcb 100644
--- a/device/bluetooth/bluetooth_adapter_unittest.cc
+++ b/device/bluetooth/bluetooth_adapter_unittest.cc
@@ -2,9 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/bind.h"
#include "base/memory/ref_counted.h"
#include "device/bluetooth/bluetooth_adapter.h"
#include "device/bluetooth/bluetooth_device.h"
+#include "device/bluetooth/bluetooth_discovery_session.h"
#include "testing/gtest/include/gtest/gtest.h"
using device::BluetoothAdapter;
@@ -49,9 +51,15 @@ class TestBluetoothAdapter : public BluetoothAdapter {
void DeleteOnCorrectThread() const override { delete this; }
+ void StartDiscoverySessionWithFilter(
+ scoped_ptr<BluetoothDiscoveryFilter> discovery_filter,
+ const DiscoverySessionCallback& callback,
+ const ErrorCallback& error_callback) override {
+ OnStartDiscoverySession(discovery_filter.Pass(), callback);
+ }
+
void StartDiscoverySession(const DiscoverySessionCallback& callback,
const ErrorCallback& error_callback) override {}
-
void CreateRfcommService(
const BluetoothUUID& uuid,
const ServiceOptions& options,
@@ -69,15 +77,42 @@ class TestBluetoothAdapter : public BluetoothAdapter {
const AcquiredCallback& callback,
const BluetoothAudioSink::ErrorCallback& error_callback) override {}
+ void TestErrorCallback() {}
+
+ ScopedVector<BluetoothDiscoverySession> discovery_sessions_;
+
+ void TestOnStartDiscoverySession(
+ scoped_ptr<device::BluetoothDiscoverySession> discovery_session) {
+ discovery_sessions_.push_back(discovery_session.Pass());
+ }
+
+ void CleanupSessions() { discovery_sessions_.clear(); }
+
+ void InjectFilteredSession(
+ scoped_ptr<device::BluetoothDiscoveryFilter> discovery_filter) {
+ StartDiscoverySessionWithFilter(
+ discovery_filter.Pass(),
+ base::Bind(&TestBluetoothAdapter::TestOnStartDiscoverySession,
+ base::Unretained(this)),
+ base::Bind(&TestBluetoothAdapter::TestErrorCallback,
+ base::Unretained(this)));
+ }
+
protected:
~TestBluetoothAdapter() override {}
- void AddDiscoverySession(const base::Closure& callback,
+ void AddDiscoverySession(BluetoothDiscoveryFilter* discovery_filter,
+ const base::Closure& callback,
const ErrorCallback& error_callback) override {}
- void RemoveDiscoverySession(const base::Closure& callback,
+ void RemoveDiscoverySession(BluetoothDiscoveryFilter* discovery_filter,
+ const base::Closure& callback,
const ErrorCallback& error_callback) override {}
+ void SetDiscoveryFilter(scoped_ptr<BluetoothDiscoveryFilter> discovery_filter,
+ const base::Closure& callback,
+ const ErrorCallback& error_callback) override {}
+
void RemovePairingDelegateInternal(
BluetoothDevice::PairingDelegate* pairing_delegate) override {}
};
@@ -162,4 +197,202 @@ TEST(BluetoothAdapterTest, UnregisterDelegate) {
EXPECT_TRUE(adapter->DefaultPairingDelegate() == NULL);
}
+TEST(BluetoothAdapterTest, GetMergedDiscoveryFilterEmpty) {
+ scoped_refptr<BluetoothAdapter> adapter = new TestBluetoothAdapter();
+ scoped_ptr<BluetoothDiscoveryFilter> discovery_filter;
+
+ discovery_filter = adapter->GetMergedDiscoveryFilter();
+ EXPECT_TRUE(discovery_filter.get() == nullptr);
+
+ discovery_filter = adapter->GetMergedDiscoveryFilterMasked(nullptr);
+ EXPECT_TRUE(discovery_filter.get() == nullptr);
+}
+
+TEST(BluetoothAdapterTest, GetMergedDiscoveryFilterRegular) {
+ scoped_refptr<TestBluetoothAdapter> adapter = new TestBluetoothAdapter();
+ scoped_ptr<BluetoothDiscoveryFilter> discovery_filter;
+
+ // make sure adapter have one session wihout filtering.
+ adapter->InjectFilteredSession(discovery_filter.Pass());
+
+ // having one reglar session should result in no filter
+ scoped_ptr<BluetoothDiscoveryFilter> resulting_filter =
+ adapter->GetMergedDiscoveryFilter();
+ EXPECT_TRUE(resulting_filter.get() == nullptr);
+
+ // omiting no filter when having one reglar session should result in no filter
+ resulting_filter = adapter->GetMergedDiscoveryFilterMasked(nullptr);
+ EXPECT_TRUE(resulting_filter.get() == nullptr);
+
+ adapter->CleanupSessions();
+}
+
+TEST(BluetoothAdapterTest, GetMergedDiscoveryFilterRssi) {
+ scoped_refptr<TestBluetoothAdapter> adapter = new TestBluetoothAdapter();
+ int16_t resulting_rssi;
+ uint16_t resulting_pathloss;
+ scoped_ptr<BluetoothDiscoveryFilter> resulting_filter;
+
+ BluetoothDiscoveryFilter* df = new BluetoothDiscoveryFilter(
+ BluetoothDiscoveryFilter::Transport::TRANSPORT_LE);
+ df->SetRSSI(-30);
+ scoped_ptr<BluetoothDiscoveryFilter> discovery_filter(df);
+
+ BluetoothDiscoveryFilter* df2 = new BluetoothDiscoveryFilter(
+ BluetoothDiscoveryFilter::Transport::TRANSPORT_LE);
+ df2->SetRSSI(-65);
+ scoped_ptr<BluetoothDiscoveryFilter> discovery_filter2(df2);
+
+ // make sure adapter have one session wihout filtering.
+ adapter->InjectFilteredSession(discovery_filter.Pass());
+
+ // DO_NOTHING should have no impact
+ resulting_filter = adapter->GetMergedDiscoveryFilter();
+ resulting_filter->GetRSSI(&resulting_rssi);
+ EXPECT_EQ(-30, resulting_rssi);
+
+ // should not use df2 at all, as it's not associated with adapter yet
+ resulting_filter = adapter->GetMergedDiscoveryFilterMasked(df2);
+ resulting_filter->GetRSSI(&resulting_rssi);
+ EXPECT_EQ(-30, resulting_rssi);
+
+ adapter->InjectFilteredSession(discovery_filter2.Pass());
+
+ // result of merging two rssi values should be lower one
+ resulting_filter = adapter->GetMergedDiscoveryFilter();
+ resulting_filter->GetRSSI(&resulting_rssi);
+ EXPECT_EQ(-65, resulting_rssi);
+
+ // ommit bigger value, result should stay same
+ resulting_filter = adapter->GetMergedDiscoveryFilterMasked(df);
+ resulting_filter->GetRSSI(&resulting_rssi);
+ EXPECT_EQ(-65, resulting_rssi);
+
+ // ommit lower value, result should change
+ resulting_filter = adapter->GetMergedDiscoveryFilterMasked(df2);
+ resulting_filter->GetRSSI(&resulting_rssi);
+ EXPECT_EQ(-30, resulting_rssi);
+
+ BluetoothDiscoveryFilter* df3 = new BluetoothDiscoveryFilter(
+ BluetoothDiscoveryFilter::Transport::TRANSPORT_LE);
+ df3->SetPathloss(60);
+ scoped_ptr<BluetoothDiscoveryFilter> discovery_filter3(df3);
+
+ // when rssi and pathloss are merged, both should be cleared, becuase there is
+ // no way to tell which filter will be more generic
+ adapter->InjectFilteredSession(discovery_filter3.Pass());
+ resulting_filter = adapter->GetMergedDiscoveryFilter();
+ EXPECT_FALSE(resulting_filter->GetRSSI(&resulting_rssi));
+ EXPECT_FALSE(resulting_filter->GetPathloss(&resulting_pathloss));
+
+ adapter->CleanupSessions();
+}
+
+TEST(BluetoothAdapterTest, GetMergedDiscoveryFilterTransport) {
+ scoped_refptr<TestBluetoothAdapter> adapter = new TestBluetoothAdapter();
+ scoped_ptr<BluetoothDiscoveryFilter> resulting_filter;
+
+ BluetoothDiscoveryFilter* df = new BluetoothDiscoveryFilter(
+ BluetoothDiscoveryFilter::Transport::TRANSPORT_CLASSIC);
+ scoped_ptr<BluetoothDiscoveryFilter> discovery_filter(df);
+
+ BluetoothDiscoveryFilter* df2 = new BluetoothDiscoveryFilter(
+ BluetoothDiscoveryFilter::Transport::TRANSPORT_LE);
+ scoped_ptr<BluetoothDiscoveryFilter> discovery_filter2(df2);
+
+ adapter->InjectFilteredSession(discovery_filter.Pass());
+
+ // Just one filter, make sure transport was properly rewritten
+ resulting_filter = adapter->GetMergedDiscoveryFilter();
+ EXPECT_EQ(BluetoothDiscoveryFilter::Transport::TRANSPORT_CLASSIC,
+ resulting_filter->GetTransport());
+
+ adapter->InjectFilteredSession(discovery_filter2.Pass());
+
+ // Two filters, should have OR of both transport's
+ resulting_filter = adapter->GetMergedDiscoveryFilter();
+ EXPECT_EQ(BluetoothDiscoveryFilter::Transport::TRANSPORT_DUAL,
+ resulting_filter->GetTransport());
+
+ // When 1st filter is masked, 2nd filter transport should be returned.
+ resulting_filter = adapter->GetMergedDiscoveryFilterMasked(df);
+ EXPECT_EQ(BluetoothDiscoveryFilter::Transport::TRANSPORT_LE,
+ resulting_filter->GetTransport());
+
+ // When 2nd filter is masked, 1st filter transport should be returned.
+ resulting_filter = adapter->GetMergedDiscoveryFilterMasked(df2);
+ EXPECT_EQ(BluetoothDiscoveryFilter::Transport::TRANSPORT_CLASSIC,
+ resulting_filter->GetTransport());
+
+ BluetoothDiscoveryFilter* df3 = new BluetoothDiscoveryFilter(
+ BluetoothDiscoveryFilter::Transport::TRANSPORT_LE);
+ df3->CopyFrom(BluetoothDiscoveryFilter(
+ BluetoothDiscoveryFilter::Transport::TRANSPORT_DUAL));
+ scoped_ptr<BluetoothDiscoveryFilter> discovery_filter3(df3);
+
+ // Merging empty filter in should result in empty filter
+ adapter->InjectFilteredSession(discovery_filter3.Pass());
+ resulting_filter = adapter->GetMergedDiscoveryFilter();
+ EXPECT_TRUE(resulting_filter->IsDefault());
+
+ adapter->CleanupSessions();
+}
+
+TEST(BluetoothAdapterTest, GetMergedDiscoveryFilterAllFields) {
+ scoped_refptr<TestBluetoothAdapter> adapter = new TestBluetoothAdapter();
+ int16_t resulting_rssi;
+ std::set<device::BluetoothUUID> resulting_uuids;
+
+ BluetoothDiscoveryFilter* df = new BluetoothDiscoveryFilter(
+ BluetoothDiscoveryFilter::Transport::TRANSPORT_LE);
+ df->SetRSSI(-60);
+ df->AddUUID(device::BluetoothUUID("1000"));
+ scoped_ptr<BluetoothDiscoveryFilter> discovery_filter(df);
+
+ BluetoothDiscoveryFilter* df2 = new BluetoothDiscoveryFilter(
+ BluetoothDiscoveryFilter::Transport::TRANSPORT_LE);
+ df2->SetRSSI(-85);
+ df2->SetTransport(BluetoothDiscoveryFilter::Transport::TRANSPORT_LE);
+ df2->AddUUID(device::BluetoothUUID("1020"));
+ df2->AddUUID(device::BluetoothUUID("1001"));
+ scoped_ptr<BluetoothDiscoveryFilter> discovery_filter2(df2);
+
+ BluetoothDiscoveryFilter* df3 = new BluetoothDiscoveryFilter(
+ BluetoothDiscoveryFilter::Transport::TRANSPORT_LE);
+ df3->SetRSSI(-65);
+ df3->SetTransport(BluetoothDiscoveryFilter::Transport::TRANSPORT_CLASSIC);
+ df3->AddUUID(device::BluetoothUUID("1020"));
+ df3->AddUUID(device::BluetoothUUID("1003"));
+ scoped_ptr<BluetoothDiscoveryFilter> discovery_filter3(df3);
+
+ // make sure adapter have one session wihout filtering.
+ adapter->InjectFilteredSession(discovery_filter.Pass());
+ adapter->InjectFilteredSession(discovery_filter2.Pass());
+ adapter->InjectFilteredSession(discovery_filter3.Pass());
+
+ scoped_ptr<BluetoothDiscoveryFilter> resulting_filter =
+ adapter->GetMergedDiscoveryFilter();
+ resulting_filter->GetRSSI(&resulting_rssi);
+ resulting_filter->GetUUIDs(resulting_uuids);
+ EXPECT_TRUE(resulting_filter->GetTransport());
+ EXPECT_EQ(BluetoothDiscoveryFilter::Transport::TRANSPORT_DUAL,
+ resulting_filter->GetTransport());
+ EXPECT_EQ(-85, resulting_rssi);
+ EXPECT_EQ(4UL, resulting_uuids.size());
+ EXPECT_TRUE(resulting_uuids.find(device::BluetoothUUID("1000")) !=
+ resulting_uuids.end());
+ EXPECT_TRUE(resulting_uuids.find(device::BluetoothUUID("1001")) !=
+ resulting_uuids.end());
+ EXPECT_TRUE(resulting_uuids.find(device::BluetoothUUID("1003")) !=
+ resulting_uuids.end());
+ EXPECT_TRUE(resulting_uuids.find(device::BluetoothUUID("1020")) !=
+ resulting_uuids.end());
+
+ resulting_filter = adapter->GetMergedDiscoveryFilterMasked(df);
+ EXPECT_EQ(BluetoothDiscoveryFilter::Transport::TRANSPORT_DUAL,
+ resulting_filter->GetTransport());
+
+ adapter->CleanupSessions();
+}
+
} // namespace device
diff --git a/device/bluetooth/bluetooth_adapter_win.cc b/device/bluetooth/bluetooth_adapter_win.cc
index fb28d7c..a9fc200 100644
--- a/device/bluetooth/bluetooth_adapter_win.cc
+++ b/device/bluetooth/bluetooth_adapter_win.cc
@@ -300,6 +300,7 @@ void BluetoothAdapterWin::DeleteOnCorrectThread() const {
// If the method is called when |discovery_status_| is DISCOVERY_STOPPING,
// starting again is handled by BluetoothAdapterWin::DiscoveryStopped().
void BluetoothAdapterWin::AddDiscoverySession(
+ BluetoothDiscoveryFilter* discovery_filter,
const base::Closure& callback,
const ErrorCallback& error_callback) {
if (discovery_status_ == DISCOVERING) {
@@ -313,6 +314,7 @@ void BluetoothAdapterWin::AddDiscoverySession(
}
void BluetoothAdapterWin::RemoveDiscoverySession(
+ BluetoothDiscoveryFilter* discovery_filter,
const base::Closure& callback,
const ErrorCallback& error_callback) {
if (discovery_status_ == NOT_DISCOVERING) {
@@ -323,6 +325,14 @@ void BluetoothAdapterWin::RemoveDiscoverySession(
MaybePostStopDiscoveryTask();
}
+void BluetoothAdapterWin::SetDiscoveryFilter(
+ scoped_ptr<BluetoothDiscoveryFilter> discovery_filter,
+ const base::Closure& callback,
+ const ErrorCallback& error_callback) {
+ NOTIMPLEMENTED();
+ error_callback.Run();
+}
+
void BluetoothAdapterWin::Init() {
ui_task_runner_ = base::ThreadTaskRunnerHandle::Get();
socket_thread_ = BluetoothSocketThread::Get();
diff --git a/device/bluetooth/bluetooth_adapter_win.h b/device/bluetooth/bluetooth_adapter_win.h
index 72280ee..2b086a2 100644
--- a/device/bluetooth/bluetooth_adapter_win.h
+++ b/device/bluetooth/bluetooth_adapter_win.h
@@ -18,6 +18,7 @@
#include "base/threading/thread_checker.h"
#include "device/bluetooth/bluetooth_adapter.h"
#include "device/bluetooth/bluetooth_audio_sink.h"
+#include "device/bluetooth/bluetooth_discovery_session.h"
#include "device/bluetooth/bluetooth_export.h"
#include "device/bluetooth/bluetooth_task_manager_win.h"
@@ -112,9 +113,15 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterWin
// BluetoothAdapter:
void DeleteOnCorrectThread() const override;
virtual void AddDiscoverySession(
+ BluetoothDiscoveryFilter* discovery_filter,
const base::Closure& callback,
const ErrorCallback& error_callback) override;
virtual void RemoveDiscoverySession(
+ BluetoothDiscoveryFilter* discovery_filter,
+ const base::Closure& callback,
+ const ErrorCallback& error_callback) override;
+ virtual void SetDiscoveryFilter(
+ scoped_ptr<BluetoothDiscoveryFilter> discovery_filter,
const base::Closure& callback,
const ErrorCallback& error_callback) override;
diff --git a/device/bluetooth/bluetooth_adapter_win_unittest.cc b/device/bluetooth/bluetooth_adapter_win_unittest.cc
index 4a7abd7..670a03d 100644
--- a/device/bluetooth/bluetooth_adapter_win_unittest.cc
+++ b/device/bluetooth/bluetooth_adapter_win_unittest.cc
@@ -154,13 +154,13 @@ class BluetoothAdapterWinTest : public testing::Test {
void CallAddDiscoverySession(
const base::Closure& callback,
const BluetoothAdapter::ErrorCallback& error_callback) {
- adapter_win_->AddDiscoverySession(callback, error_callback);
+ adapter_win_->AddDiscoverySession(nullptr, callback, error_callback);
}
void CallRemoveDiscoverySession(
const base::Closure& callback,
const BluetoothAdapter::ErrorCallback& error_callback) {
- adapter_win_->RemoveDiscoverySession(callback, error_callback);
+ adapter_win_->RemoveDiscoverySession(nullptr, callback, error_callback);
}
protected:
diff --git a/device/bluetooth/bluetooth_chromeos_unittest.cc b/device/bluetooth/bluetooth_chromeos_unittest.cc
index da03501..535e047 100644
--- a/device/bluetooth/bluetooth_chromeos_unittest.cc
+++ b/device/bluetooth/bluetooth_chromeos_unittest.cc
@@ -3251,11 +3251,13 @@ TEST_F(BluetoothChromeOSTest, Shutdown) {
EXPECT_EQ(0, callback_count_) << "OnPropertyChangeCompleted error";
EXPECT_EQ(1, error_callback_count_--) << "OnPropertyChangeCompleted error";
- adapter_chrome_os->AddDiscoverySession(GetCallback(), GetErrorCallback());
+ adapter_chrome_os->AddDiscoverySession(nullptr, GetCallback(),
+ GetErrorCallback());
EXPECT_EQ(0, callback_count_) << "AddDiscoverySession error";
EXPECT_EQ(1, error_callback_count_--) << "AddDiscoverySession error";
- adapter_chrome_os->RemoveDiscoverySession(GetCallback(), GetErrorCallback());
+ adapter_chrome_os->RemoveDiscoverySession(nullptr, GetCallback(),
+ GetErrorCallback());
EXPECT_EQ(0, callback_count_) << "RemoveDiscoverySession error";
EXPECT_EQ(1, error_callback_count_--) << "RemoveDiscoverySession error";
@@ -3321,7 +3323,8 @@ TEST_F(BluetoothChromeOSTest, Shutdown_OnStartDiscovery) {
static_cast<BluetoothAdapterChromeOS*>(adapter_.get());
for (int i = 0; i < kNumberOfDiscoverySessions; i++) {
- adapter_chrome_os->AddDiscoverySession(GetCallback(), GetErrorCallback());
+ adapter_chrome_os->AddDiscoverySession(nullptr, GetCallback(),
+ GetErrorCallback());
}
adapter_->Shutdown();
adapter_chrome_os->OnStartDiscovery(GetCallback(), GetErrorCallback());
@@ -3338,7 +3341,8 @@ TEST_F(BluetoothChromeOSTest, Shutdown_OnStartDiscoveryError) {
static_cast<BluetoothAdapterChromeOS*>(adapter_.get());
for (int i = 0; i < kNumberOfDiscoverySessions; i++) {
- adapter_chrome_os->AddDiscoverySession(GetCallback(), GetErrorCallback());
+ adapter_chrome_os->AddDiscoverySession(nullptr, GetCallback(),
+ GetErrorCallback());
}
adapter_->Shutdown();
adapter_chrome_os->OnStartDiscoveryError(GetCallback(), GetErrorCallback(),
@@ -3357,14 +3361,17 @@ TEST_F(BluetoothChromeOSTest, Shutdown_OnStopDiscovery) {
// In order to queue up discovery sessions before an OnStopDiscovery call
// RemoveDiscoverySession must be called, so Add, Start, and Remove:
- adapter_chrome_os->AddDiscoverySession(GetCallback(), GetErrorCallback());
+ adapter_chrome_os->AddDiscoverySession(nullptr, GetCallback(),
+ GetErrorCallback());
adapter_chrome_os->OnStartDiscovery(GetCallback(), GetErrorCallback());
- adapter_chrome_os->RemoveDiscoverySession(GetCallback(), GetErrorCallback());
+ adapter_chrome_os->RemoveDiscoverySession(nullptr, GetCallback(),
+ GetErrorCallback());
callback_count_ = 0;
error_callback_count_ = 0;
// Can now queue discovery sessions while waiting for OnStopDiscovery.
for (int i = 0; i < kNumberOfDiscoverySessions; i++) {
- adapter_chrome_os->AddDiscoverySession(GetCallback(), GetErrorCallback());
+ adapter_chrome_os->AddDiscoverySession(nullptr, GetCallback(),
+ GetErrorCallback());
}
adapter_->Shutdown();
adapter_chrome_os->OnStopDiscovery(GetCallback());
@@ -3384,14 +3391,17 @@ TEST_F(BluetoothChromeOSTest, Shutdown_OnStopDiscoveryError) {
// In order to queue up discovery sessions before an OnStopDiscoveryError call
// RemoveDiscoverySession must be called, so Add, Start, and Remove:
- adapter_chrome_os->AddDiscoverySession(GetCallback(), GetErrorCallback());
+ adapter_chrome_os->AddDiscoverySession(nullptr, GetCallback(),
+ GetErrorCallback());
adapter_chrome_os->OnStartDiscovery(GetCallback(), GetErrorCallback());
- adapter_chrome_os->RemoveDiscoverySession(GetCallback(), GetErrorCallback());
+ adapter_chrome_os->RemoveDiscoverySession(nullptr, GetCallback(),
+ GetErrorCallback());
callback_count_ = 0;
error_callback_count_ = 0;
// Can now queue discovery sessions while waiting for OnStopDiscoveryError.
for (int i = 0; i < kNumberOfDiscoverySessions; i++) {
- adapter_chrome_os->AddDiscoverySession(GetCallback(), GetErrorCallback());
+ adapter_chrome_os->AddDiscoverySession(nullptr, GetCallback(),
+ GetErrorCallback());
}
adapter_->Shutdown();
adapter_chrome_os->OnStopDiscoveryError(GetErrorCallback(), "", "");
diff --git a/device/bluetooth/bluetooth_discovery_filter_unittest.cc b/device/bluetooth/bluetooth_discovery_filter_unittest.cc
new file mode 100644
index 0000000..ea7a04f
--- /dev/null
+++ b/device/bluetooth/bluetooth_discovery_filter_unittest.cc
@@ -0,0 +1,181 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/macros.h"
+#include "device/bluetooth/bluetooth_discovery_session.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+const device::BluetoothUUID uuid1003("1003");
+const device::BluetoothUUID uuid1004("1004");
+const device::BluetoothUUID uuid1020("1020");
+
+} // namespace
+
+namespace device {
+
+TEST(BluetoothDiscoveryFilterTest, Equal) {
+ BluetoothDiscoveryFilter df1(
+ BluetoothDiscoveryFilter::Transport::TRANSPORT_CLASSIC);
+ df1.SetRSSI(-65);
+ df1.AddUUID(uuid1020);
+ df1.AddUUID(uuid1003);
+
+ BluetoothDiscoveryFilter df2(
+ BluetoothDiscoveryFilter::Transport::TRANSPORT_CLASSIC);
+ df2.SetRSSI(-65);
+ df2.AddUUID(uuid1020);
+ df2.AddUUID(uuid1004);
+
+ // uuids are not same, so should fail
+ ASSERT_FALSE(df1.Equals(df2));
+
+ // make filters equal
+ df1.AddUUID(uuid1004);
+ df2.AddUUID(uuid1003);
+ ASSERT_TRUE(df1.Equals(df2));
+
+ // now transport don't match
+ df1.SetTransport(BluetoothDiscoveryFilter::Transport::TRANSPORT_LE);
+ ASSERT_FALSE(df1.Equals(df2));
+
+ // now everything is back matching
+ df1.SetTransport(BluetoothDiscoveryFilter::Transport::TRANSPORT_CLASSIC);
+ ASSERT_TRUE(df1.Equals(df2));
+
+ // now rssi don't match
+ df1.SetRSSI(-30);
+ ASSERT_FALSE(df1.Equals(df2));
+
+ BluetoothDiscoveryFilter df3(
+ BluetoothDiscoveryFilter::Transport::TRANSPORT_CLASSIC);
+ df3.SetPathloss(45);
+ df3.AddUUID(uuid1020);
+ df3.AddUUID(uuid1003);
+ df3.AddUUID(uuid1004);
+
+ // Having Pathloss and RSSI set in two different filter makes them unequal.
+ ASSERT_FALSE(df1.Equals(df3));
+}
+
+TEST(BluetoothDiscoveryFilterTest, CopyFrom) {
+ BluetoothDiscoveryFilter df1(
+ BluetoothDiscoveryFilter::Transport::TRANSPORT_CLASSIC);
+ df1.SetRSSI(-65);
+ df1.AddUUID(uuid1020);
+ df1.AddUUID(uuid1003);
+
+ BluetoothDiscoveryFilter df2(
+ BluetoothDiscoveryFilter::Transport::TRANSPORT_CLASSIC);
+
+ df2.CopyFrom(df1);
+
+ int16_t out_rssi;
+ std::set<device::BluetoothUUID> out_uuids;
+
+ // make sure all properties were copied
+ df2.GetRSSI(&out_rssi);
+ EXPECT_EQ(-65, out_rssi);
+
+ EXPECT_EQ(BluetoothDiscoveryFilter::Transport::TRANSPORT_CLASSIC,
+ df2.GetTransport());
+
+ df2.GetUUIDs(out_uuids);
+ EXPECT_TRUE(out_uuids.find(uuid1020) != out_uuids.end());
+ EXPECT_TRUE(out_uuids.find(uuid1003) != out_uuids.end());
+}
+
+TEST(BluetoothDiscoveryFilterTest, MergeUUIDs) {
+ BluetoothDiscoveryFilter df1(
+ BluetoothDiscoveryFilter::Transport::TRANSPORT_LE);
+ df1.AddUUID(uuid1020);
+ df1.AddUUID(uuid1003);
+
+ BluetoothDiscoveryFilter df2(
+ BluetoothDiscoveryFilter::Transport::TRANSPORT_LE);
+ df2.AddUUID(uuid1020);
+ df2.AddUUID(uuid1004);
+
+ scoped_ptr<BluetoothDiscoveryFilter> df3 =
+ BluetoothDiscoveryFilter::Merge(&df1, &df2);
+
+ // df3 should contain all uuids from df1 and df2
+ std::set<device::BluetoothUUID> out_uuids;
+ df3->GetUUIDs(out_uuids);
+ EXPECT_TRUE(out_uuids.find(uuid1020) != out_uuids.end());
+ EXPECT_TRUE(out_uuids.find(uuid1003) != out_uuids.end());
+ EXPECT_TRUE(out_uuids.find(uuid1004) != out_uuids.end());
+
+ // Merging with empty filter would return empty filter
+ df3 = BluetoothDiscoveryFilter::Merge(&df1, nullptr);
+ df3->GetUUIDs(out_uuids);
+ EXPECT_EQ(0UL, out_uuids.size());
+ EXPECT_TRUE(df3->IsDefault());
+}
+
+TEST(BluetoothDiscoveryFilterTest, MergeProximity) {
+ BluetoothDiscoveryFilter df1(
+ BluetoothDiscoveryFilter::Transport::TRANSPORT_LE);
+ df1.SetRSSI(-50);
+
+ BluetoothDiscoveryFilter df2(
+ BluetoothDiscoveryFilter::Transport::TRANSPORT_LE);
+ df2.SetRSSI(-70);
+
+ BluetoothDiscoveryFilter df3(
+ BluetoothDiscoveryFilter::Transport::TRANSPORT_LE);
+ df3.SetPathloss(70);
+
+ BluetoothDiscoveryFilter df4(
+ BluetoothDiscoveryFilter::Transport::TRANSPORT_LE);
+ df4.SetPathloss(20);
+
+ scoped_ptr<BluetoothDiscoveryFilter> result =
+ BluetoothDiscoveryFilter::Merge(&df1, &df2);
+
+ int16_t out_rssi;
+ // Merging RSSI should return smaller of both values
+ EXPECT_TRUE(result->GetRSSI(&out_rssi));
+ EXPECT_EQ(-70, out_rssi);
+
+ uint16_t out_pathloss;
+ // Merging RSSI with Pathloss should clear proximity
+ result = BluetoothDiscoveryFilter::Merge(&df1, &df3);
+ EXPECT_FALSE(result->GetRSSI(&out_rssi));
+ EXPECT_FALSE(result->GetPathloss(&out_pathloss));
+
+ // Merging Pathloss should return bigger of both values
+ result = BluetoothDiscoveryFilter::Merge(&df3, &df4);
+ EXPECT_TRUE(result->GetPathloss(&out_pathloss));
+ EXPECT_EQ(70, out_pathloss);
+}
+
+TEST(BluetoothDiscoveryFilterTest, MergeTransport) {
+ BluetoothDiscoveryFilter df1(
+ BluetoothDiscoveryFilter::Transport::TRANSPORT_CLASSIC);
+
+ BluetoothDiscoveryFilter df2(
+ BluetoothDiscoveryFilter::Transport::TRANSPORT_LE);
+
+ BluetoothDiscoveryFilter df3(
+ BluetoothDiscoveryFilter::Transport::TRANSPORT_DUAL);
+
+ scoped_ptr<BluetoothDiscoveryFilter> result =
+ BluetoothDiscoveryFilter::Merge(&df1, &df2);
+
+ // Merging LE and CLASSIC should result in both being set
+ EXPECT_EQ(BluetoothDiscoveryFilter::Transport::TRANSPORT_DUAL,
+ result->GetTransport());
+
+ result = BluetoothDiscoveryFilter::Merge(&df1, &df3);
+ EXPECT_EQ(BluetoothDiscoveryFilter::Transport::TRANSPORT_DUAL,
+ result->GetTransport());
+
+ // Merging with null should alway result with empty filter.
+ result = BluetoothDiscoveryFilter::Merge(&df1, nullptr);
+ EXPECT_TRUE(result->IsDefault());
+}
+
+} // namespace device
diff --git a/device/bluetooth/bluetooth_discovery_session.cc b/device/bluetooth/bluetooth_discovery_session.cc
index bfcc59f..e30f86c 100644
--- a/device/bluetooth/bluetooth_discovery_session.cc
+++ b/device/bluetooth/bluetooth_discovery_session.cc
@@ -9,9 +9,180 @@
namespace device {
+BluetoothDiscoveryFilter::BluetoothDiscoveryFilter(TransportMask transport) {
+ SetTransport(transport);
+}
+
+BluetoothDiscoveryFilter::~BluetoothDiscoveryFilter() {
+}
+
+bool BluetoothDiscoveryFilter::GetRSSI(int16_t* out_rssi) const {
+ DCHECK(out_rssi);
+ if (!rssi_.get())
+ return false;
+
+ *out_rssi = *rssi_;
+ return true;
+}
+
+void BluetoothDiscoveryFilter::SetRSSI(int16_t rssi) {
+ if (!rssi_.get())
+ rssi_.reset(new int16_t());
+
+ *rssi_ = rssi;
+}
+
+bool BluetoothDiscoveryFilter::GetPathloss(uint16_t* out_pathloss) const {
+ DCHECK(out_pathloss);
+ if (!pathloss_.get())
+ return false;
+
+ *out_pathloss = *pathloss_;
+ return true;
+}
+
+void BluetoothDiscoveryFilter::SetPathloss(uint16_t pathloss) {
+ if (!pathloss_.get())
+ pathloss_.reset(new uint16_t());
+
+ *pathloss_ = pathloss;
+}
+
+BluetoothDiscoveryFilter::TransportMask BluetoothDiscoveryFilter::GetTransport()
+ const {
+ return transport_;
+}
+
+void BluetoothDiscoveryFilter::SetTransport(TransportMask transport) {
+ DCHECK(transport > 0 && transport < 4);
+ transport_ = transport;
+}
+
+void BluetoothDiscoveryFilter::GetUUIDs(
+ std::set<device::BluetoothUUID>& out_uuids) const {
+ out_uuids.clear();
+
+ for (auto& uuid : uuids_)
+ out_uuids.insert(*uuid);
+}
+
+void BluetoothDiscoveryFilter::AddUUID(const device::BluetoothUUID& uuid) {
+ DCHECK(uuid.IsValid());
+ for (auto& uuid_it : uuids_) {
+ if (*uuid_it == uuid)
+ return;
+ }
+
+ uuids_.push_back(new device::BluetoothUUID(uuid));
+}
+
+void BluetoothDiscoveryFilter::CopyFrom(
+ const BluetoothDiscoveryFilter& filter) {
+ transport_ = filter.transport_;
+
+ if (filter.uuids_.size()) {
+ for (auto& uuid : filter.uuids_)
+ AddUUID(*uuid);
+ } else
+ uuids_.clear();
+
+ if (filter.rssi_.get()) {
+ SetRSSI(*filter.rssi_);
+ } else
+ rssi_.reset();
+
+ if (filter.pathloss_.get()) {
+ SetPathloss(*filter.pathloss_);
+ } else
+ pathloss_.reset();
+}
+
+scoped_ptr<device::BluetoothDiscoveryFilter> BluetoothDiscoveryFilter::Merge(
+ const device::BluetoothDiscoveryFilter* filter_a,
+ const device::BluetoothDiscoveryFilter* filter_b) {
+ scoped_ptr<BluetoothDiscoveryFilter> result;
+
+ if (!filter_a && !filter_b) {
+ return result;
+ }
+
+ result.reset(new BluetoothDiscoveryFilter(Transport::TRANSPORT_DUAL));
+
+ if (!filter_a || !filter_b || filter_a->IsDefault() ||
+ filter_b->IsDefault()) {
+ return result;
+ }
+
+ // both filters are not empty, so they must have transport set.
+ result->SetTransport(filter_a->transport_ | filter_b->transport_);
+
+ // if both filters have uuids, them merge them. Otherwise uuids filter should
+ // be left empty
+ if (filter_a->uuids_.size() && filter_b->uuids_.size()) {
+ std::set<device::BluetoothUUID> uuids;
+ filter_a->GetUUIDs(uuids);
+ for (auto& uuid : uuids)
+ result->AddUUID(uuid);
+
+ filter_b->GetUUIDs(uuids);
+ for (auto& uuid : uuids)
+ result->AddUUID(uuid);
+ }
+
+ if ((filter_a->rssi_.get() && filter_b->pathloss_.get()) ||
+ (filter_a->pathloss_.get() && filter_b->rssi_.get())) {
+ // if both rssi and pathloss filtering is enabled in two different
+ // filters, we can't tell which filter is more generic, and we don't set
+ // proximity filtering on merged filter.
+ return result;
+ }
+
+ if (filter_a->rssi_.get() && filter_b->rssi_.get()) {
+ result->SetRSSI(std::min(*filter_a->rssi_, *filter_b->rssi_));
+ } else if (filter_a->pathloss_.get() && filter_b->pathloss_.get()) {
+ result->SetPathloss(std::max(*filter_a->pathloss_, *filter_b->pathloss_));
+ }
+
+ return result;
+}
+
+bool BluetoothDiscoveryFilter::Equals(
+ const BluetoothDiscoveryFilter& other) const {
+ if (((!!rssi_.get()) != (!!other.rssi_.get())) ||
+ (rssi_.get() && other.rssi_.get() && *rssi_ != *other.rssi_)) {
+ return false;
+ }
+
+ if (((!!pathloss_.get()) != (!!other.pathloss_.get())) ||
+ (pathloss_.get() && other.pathloss_.get() &&
+ *pathloss_ != *other.pathloss_)) {
+ return false;
+ }
+
+ if (transport_ != other.transport_)
+ return false;
+
+ std::set<device::BluetoothUUID> uuids_a, uuids_b;
+ GetUUIDs(uuids_a);
+ other.GetUUIDs(uuids_b);
+ if (uuids_a != uuids_b)
+ return false;
+
+ return true;
+}
+
+bool BluetoothDiscoveryFilter::IsDefault() const {
+ return !(rssi_.get() || pathloss_.get() || uuids_.size() ||
+ transport_ != Transport::TRANSPORT_DUAL);
+}
+
BluetoothDiscoverySession::BluetoothDiscoverySession(
- scoped_refptr<BluetoothAdapter> adapter)
- : active_(true), adapter_(adapter), weak_ptr_factory_(this) {
+ scoped_refptr<BluetoothAdapter> adapter,
+ scoped_ptr<BluetoothDiscoveryFilter> discovery_filter)
+ : active_(true),
+ adapter_(adapter),
+ discovery_filter_(discovery_filter.release()),
+ weak_ptr_factory_(this) {
DCHECK(adapter_.get());
}
@@ -36,14 +207,15 @@ void BluetoothDiscoverySession::Stop(
}
VLOG(1) << "Stopping device discovery session.";
adapter_->RemoveDiscoverySession(
+ discovery_filter_.get(),
base::Bind(&BluetoothDiscoverySession::OnStop,
- weak_ptr_factory_.GetWeakPtr(),
- callback),
+ weak_ptr_factory_.GetWeakPtr(), callback),
error_callback);
}
void BluetoothDiscoverySession::OnStop(const base::Closure& callback) {
MarkAsInactive();
+ discovery_filter_.reset();
callback.Run();
}
@@ -54,4 +226,18 @@ void BluetoothDiscoverySession::MarkAsInactive() {
adapter_->DiscoverySessionBecameInactive(this);
}
+void BluetoothDiscoverySession::SetDiscoveryFilter(
+ scoped_ptr<BluetoothDiscoveryFilter> discovery_filter,
+ const base::Closure& callback,
+ const ErrorCallback& error_callback) {
+ discovery_filter_.reset(discovery_filter.release());
+ adapter_->SetDiscoveryFilter(adapter_->GetMergedDiscoveryFilter().Pass(),
+ callback, error_callback);
+}
+
+const BluetoothDiscoveryFilter* BluetoothDiscoverySession::GetDiscoveryFilter()
+ const {
+ return discovery_filter_.get();
+}
+
} // namespace device
diff --git a/device/bluetooth/bluetooth_discovery_session.h b/device/bluetooth/bluetooth_discovery_session.h
index 2dae0de..d50bf9c 100644
--- a/device/bluetooth/bluetooth_discovery_session.h
+++ b/device/bluetooth/bluetooth_discovery_session.h
@@ -8,11 +8,67 @@
#include "base/callback.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
+#include "device/bluetooth/bluetooth_adapter.h"
#include "device/bluetooth/bluetooth_export.h"
namespace device {
-class BluetoothAdapter;
+// used to keep discovery filter that might be Used to limit reported devices.
+class DEVICE_BLUETOOTH_EXPORT BluetoothDiscoveryFilter {
+ public:
+ // Possible transports to use for scan filter.
+ enum Transport {
+ TRANSPORT_CLASSIC = 0x01,
+ TRANSPORT_LE = 0x02,
+ TRANSPORT_DUAL = (TRANSPORT_CLASSIC | TRANSPORT_LE)
+ };
+ using TransportMask = uint8_t;
+
+ BluetoothDiscoveryFilter(TransportMask transport);
+ ~BluetoothDiscoveryFilter();
+
+ // These getters return true when given field is set in filter, and copy this
+ // value to |out_*| parameter. If value is not set, returns false.
+ // Thes setters assign given value to proper filter field.
+ bool GetRSSI(int16_t* out_rssi) const;
+ void SetRSSI(int16_t rssi);
+ bool GetPathloss(uint16_t* out_pathloss) const;
+ void SetPathloss(uint16_t pathloss);
+
+ // Return and set transport field of this filter.
+ TransportMask GetTransport() const;
+ void SetTransport(TransportMask transport);
+
+ // Make |out_uuids| represent all uuids assigned to this filter.
+ void GetUUIDs(std::set<device::BluetoothUUID>& out_uuids) const;
+
+ // Add UUID to internal UUIDs filter. If UUIDs filter doesn't exist, it will
+ // be created.
+ void AddUUID(const device::BluetoothUUID& uuid);
+
+ // Copy content of |filter| and assigns it to this filter.
+ void CopyFrom(const BluetoothDiscoveryFilter& filter);
+
+ // Check if two filters are equal.
+ bool Equals(const BluetoothDiscoveryFilter& filter) const;
+
+ // Returns true if all fields in filter are empty
+ bool IsDefault() const;
+
+ // Returns result of merging two filters together. If at least one of the
+ // filters is NULL this will return an empty filter
+ static scoped_ptr<device::BluetoothDiscoveryFilter> Merge(
+ const device::BluetoothDiscoveryFilter* filter_a,
+ const device::BluetoothDiscoveryFilter* filter_b);
+
+ private:
+ scoped_ptr<int16_t> rssi_;
+ scoped_ptr<uint16_t> pathloss_;
+ TransportMask transport_;
+ ScopedVector<device::BluetoothUUID> uuids_;
+
+ DISALLOW_COPY_AND_ASSIGN(BluetoothDiscoveryFilter);
+};
// BluetoothDiscoverySession represents a current active or inactive device
// discovery session. Instances of this class are obtained by calling
@@ -58,8 +114,17 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothDiscoverySession {
virtual void Stop(const base::Closure& callback,
const ErrorCallback& error_callback);
+ virtual void SetDiscoveryFilter(
+ scoped_ptr<BluetoothDiscoveryFilter> discovery_filter,
+ const base::Closure& callback,
+ const ErrorCallback& error_callback);
+
+ virtual const BluetoothDiscoveryFilter* GetDiscoveryFilter() const;
+
protected:
- explicit BluetoothDiscoverySession(scoped_refptr<BluetoothAdapter> adapter);
+ explicit BluetoothDiscoverySession(
+ scoped_refptr<BluetoothAdapter> adapter,
+ scoped_ptr<BluetoothDiscoveryFilter> discovery_filter);
private:
friend class BluetoothAdapter;
@@ -78,6 +143,9 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothDiscoverySession {
// The adapter that created this instance.
scoped_refptr<BluetoothAdapter> adapter_;
+ // Filter assigned to this session, if any
+ scoped_ptr<BluetoothDiscoveryFilter> discovery_filter_;
+
// Note: This should remain the last member so it'll be destroyed and
// invalidate its weak pointers before any other members are destroyed.
base::WeakPtrFactory<BluetoothDiscoverySession> weak_ptr_factory_;
diff --git a/device/bluetooth/test/mock_bluetooth_adapter.cc b/device/bluetooth/test/mock_bluetooth_adapter.cc
index 2f797d3..1ee00ee 100644
--- a/device/bluetooth/test/mock_bluetooth_adapter.cc
+++ b/device/bluetooth/test/mock_bluetooth_adapter.cc
@@ -24,11 +24,21 @@ void MockBluetoothAdapter::DeleteOnCorrectThread() const {
};
void MockBluetoothAdapter::AddDiscoverySession(
+ BluetoothDiscoveryFilter* discovery_filter,
const base::Closure& callback,
- const ErrorCallback& error_callback) {}
+ const ErrorCallback& error_callback) {
+}
void MockBluetoothAdapter::RemoveDiscoverySession(
+ BluetoothDiscoveryFilter* discovery_filter,
const base::Closure& callback,
- const ErrorCallback& error_callback) {}
+ const ErrorCallback& error_callback) {
+}
+
+void MockBluetoothAdapter::SetDiscoveryFilter(
+ scoped_ptr<BluetoothDiscoveryFilter> discovery_filter,
+ const base::Closure& callback,
+ const ErrorCallback& error_callback) {
+}
} // namespace device
diff --git a/device/bluetooth/test/mock_bluetooth_adapter.h b/device/bluetooth/test/mock_bluetooth_adapter.h
index fd67936..d338256 100644
--- a/device/bluetooth/test/mock_bluetooth_adapter.h
+++ b/device/bluetooth/test/mock_bluetooth_adapter.h
@@ -11,6 +11,7 @@
#include "device/bluetooth/bluetooth_adapter.h"
#include "device/bluetooth/bluetooth_audio_sink.h"
#include "device/bluetooth/bluetooth_device.h"
+#include "device/bluetooth/bluetooth_discovery_session.h"
#include "testing/gmock/include/gmock/gmock.h"
namespace device {
@@ -87,10 +88,15 @@ class MockBluetoothAdapter : public BluetoothAdapter {
protected:
void DeleteOnCorrectThread() const override;
- virtual void AddDiscoverySession(const base::Closure& callback,
- const ErrorCallback& error_callback);
- virtual void RemoveDiscoverySession(const base::Closure& callback,
- const ErrorCallback& error_callback);
+ void AddDiscoverySession(BluetoothDiscoveryFilter* discovery_filter,
+ const base::Closure& callback,
+ const ErrorCallback& error_callback) override;
+ void RemoveDiscoverySession(BluetoothDiscoveryFilter* discovery_filter,
+ const base::Closure& callback,
+ const ErrorCallback& error_callback) override;
+ void SetDiscoveryFilter(scoped_ptr<BluetoothDiscoveryFilter> discovery_filter,
+ const base::Closure& callback,
+ const ErrorCallback& error_callback) override;
virtual ~MockBluetoothAdapter();
MOCK_METHOD1(RemovePairingDelegateInternal,
diff --git a/device/bluetooth/test/mock_bluetooth_discovery_session.cc b/device/bluetooth/test/mock_bluetooth_discovery_session.cc
index 295f954..1aea85a 100644
--- a/device/bluetooth/test/mock_bluetooth_discovery_session.cc
+++ b/device/bluetooth/test/mock_bluetooth_discovery_session.cc
@@ -15,8 +15,10 @@ namespace device {
// test code.
MockBluetoothDiscoverySession::MockBluetoothDiscoverySession()
: BluetoothDiscoverySession(
- scoped_refptr<BluetoothAdapter>(
- new testing::NiceMock<MockBluetoothAdapter>())) {}
+ scoped_refptr<BluetoothAdapter>(
+ new testing::NiceMock<MockBluetoothAdapter>()),
+ nullptr) {
+}
MockBluetoothDiscoverySession::~MockBluetoothDiscoverySession() {}
} // namespace device
diff --git a/device/device_tests.gyp b/device/device_tests.gyp
index 9bf39ac..8b1545a0 100644
--- a/device/device_tests.gyp
+++ b/device/device_tests.gyp
@@ -40,6 +40,7 @@
'bluetooth/bluetooth_chromeos_unittest.cc',
'bluetooth/bluetooth_device_unittest.cc',
'bluetooth/bluetooth_device_win_unittest.cc',
+ 'bluetooth/bluetooth_discovery_filter_unittest.cc',
'bluetooth/bluetooth_gatt_chromeos_unittest.cc',
'bluetooth/bluetooth_low_energy_win_unittest.cc',
'bluetooth/bluetooth_service_record_win_unittest.cc',