diff --git a/fastpair/dart/fast_pair_wrapper_impl.cc b/fastpair/dart/fast_pair_wrapper_impl.cc index de235a75..c29935e9 100644 --- a/fastpair/dart/fast_pair_wrapper_impl.cc +++ b/fastpair/dart/fast_pair_wrapper_impl.cc @@ -30,7 +30,8 @@ FastPairWrapperImpl::FastPairWrapperImpl() { FastPairWrapperImpl::~FastPairWrapperImpl() = default; void FastPairWrapperImpl::StartScan() { - scanner_broker_ = std::make_unique(); + Mediums mediums; + scanner_broker_ = std::make_unique(mediums); if (is_scanning_) { NEARBY_LOGS(VERBOSE) << __func__ << ": We're currently scanning. "; return; diff --git a/fastpair/dart/fast_pair_wrapper_impl_test.cc b/fastpair/dart/fast_pair_wrapper_impl_test.cc index afd1f768..b614ae37 100644 --- a/fastpair/dart/fast_pair_wrapper_impl_test.cc +++ b/fastpair/dart/fast_pair_wrapper_impl_test.cc @@ -16,8 +16,6 @@ #include -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" #include "gtest/gtest.h" #include "internal/platform/medium_environment.h" @@ -42,7 +40,7 @@ TEST_F(FastPairWrapperImplTest, StartScanningSuccess) { EXPECT_FALSE(wrapper_->IsPairing()); EXPECT_FALSE(wrapper_->IsServerAccessing()); wrapper_->StartScan(); - SystemClock::Sleep(absl::Milliseconds(200)); + SystemClock::Sleep(absl::Milliseconds(2000)); EXPECT_TRUE(wrapper_->IsScanning()); env_.Stop(); } diff --git a/fastpair/handshake/BUILD b/fastpair/handshake/BUILD index 2b6b079e..40de6d37 100644 --- a/fastpair/handshake/BUILD +++ b/fastpair/handshake/BUILD @@ -39,7 +39,7 @@ cc_library( "//fastpair/common", "//fastpair/crypto", "//fastpair/dataparser", - "//fastpair/internal/ble", + "//fastpair/internal/mediums", "//fastpair/repository", "//fastpair/server_access", "//internal/base:bluetooth_address", @@ -87,7 +87,7 @@ cc_test( "//fastpair/common", "//fastpair/crypto", "//fastpair/dataparser", - "//fastpair/internal/ble", + "//fastpair/internal/mediums", "//fastpair/server_access:test_support", "//fastpair/testing", "//internal/platform:logging", @@ -112,6 +112,7 @@ cc_test( ":handshake", ":test_support", "//fastpair/common", + "//fastpair/internal/mediums", "//fastpair/testing", "//internal/platform:base", "//internal/platform:comm", @@ -159,6 +160,7 @@ cc_test( deps = [ ":handshake", "//fastpair/common", + "//fastpair/internal/mediums", "//internal/platform:test_util", "//internal/platform:types", "//internal/platform/implementation/g3", # build_cleaner: keep diff --git a/fastpair/handshake/fast_pair_gatt_service_client_impl.cc b/fastpair/handshake/fast_pair_gatt_service_client_impl.cc index 4c0e2d04..c347db66 100644 --- a/fastpair/handshake/fast_pair_gatt_service_client_impl.cc +++ b/fastpair/handshake/fast_pair_gatt_service_client_impl.cc @@ -35,8 +35,8 @@ #include "fastpair/common/pair_failure.h" #include "fastpair/handshake/fast_pair_data_encryptor.h" #include "fastpair/handshake/fast_pair_gatt_service_client.h" +#include "fastpair/internal/mediums/mediums.h" #include "internal/base/bluetooth_address.h" -#include "internal/platform/ble_v2.h" #include "internal/platform/logging.h" #include "internal/platform/uuid.h" #include @@ -68,12 +68,13 @@ FastPairGattServiceClientImpl::Factory* // static std::unique_ptr -FastPairGattServiceClientImpl::Factory::Create(const FastPairDevice& device) { +FastPairGattServiceClientImpl::Factory::Create(const FastPairDevice& device, + Mediums& mediums) { if (g_test_factory_) { return g_test_factory_->CreateInstance(); } - return std::make_unique(device); + return std::make_unique(device, mediums); } // static @@ -85,8 +86,8 @@ void FastPairGattServiceClientImpl::Factory::SetFactoryForTesting( FastPairGattServiceClientImpl::Factory::~Factory() = default; FastPairGattServiceClientImpl::FastPairGattServiceClientImpl( - const FastPairDevice& device) - : device_address_(device.GetBleAddress()) {} + const FastPairDevice& device, Mediums& mediums) + : device_address_(device.GetBleAddress()), mediums_(mediums) {} void FastPairGattServiceClientImpl::InitializeGattConnection( absl::AnyInvocable)> @@ -118,7 +119,10 @@ void FastPairGattServiceClientImpl::AttemptGattConnection() { void FastPairGattServiceClientImpl::CreateGattConnection() { NEARBY_LOGS(INFO) << __func__ << " : Create Gatt Connection to the device."; - gatt_client_ = ble_.ConnectToGattServer(device_address_); + if (mediums_.GetBluetoothRadio().Enable() && + mediums_.GetBleV2().IsAvailable()) { + gatt_client_ = mediums_.GetBleV2().ConnectToGattServer(device_address_); + } if (!gatt_client_) { // The device must have been lost between connection attempts. NotifyInitializedError( @@ -260,7 +264,7 @@ void FastPairGattServiceClientImpl::WriteRequestAsync( std::vector data_to_write_vec(data_to_write.begin(), data_to_write.end()); - // Append the public version of the private key to the message so thedevice + // Append the public version of the private key to the message so the device // can generate the shared secret to decrypt the message. const std::optional> public_key = fast_pair_data_encryptor.GetPublicKey(); diff --git a/fastpair/handshake/fast_pair_gatt_service_client_impl.h b/fastpair/handshake/fast_pair_gatt_service_client_impl.h index d904e14a..bd8251b9 100644 --- a/fastpair/handshake/fast_pair_gatt_service_client_impl.h +++ b/fastpair/handshake/fast_pair_gatt_service_client_impl.h @@ -25,7 +25,7 @@ #include "fastpair/common/fast_pair_device.h" #include "fastpair/common/pair_failure.h" #include "fastpair/handshake/fast_pair_gatt_service_client.h" -#include "fastpair/internal/ble/ble.h" +#include "fastpair/internal/mediums/mediums.h" #include "internal/platform/ble_v2.h" #include "internal/platform/timer_impl.h" @@ -41,7 +41,7 @@ class FastPairGattServiceClientImpl : public FastPairGattServiceClient { class Factory { public: static std::unique_ptr Create( - const FastPairDevice& device); + const FastPairDevice& device, Mediums& mediums); static void SetFactoryForTesting(Factory* test_factory); protected: @@ -52,7 +52,8 @@ class FastPairGattServiceClientImpl : public FastPairGattServiceClient { static Factory* g_test_factory_; }; - explicit FastPairGattServiceClientImpl(const FastPairDevice& device); + explicit FastPairGattServiceClientImpl(const FastPairDevice& device, + Mediums& mediums); FastPairGattServiceClientImpl(const FastPairGattServiceClientImpl&) = delete; FastPairGattServiceClientImpl& operator=( const FastPairGattServiceClientImpl&) = delete; @@ -144,7 +145,7 @@ class FastPairGattServiceClientImpl : public FastPairGattServiceClient { bool is_initialized_ = false; std::string device_address_; std::unique_ptr gatt_client_; - Ble ble_; + Mediums& mediums_; }; } // namespace fastpair } // namespace nearby diff --git a/fastpair/handshake/fast_pair_gatt_service_client_impl_test.cc b/fastpair/handshake/fast_pair_gatt_service_client_impl_test.cc index f6750688..8bd35736 100644 --- a/fastpair/handshake/fast_pair_gatt_service_client_impl_test.cc +++ b/fastpair/handshake/fast_pair_gatt_service_client_impl_test.cc @@ -30,6 +30,7 @@ #include "fastpair/common/protocol.h" #include "fastpair/handshake/fake_fast_pair_data_encryptor.h" #include "fastpair/handshake/fast_pair_gatt_service_client.h" +#include "fastpair/internal/mediums/mediums.h" #include "internal/platform/ble_v2.h" #include "internal/platform/bluetooth_adapter.h" #include "internal/platform/byte_array.h" @@ -165,7 +166,9 @@ class FastPairGattServiceClientTest : public testing::Test { void InitializeFastPairGattServiceClient() { FastPairDevice device(kMetadataId, kProviderAddress, Protocol::kFastPairInitialPairing); - gatt_client_ = FastPairGattServiceClientImpl::Factory::Create(device); + Mediums mediums; + gatt_client_ = + FastPairGattServiceClientImpl::Factory::Create(device, mediums); gatt_client_->InitializeGattConnection( [this](std::optional failure) { initalized_failure_ = failure; diff --git a/fastpair/handshake/fast_pair_handshake_impl.cc b/fastpair/handshake/fast_pair_handshake_impl.cc index 16317315..734c7112 100644 --- a/fastpair/handshake/fast_pair_handshake_impl.cc +++ b/fastpair/handshake/fast_pair_handshake_impl.cc @@ -31,10 +31,11 @@ namespace nearby { namespace fastpair { FastPairHandshakeImpl::FastPairHandshakeImpl(FastPairDevice& device, + Mediums& mediums, OnCompleteCallback on_complete) : FastPairHandshake(std::move(on_complete), nullptr, nullptr) { fast_pair_gatt_service_client_ = - FastPairGattServiceClientImpl::Factory::Create(device); + FastPairGattServiceClientImpl::Factory::Create(device, mediums); fast_pair_gatt_service_client_->InitializeGattConnection( [&](std::optional failure) { OnGattClientInitializedCallback(device, failure); diff --git a/fastpair/handshake/fast_pair_handshake_impl.h b/fastpair/handshake/fast_pair_handshake_impl.h index e38fc688..fa8a46a3 100644 --- a/fastpair/handshake/fast_pair_handshake_impl.h +++ b/fastpair/handshake/fast_pair_handshake_impl.h @@ -22,13 +22,15 @@ #include "fastpair/common/pair_failure.h" #include "fastpair/crypto/decrypted_response.h" #include "fastpair/handshake/fast_pair_handshake.h" +#include "fastpair/internal/mediums/mediums.h" namespace nearby { namespace fastpair { class FastPairHandshakeImpl : public FastPairHandshake { public: - FastPairHandshakeImpl(FastPairDevice& device, OnCompleteCallback on_complete); + explicit FastPairHandshakeImpl(FastPairDevice& device, Mediums& mediums, + OnCompleteCallback on_complete); FastPairHandshakeImpl(const FastPairHandshakeImpl&) = delete; FastPairHandshakeImpl& operator=(const FastPairHandshakeImpl&) = delete; diff --git a/fastpair/handshake/fast_pair_handshake_impl_test.cc b/fastpair/handshake/fast_pair_handshake_impl_test.cc index 47dac67c..d3511542 100644 --- a/fastpair/handshake/fast_pair_handshake_impl_test.cc +++ b/fastpair/handshake/fast_pair_handshake_impl_test.cc @@ -162,8 +162,9 @@ TEST_F(FastPairHandshakeImplTest, Success) { FastPairDevice device(kMetadataId, kProviderAddress, Protocol::kFastPairInitialPairing); CountDownLatch latch(1); + Mediums mediums; handshake_ = std::make_unique( - device, + device, mediums, [&](FastPairDevice& callback_device, std::optional failure) { EXPECT_EQ(&device, &callback_device); EXPECT_EQ(device.public_address(), kPublicAddress); @@ -180,8 +181,9 @@ TEST_F(FastPairHandshakeImplTest, GattError) { FastPairDevice device(kMetadataId, kProviderAddress, Protocol::kFastPairInitialPairing); CountDownLatch latch(1); + Mediums mediums; handshake_ = std::make_unique( - device, + device, mediums, [&](FastPairDevice& callback_device, std::optional failure) { EXPECT_EQ(&device, &callback_device); EXPECT_EQ(failure.value(), PairFailure::kCreateGattConnection); @@ -197,8 +199,9 @@ TEST_F(FastPairHandshakeImplTest, DataEncryptorCreateError) { FastPairDevice device(kMetadataId, kProviderAddress, Protocol::kFastPairInitialPairing); CountDownLatch latch(1); + Mediums mediums; handshake_ = std::make_unique( - device, + device, mediums, [&](FastPairDevice& callback_device, std::optional failure) { EXPECT_EQ(&device, &callback_device); EXPECT_EQ(failure.value(), PairFailure::kDataEncryptorRetrieval); @@ -214,8 +217,9 @@ TEST_F(FastPairHandshakeImplTest, WriteResponseError) { FastPairDevice device(kMetadataId, kProviderAddress, Protocol::kFastPairInitialPairing); CountDownLatch latch(1); + Mediums mediums; handshake_ = std::make_unique( - device, + device, mediums, [&](FastPairDevice& callback_device, std::optional failure) { EXPECT_EQ(&device, &callback_device); EXPECT_EQ(failure.value(), @@ -233,8 +237,9 @@ TEST_F(FastPairHandshakeImplTest, WriteResponseWrongSize) { FastPairDevice device(kMetadataId, kProviderAddress, Protocol::kFastPairInitialPairing); CountDownLatch latch(1); + Mediums mediums; handshake_ = std::make_unique( - device, + device, mediums, [&](FastPairDevice& callback_device, std::optional failure) { EXPECT_EQ(&device, &callback_device); EXPECT_EQ(failure.value(), @@ -252,8 +257,9 @@ TEST_F(FastPairHandshakeImplTest, ParseResponseError) { FastPairDevice device(kMetadataId, kProviderAddress, Protocol::kFastPairInitialPairing); CountDownLatch latch(1); + Mediums mediums; handshake_ = std::make_unique( - device, + device, mediums, [&](FastPairDevice& callback_device, std::optional failure) { EXPECT_EQ(&device, &callback_device); EXPECT_EQ(failure.value(), diff --git a/fastpair/handshake/fast_pair_handshake_lookup.cc b/fastpair/handshake/fast_pair_handshake_lookup.cc index a137280d..93dc075e 100644 --- a/fastpair/handshake/fast_pair_handshake_lookup.cc +++ b/fastpair/handshake/fast_pair_handshake_lookup.cc @@ -77,11 +77,11 @@ void FastPairHandshakeLookup::Clear() { } FastPairHandshake* FastPairHandshakeLookup::Create( - FastPairDevice& device, OnCompleteCallback on_complete) { + FastPairDevice& device, Mediums& mediums, OnCompleteCallback on_complete) { absl::MutexLock lock(&mutex_); auto it = fast_pair_handshakes_.emplace( - &device, - std::make_unique(device, std::move(on_complete))); + &device, std::make_unique(device, mediums, + std::move(on_complete))); DCHECK(it.second); return it.first->second.get(); } diff --git a/fastpair/handshake/fast_pair_handshake_lookup.h b/fastpair/handshake/fast_pair_handshake_lookup.h index 4909fa17..2b459077 100644 --- a/fastpair/handshake/fast_pair_handshake_lookup.h +++ b/fastpair/handshake/fast_pair_handshake_lookup.h @@ -24,6 +24,7 @@ #include "fastpair/common/fast_pair_device.h" #include "fastpair/common/pair_failure.h" #include "fastpair/handshake/fast_pair_handshake.h" +#include "fastpair/internal/mediums/mediums.h" namespace nearby { namespace fastpair { @@ -63,7 +64,7 @@ class FastPairHandshakeLookup { // Creates and returns a new instance for |FastPairdevice| if no instance // already exists. // Returns the existing instance if there is one. - FastPairHandshake* Create(FastPairDevice& device, + FastPairHandshake* Create(FastPairDevice& device, Mediums& mediums, OnCompleteCallback on_complete); protected: diff --git a/fastpair/handshake/fast_pair_handshake_lookup_test.cc b/fastpair/handshake/fast_pair_handshake_lookup_test.cc index d30e88ab..f95ab526 100644 --- a/fastpair/handshake/fast_pair_handshake_lookup_test.cc +++ b/fastpair/handshake/fast_pair_handshake_lookup_test.cc @@ -17,15 +17,13 @@ #include #include -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" #include "gtest/gtest.h" #include "absl/strings/string_view.h" #include "fastpair/common/fast_pair_device.h" #include "fastpair/common/pair_failure.h" #include "fastpair/common/protocol.h" +#include "fastpair/internal/mediums/mediums.h" #include "internal/platform/count_down_latch.h" -#include "internal/platform/medium_environment.h" namespace nearby { namespace fastpair { @@ -43,8 +41,9 @@ class FastPairHandshakeLookupTest : public ::testing::Test { void CreateFastPairHandshkeInstanceForDevice(FastPairDevice& device) { CountDownLatch latch(1); + Mediums mediums; EXPECT_TRUE(FastPairHandshakeLookup::GetInstance()->Create( - device, + device, mediums, [&](FastPairDevice& cb_device, std::optional failure) { EXPECT_EQ(&device, &cb_device); EXPECT_EQ(failure, PairFailure::kCreateGattConnection); diff --git a/fastpair/internal/ble/BUILD b/fastpair/internal/mediums/BUILD similarity index 55% rename from fastpair/internal/ble/BUILD rename to fastpair/internal/mediums/BUILD index 2fe38e54..22bcdd14 100644 --- a/fastpair/internal/ble/BUILD +++ b/fastpair/internal/mediums/BUILD @@ -15,12 +15,17 @@ licenses(["notice"]) cc_library( - name = "ble", + name = "mediums", srcs = [ "ble.cc", + "ble_v2.cc", + "bluetooth_radio.cc", ], hdrs = [ "ble.h", + "ble_v2.h", + "bluetooth_radio.h", + "mediums.h", ], visibility = [ "//fastpair:__subpackages__", @@ -30,13 +35,41 @@ cc_library( "//internal/platform:comm", "//internal/platform:logging", "//internal/platform:types", - "@com_google_absl//absl/container:flat_hash_map", - "@com_google_absl//absl/container:flat_hash_set", "@com_google_absl//absl/strings", "@com_google_absl//absl/time", ], ) +cc_test( + name = "bluetooth_radio_test", + size = "small", + srcs = [ + "bluetooth_radio_test.cc", + ], + shard_count = 16, + deps = [ + ":mediums", + "//internal/platform/implementation/g3", # build_cleaner: keep + "@com_github_protobuf_matchers//protobuf-matchers", + "@com_google_googletest//:gtest_main", + ], +) + +cc_test( + name = "mediums_test", + size = "small", + srcs = [ + "mediums_test.cc", + ], + shard_count = 16, + deps = [ + ":mediums", + "//internal/platform/implementation/g3", # build_cleaner: keep + "@com_github_protobuf_matchers//protobuf-matchers", + "@com_google_googletest//:gtest_main", + ], +) + cc_test( name = "ble_test", size = "small", @@ -45,7 +78,7 @@ cc_test( ], shard_count = 16, deps = [ - ":ble", + ":mediums", "//internal/platform:base", "//internal/platform:comm", "//internal/platform:test_util", @@ -57,3 +90,18 @@ cc_test( "@com_google_googletest//:gtest_main", ], ) + +cc_test( + name = "ble_v2_test", + size = "small", + srcs = [ + "ble_v2_test.cc", + ], + shard_count = 16, + deps = [ + ":mediums", + "//internal/platform/implementation/g3", # build_cleaner: keep + "@com_github_protobuf_matchers//protobuf-matchers", + "@com_google_googletest//:gtest_main", + ], +) diff --git a/fastpair/internal/ble/ble.cc b/fastpair/internal/mediums/ble.cc similarity index 64% rename from fastpair/internal/ble/ble.cc rename to fastpair/internal/mediums/ble.cc index 7edfd25e..14c790da 100644 --- a/fastpair/internal/ble/ble.cc +++ b/fastpair/internal/mediums/ble.cc @@ -12,87 +12,19 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "fastpair/internal/ble/ble.h" +#include "fastpair/internal/mediums/ble.h" -#include #include #include -#include "internal/platform/ble_v2.h" +#include "fastpair/internal/mediums/bluetooth_radio.h" #include "internal/platform/bluetooth_adapter.h" #include "internal/platform/logging.h" +#include "internal/platform/mutex_lock.h" namespace nearby { namespace fastpair { -namespace { -// A stub BlePeripheral implementation. -class BlePeripheralStub : public api::ble_v2::BlePeripheral { - public: - explicit BlePeripheralStub(absl::string_view ble_address) { - ble_address_ = std::string(ble_address); - } - - std::string GetAddress() const override { return ble_address_; } - - private: - std::string ble_address_; -}; -} // namespace - -Ble::~Ble() { - // We never enabled Bluetooth, nothing to do. - if (!ever_saved_state_.Get()) { - NEARBY_LOG(INFO, "BT adapter was not used. Not touching HW."); - return; - } - - NEARBY_LOG(INFO, "Bring BT adapter to original state"); - if (!SetBluetoothState(originally_enabled_.Get())) { - NEARBY_LOG(INFO, "Failed to restore BT adapter original state."); - } -} - -bool Ble::Enable() { - if (!SaveOriginalState()) { - return false; - } - - return SetBluetoothState(true); -} - -bool Ble::Disable() { - if (!SaveOriginalState()) { - return false; - } - - return SetBluetoothState(false); -} - -bool Ble::IsEnabled() const { - return IsAdapterValid() && IsInDesiredState(true); -} - -bool Ble::SetBluetoothState(bool enable) { - return adapter_.SetStatus(enable ? BluetoothAdapter::Status::kEnabled - : BluetoothAdapter::Status::kDisabled); -} - -bool Ble::IsInDesiredState(bool should_be_enabled) const { - return adapter_.IsEnabled() == should_be_enabled; -} - -bool Ble::SaveOriginalState() { - if (!IsAdapterValid()) { - return false; - } - - // If we haven't saved the original state of the radio, save it. - if (!ever_saved_state_.Set(true)) { - originally_enabled_.Set(adapter_.IsEnabled()); - } - - return true; -} +Ble::Ble(BluetoothRadio& radio) : radio_(radio) {} bool Ble::IsAvailable() const { MutexLock lock(&mutex_); @@ -122,7 +54,7 @@ bool Ble::StartScanning(const std::string& service_id, return false; } - if (!IsEnabled()) { + if (!radio_.IsEnabled()) { NEARBY_LOGS(INFO) << "Can't start BLE scanning because Bluetooth was NOT enabled"; return false; @@ -183,18 +115,9 @@ bool Ble::StopScanning(const std::string& service_id) { return ret; } -std::unique_ptr Ble::ConnectToGattServer( - absl::string_view ble_address) { - MutexLock lock(&mutex_); - auto v2_peripheral = std::make_unique(ble_address); - return v2_medium_.ConnectToGattServer(BleV2Peripheral(v2_peripheral.get()), - api::ble_v2::TxPowerLevel::kUnknown, - {}); -} - bool Ble::IsScanning() { + NEARBY_LOGS(INFO) << __func__; MutexLock lock(&mutex_); - return IsScanningLocked(); } diff --git a/fastpair/internal/ble/ble.h b/fastpair/internal/mediums/ble.h similarity index 50% rename from fastpair/internal/ble/ble.h rename to fastpair/internal/mediums/ble.h index b1710bdf..c6923384 100644 --- a/fastpair/internal/ble/ble.h +++ b/fastpair/internal/mediums/ble.h @@ -15,59 +15,30 @@ #ifndef THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_BLE_BLE_H_ #define THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_BLE_BLE_H_ -#include -#include #include -#include "absl/container/flat_hash_map.h" -#include "absl/container/flat_hash_set.h" -#include "internal/platform/atomic_boolean.h" +#include "fastpair/internal/mediums/bluetooth_radio.h" #include "internal/platform/ble.h" -#include "internal/platform/ble_v2.h" #include "internal/platform/bluetooth_adapter.h" -#include "internal/platform/multi_thread_executor.h" #include "internal/platform/mutex.h" namespace nearby { namespace fastpair { +// Provides the operations that can be performed on the Bluetooth Low Energy +// (BLE) medium. class Ble { public: using DiscoveredPeripheralCallback = BleMedium::DiscoveredPeripheralCallback; - Ble() = default; - Ble(Ble&&) = default; - Ble& operator=(Ble&&) = default; + explicit Ble(BluetoothRadio& bluetooth_radio); + Ble(Ble&&) = delete; + Ble& operator=(Ble&&) = delete; + ~Ble() = default; - // Reverts the Ble to its original state. - ~Ble(); - - // Enables Bluetooth. Returns true if enabled successfully. - // This must be called before attempting to invoke any other methods of - // this class. - bool Enable(); - - // Disables Bluetooth. Returns true if disabled successfully. - bool Disable(); - - // Returns true if the Bluetooth radio is currently enabled. - bool IsEnabled() const; - - // Returns true if Ble communications are supported by a platform. + // Returns true, if Ble communications are supported by a platform. bool IsAvailable() const ABSL_LOCKS_EXCLUDED(mutex_); - // Returns true if this object owns a valid platform implementation. - bool IsMediumValid() const ABSL_LOCKS_EXCLUDED(mutex_) { - MutexLock lock(&mutex_); - return medium_.IsValid(); - } - - // Returns true if this object has a valid BluetoothAdapter reference. - bool IsAdapterValid() const { return adapter_.IsValid(); } - - // Return true if Ble is currenlty scanning. - bool IsScanning() ABSL_LOCKS_EXCLUDED(mutex_); - // Enables Ble scanning mode. Will report any discoverable peripherals in // range through a callback. Returns true, if scanning mode was enabled, // false otherwise. @@ -76,51 +47,29 @@ class Ble { DiscoveredPeripheralCallback callback) ABSL_LOCKS_EXCLUDED(mutex_); - // Returns a new GattClient connection to a gatt server. - std::unique_ptr ConnectToGattServer( - absl::string_view ble_address); - // Disables Ble discovery mode. bool StopScanning(const std::string& service_id) ABSL_LOCKS_EXCLUDED(mutex_); + // Return true if Ble is currenlty scanning. + bool IsScanning() ABSL_LOCKS_EXCLUDED(mutex_); + // Return BleMedium BleMedium& getMedium() { return medium_; } - // Return BluetoothAdapter - BluetoothAdapter& GetBluetoothAdapter() { return adapter_; } - private: - mutable Mutex mutex_; - // BluetoothAdapter::IsValid() will return false if BT is not supported. - BluetoothAdapter adapter_; - DiscoveredPeripheralCallback discovered_peripheral_callback_; - BleMedium medium_ ABSL_GUARDED_BY(mutex_){adapter_}; - BleV2Medium v2_medium_ ABSL_GUARDED_BY(mutex_){adapter_}; - bool is_scanning_ = false; - // Same as IsAvailable(), but must be called with mutex_ held. bool IsAvailableLocked() const ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); // Same as IsDiscovering(), but must be called with mutex_ held. bool IsScanningLocked() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - bool SetBluetoothState(bool enable); - - bool IsInDesiredState(bool should_be_enabled) const; - - // To be called in enable() and disable(). This will remember the - // original state of the ble before any ble state has been modified. - // Returns false if Bluetooth doesn't exist on the device and the state cannot - // be obtained. - bool SaveOriginalState(); - - // The Ble's original state, before we modified it. True if - // originally enabled, false if originally disabled. - // We restore the radio to its original state in the destructor. - AtomicBoolean originally_enabled_{false}; - - // false if we never modified the radio state, true otherwise. - AtomicBoolean ever_saved_state_{false}; + mutable Mutex mutex_; + DiscoveredPeripheralCallback discovered_peripheral_callback_; + BluetoothRadio& radio_ ABSL_GUARDED_BY(mutex_); + BluetoothAdapter& adapter_ ABSL_GUARDED_BY(mutex_){ + radio_.GetBluetoothAdapter()}; + BleMedium medium_ ABSL_GUARDED_BY(mutex_){adapter_}; + bool is_scanning_ = false; }; } // namespace fastpair diff --git a/fastpair/internal/ble/ble_test.cc b/fastpair/internal/mediums/ble_test.cc similarity index 59% rename from fastpair/internal/ble/ble_test.cc rename to fastpair/internal/mediums/ble_test.cc index f4d7c0d6..9fb93fd1 100644 --- a/fastpair/internal/ble/ble_test.cc +++ b/fastpair/internal/mediums/ble_test.cc @@ -1,4 +1,4 @@ -// Copyright 2022 Google LLC +// Copyright 2023 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -12,13 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "fastpair/internal/ble/ble.h" +#include "fastpair/internal/mediums/ble.h" #include #include "gtest/gtest.h" -#include "internal/platform/ble.h" -#include "internal/platform/bluetooth_adapter.h" #include "internal/platform/count_down_latch.h" #include "internal/platform/medium_environment.h" @@ -26,64 +24,27 @@ namespace nearby { namespace fastpair { namespace { -using FeatureFlags = FeatureFlags::Flags; - +using DiscoveredPeripheralCallback = BleMedium::DiscoveredPeripheralCallback; constexpr absl::Duration kWaitDuration = absl::Milliseconds(1000); constexpr absl::string_view kServiceID{"com.google.location.nearby.apps.test"}; constexpr absl::string_view kAdvertisementString{"96C12E"}; constexpr absl::string_view kFastPairServiceUuid{"\x2c\xfe"}; -class BleTest : public ::testing::TestWithParam { - protected: - using DiscoveredPeripheralCallback = BleMedium::DiscoveredPeripheralCallback; - - MediumEnvironment& env_{MediumEnvironment::Instance()}; -}; - -TEST_F(BleTest, ConstructorDestructorWorks) { - Ble ble; - EXPECT_TRUE(ble.IsAdapterValid()); +TEST(BleTest, ConstructorDestructorWorks) { + BluetoothRadio radio; + Ble ble(radio); + EXPECT_TRUE(ble.IsAvailable()); + EXPECT_FALSE(ble.IsScanning()); } -TEST_F(BleTest, CanEnable) { - Ble ble; - EXPECT_TRUE(ble.IsAdapterValid()); - EXPECT_TRUE(ble.IsEnabled()); - EXPECT_TRUE(ble.Disable()); - EXPECT_FALSE(ble.IsEnabled()); - EXPECT_TRUE(ble.Enable()); - EXPECT_TRUE(ble.IsEnabled()); -} - -TEST_F(BleTest, CanDisable) { - Ble ble; - EXPECT_TRUE(ble.IsAdapterValid()); - EXPECT_TRUE(ble.IsEnabled()); - EXPECT_TRUE(ble.Disable()); - EXPECT_FALSE(ble.IsEnabled()); -} - -TEST_F(BleTest, CanConstructValidObject) { - env_.Start(); - Ble ble_a; - Ble ble_b; - - EXPECT_TRUE(ble_a.IsMediumValid()); - EXPECT_TRUE(ble_a.IsAdapterValid()); - EXPECT_TRUE(ble_a.IsAvailable()); - EXPECT_TRUE(ble_b.IsMediumValid()); - EXPECT_TRUE(ble_b.IsAdapterValid()); - EXPECT_TRUE(ble_b.IsAvailable()); - EXPECT_NE(&ble_a.GetBluetoothAdapter(), &ble_b.GetBluetoothAdapter()); - env_.Stop(); -} - -TEST_F(BleTest, CanStartDiscovery) { - env_.Start(); - Ble ble_a; - Ble ble_b; - ble_a.Enable(); - ble_b.Enable(); +TEST(BleTest, CanStartDiscovery) { + MediumEnvironment::Instance().Start(); + BluetoothRadio radio_a; + BluetoothRadio radio_b; + Ble ble_a{radio_a}; + Ble ble_b{radio_b}; + radio_a.Enable(); + radio_b.Enable(); std::string service_id(kServiceID); ByteArray advertisement_bytes{std::string(kAdvertisementString)}; std::string fast_pair_service_uuid(kFastPairServiceUuid); @@ -112,16 +73,8 @@ TEST_F(BleTest, CanStartDiscovery) { EXPECT_TRUE(lost_latch.Await(kWaitDuration).result()); EXPECT_TRUE(ble_a.StopScanning(service_id)); EXPECT_FALSE(ble_a.IsScanning()); - env_.Stop(); + MediumEnvironment::Instance().Stop(); } - -TEST_F(BleTest, CannConnectToGattServer) { - env_.Start(); - Ble ble; - EXPECT_NE(ble.ConnectToGattServer("bleaddress"), nullptr); - env_.Stop(); -} - } // namespace } // namespace fastpair } // namespace nearby diff --git a/fastpair/internal/mediums/ble_v2.cc b/fastpair/internal/mediums/ble_v2.cc new file mode 100644 index 00000000..0fdc0c14 --- /dev/null +++ b/fastpair/internal/mediums/ble_v2.cc @@ -0,0 +1,69 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "fastpair/internal/mediums/ble_v2.h" + +#include +#include + +#include "internal/platform/mutex_lock.h" + +namespace nearby { +namespace fastpair { +namespace { +// A stub BlePeripheral implementation. +class BlePeripheralStub : public api::ble_v2::BlePeripheral { + public: + explicit BlePeripheralStub(absl::string_view ble_address) { + ble_address_ = std::string(ble_address); + } + + std::string GetAddress() const override { return ble_address_; } + + private: + std::string ble_address_; +}; +} // namespace + +BleV2::BleV2(BluetoothRadio& radio) : radio_(radio) {} + +bool BleV2::IsAvailable() const { + MutexLock lock(&mutex_); + return IsAvailableLocked(); +} + +bool BleV2::IsAvailableLocked() const { + return medium_.IsValid() && adapter_.IsValid() && adapter_.IsEnabled(); +} + +std::unique_ptr BleV2::ConnectToGattServer( + absl::string_view ble_address) { + MutexLock lock(&mutex_); + if (!radio_.IsEnabled()) { + NEARBY_LOGS(INFO) + << "Can't connect to GattServer because Bluetooth was NOT enabled"; + return nullptr; + } + if (!IsAvailableLocked()) { + NEARBY_LOGS(VERBOSE) + << __func__ + << "Can't connect to GattServer because BleV2 isn't available."; + return nullptr; + } + auto v2_peripheral = std::make_unique(ble_address); + return medium_.ConnectToGattServer(BleV2Peripheral(v2_peripheral.get()), + api::ble_v2::TxPowerLevel::kUnknown, {}); +} +} // namespace fastpair +} // namespace nearby diff --git a/fastpair/internal/mediums/ble_v2.h b/fastpair/internal/mediums/ble_v2.h new file mode 100644 index 00000000..5a79e201 --- /dev/null +++ b/fastpair/internal/mediums/ble_v2.h @@ -0,0 +1,56 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_MEDIUMS_BLE_V2_H_ +#define THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_MEDIUMS_BLE_V2_H_ + +#include + +#include "fastpair/internal/mediums/bluetooth_radio.h" +#include "internal/platform/ble_v2.h" +#include "internal/platform/mutex.h" +#include "internal/platform/mutex_lock.h" + +namespace nearby { +namespace fastpair { + +// Provides the operations that can be performed on the Bluetooth Low Energy +// (BLE_V2) medium. +class BleV2 { + public: + explicit BleV2(BluetoothRadio& bluetooth_radio); + ~BleV2() = default; + + // Returns true, if BleV2 communications are supported by a platform. + bool IsAvailable() const ABSL_LOCKS_EXCLUDED(mutex_); + + // Returns a new GattClient connection to a gatt server. + std::unique_ptr ConnectToGattServer( + absl::string_view ble_address); + + private: + // Same as IsAvailable(), but must be called with mutex_ held. + bool IsAvailableLocked() const ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); + + mutable Mutex mutex_; + BluetoothRadio& radio_ ABSL_GUARDED_BY(mutex_); + BluetoothAdapter& adapter_ ABSL_GUARDED_BY(mutex_){ + radio_.GetBluetoothAdapter()}; + BleV2Medium medium_ ABSL_GUARDED_BY(mutex_){adapter_}; +}; + +} // namespace fastpair +} // namespace nearby + +#endif // THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_MEDIUMS_BLE_V2_H_ diff --git a/fastpair/internal/mediums/ble_v2_test.cc b/fastpair/internal/mediums/ble_v2_test.cc new file mode 100644 index 00000000..26e9e52c --- /dev/null +++ b/fastpair/internal/mediums/ble_v2_test.cc @@ -0,0 +1,46 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "fastpair/internal/mediums/ble_v2.h" + +#include "gtest/gtest.h" + +namespace nearby { +namespace fastpair { +namespace { + +TEST(BleV2Test, IsAvailable) { + BluetoothRadio radio; + BleV2 bleV2(radio); + EXPECT_TRUE(bleV2.IsAvailable()); + EXPECT_TRUE(radio.Disable()); + EXPECT_FALSE(bleV2.IsAvailable()); +} + +TEST(BleV2Test, CanConnectToGattServer) { + BluetoothRadio radio; + BleV2 bleV2(radio); + EXPECT_TRUE(bleV2.ConnectToGattServer("bleaddress")); +} + +TEST(BleV2Test, CannotConnectToGattServer) { + BluetoothRadio radio; + BleV2 bleV2(radio); + EXPECT_TRUE(radio.Disable()); + EXPECT_FALSE(bleV2.ConnectToGattServer("bleaddress")); +} + +} // namespace +} // namespace fastpair +} // namespace nearby diff --git a/fastpair/internal/mediums/bluetooth_radio.cc b/fastpair/internal/mediums/bluetooth_radio.cc new file mode 100644 index 00000000..b22895f4 --- /dev/null +++ b/fastpair/internal/mediums/bluetooth_radio.cc @@ -0,0 +1,86 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "fastpair/internal/mediums/bluetooth_radio.h" + +#include "internal/platform/logging.h" + +namespace nearby { +namespace fastpair { + +BluetoothRadio::BluetoothRadio() { + if (!IsAdapterValid()) { + NEARBY_LOGS(ERROR) << "Bluetooth adapter is not valid: BT is not supported"; + } +} + +BluetoothRadio::~BluetoothRadio() { + // We never enabled Bluetooth, nothing to do. + if (!ever_saved_state_.Get()) { + NEARBY_LOGS(INFO) << "BT adapter was not used. Not touching HW."; + return; + } + + NEARBY_LOG(INFO, "Bring BT adapter to original state"); + if (!SetBluetoothState(originally_enabled_.Get())) { + NEARBY_LOGS(INFO) << "Failed to restore BT adapter original state."; + } +} + +bool BluetoothRadio::Enable() { + NEARBY_LOGS(INFO) << __func__; + if (!SaveOriginalState()) { + return false; + } + + return SetBluetoothState(true); +} + +bool BluetoothRadio::Disable() { + if (!SaveOriginalState()) { + return false; + } + + return SetBluetoothState(false); +} + +bool BluetoothRadio::IsEnabled() const { + return IsAdapterValid() && IsInDesiredState(true); +} + +bool BluetoothRadio::SetBluetoothState(bool enable) { + return bluetooth_adapter_.SetStatus( + enable ? BluetoothAdapter::Status::kEnabled + : BluetoothAdapter::Status::kDisabled); +} + +bool BluetoothRadio::IsInDesiredState(bool should_be_enabled) const { + return bluetooth_adapter_.IsEnabled() == should_be_enabled; +} + +bool BluetoothRadio::SaveOriginalState() { + if (!IsAdapterValid()) { + return false; + } + + // If we haven't saved the original state of the radio, save it. + if (!ever_saved_state_.Set(true)) { + originally_enabled_.Set(bluetooth_adapter_.IsEnabled()); + } + + return true; +} + +} // namespace fastpair +} // namespace nearby diff --git a/fastpair/internal/mediums/bluetooth_radio.h b/fastpair/internal/mediums/bluetooth_radio.h new file mode 100644 index 00000000..135d3731 --- /dev/null +++ b/fastpair/internal/mediums/bluetooth_radio.h @@ -0,0 +1,79 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_MEDIUMS_BLUETOOTH_RADIO_H_ +#define THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_MEDIUMS_BLUETOOTH_RADIO_H_ + +#include "internal/platform/atomic_boolean.h" +#include "internal/platform/bluetooth_adapter.h" + +namespace nearby { +namespace fastpair { + +// Provides the operations that can be performed on the Bluetooth radio. +class BluetoothRadio { + public: + BluetoothRadio(); + BluetoothRadio(BluetoothRadio&&) = default; + BluetoothRadio& operator=(BluetoothRadio&&) = default; + + // Reverts the Bluetooth radio to its original state. + ~BluetoothRadio(); + + // Enables Bluetooth. + // + // This must be called before attempting to invoke any other methods of + // this class. + // + // Returns true if enabled successfully. + bool Enable(); + + // Disables Bluetooth. + // + // Returns true if disabled successfully. + bool Disable(); + + // Returns true if the Bluetooth radio is currently enabled. + bool IsEnabled() const; + + // Returns result of BluetoothAdapter::IsValid() for private adapter instance. + bool IsAdapterValid() const { return bluetooth_adapter_.IsValid(); } + + BluetoothAdapter& GetBluetoothAdapter() { return bluetooth_adapter_; } + + private: + bool SetBluetoothState(bool enable); + bool IsInDesiredState(bool should_be_enabled) const; + // To be called in enable() and disable(). This will remember the + // original state of the radio before any radio state has been modified. + // Returns false if Bluetooth doesn't exist on the device and the state cannot + // be obtained. + bool SaveOriginalState(); + + // BluetoothAdapter::IsValid() will return false if BT is not supported. + BluetoothAdapter bluetooth_adapter_; + + // The Bluetooth radio's original state, before we modified it. True if + // originally enabled, false if originally disabled. + // We restore the radio to its original state in the destructor. + + AtomicBoolean originally_enabled_{false}; + // false if we never modified the radio state, true otherwise. + AtomicBoolean ever_saved_state_{false}; +}; + +} // namespace fastpair +} // namespace nearby + +#endif // THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_MEDIUMS_BLUETOOTH_RADIO_H_ diff --git a/fastpair/internal/mediums/bluetooth_radio_test.cc b/fastpair/internal/mediums/bluetooth_radio_test.cc new file mode 100644 index 00000000..834aca8e --- /dev/null +++ b/fastpair/internal/mediums/bluetooth_radio_test.cc @@ -0,0 +1,48 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "fastpair/internal/mediums/bluetooth_radio.h" + +#include "gtest/gtest.h" + +namespace nearby { +namespace fastpair { +namespace { + +TEST(BluetoothRadioTest, ConstructorDestructorWorks) { + BluetoothRadio radio; + EXPECT_TRUE(radio.IsAdapterValid()); +} + +TEST(BluetoothRadioTest, CanEnable) { + BluetoothRadio radio; + EXPECT_TRUE(radio.IsAdapterValid()); + EXPECT_TRUE(radio.IsEnabled()); + EXPECT_TRUE(radio.Disable()); + EXPECT_FALSE(radio.IsEnabled()); + EXPECT_TRUE(radio.Enable()); + EXPECT_TRUE(radio.IsEnabled()); +} + +TEST(BluetoothRadioTest, CanDisable) { + BluetoothRadio radio; + EXPECT_TRUE(radio.IsAdapterValid()); + EXPECT_TRUE(radio.IsEnabled()); + EXPECT_TRUE(radio.Disable()); + EXPECT_FALSE(radio.IsEnabled()); +} + +} // namespace +} // namespace fastpair +} // namespace nearby diff --git a/fastpair/internal/mediums/mediums.h b/fastpair/internal/mediums/mediums.h new file mode 100644 index 00000000..cf3f21a9 --- /dev/null +++ b/fastpair/internal/mediums/mediums.h @@ -0,0 +1,56 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_MEDIUMS_MEDIUMS_H_ +#define THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_MEDIUMS_MEDIUMS_H_ + +#include "fastpair/internal/mediums/ble.h" +#include "fastpair/internal/mediums/ble_v2.h" +#include "fastpair/internal/mediums/bluetooth_radio.h" + +namespace nearby { +namespace fastpair { + +// Facilitates convenient and reliable usage of various wireless mediums. +class Mediums { + public: + Mediums() = default; + ~Mediums() = default; + + // Returns a handle to the Bluetooth radio. + BluetoothRadio& GetBluetoothRadio() { return bluetooth_radio_; } + + // Returns a handle to the Ble medium. + Ble& GetBle() { return ble_; } + + // Returns a handle to the Ble medium. + BleV2& GetBleV2() { return ble_v2_; } + + private: + // The order of declaration is critical for both construction and + // destruction. + // + // 1) Construction: The individual mediums have a dependency on the + // corresponding radio, so the radio must be initialized first. + // + // 2) Destruction: The individual mediums should be shut down before the + // corresponding radio. + BluetoothRadio bluetooth_radio_; + Ble ble_{bluetooth_radio_}; + BleV2 ble_v2_{bluetooth_radio_}; +}; + +} // namespace fastpair +} // namespace nearby +#endif // THIRD_PARTY_NEARBY_FASTPAIR_INTERNAL_MEDIUMS_MEDIUMS_H_ diff --git a/fastpair/internal/mediums/mediums_test.cc b/fastpair/internal/mediums/mediums_test.cc new file mode 100644 index 00000000..2746abb3 --- /dev/null +++ b/fastpair/internal/mediums/mediums_test.cc @@ -0,0 +1,31 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "fastpair/internal/mediums/mediums.h" + +#include "gtest/gtest.h" + +namespace nearby { +namespace fastpair { +namespace { + +TEST(MediumTest, ConstructorWorks) { + Mediums medium; + EXPECT_TRUE(medium.GetBluetoothRadio().IsAdapterValid()); + EXPECT_FALSE(medium.GetBle().IsScanning()); + EXPECT_TRUE(medium.GetBleV2().ConnectToGattServer("ble_address")); +} +} // namespace +} // namespace fastpair +} // namespace nearby diff --git a/fastpair/keyed_service/fast_pair_mediator.cc b/fastpair/keyed_service/fast_pair_mediator.cc index d72d01c1..fee1b2c9 100644 --- a/fastpair/keyed_service/fast_pair_mediator.cc +++ b/fastpair/keyed_service/fast_pair_mediator.cc @@ -29,12 +29,12 @@ Mediator::Mediator(std::unique_ptr scanner_broker, scanner_broker_->AddObserver(this); } -void Mediator::OnDeviceFound(const FastPairDevice& device) { +void Mediator::OnDeviceFound(FastPairDevice& device) { NEARBY_LOGS(INFO) << __func__ << ": " << device; // Show discovery notification } -void Mediator::OnDeviceLost(const FastPairDevice& device) { +void Mediator::OnDeviceLost(FastPairDevice& device) { NEARBY_LOGS(INFO) << __func__ << ": " << device; } diff --git a/fastpair/keyed_service/fast_pair_mediator.h b/fastpair/keyed_service/fast_pair_mediator.h index c59857a1..499b6ea2 100644 --- a/fastpair/keyed_service/fast_pair_mediator.h +++ b/fastpair/keyed_service/fast_pair_mediator.h @@ -33,8 +33,8 @@ class Mediator final : public ScannerBroker::Observer { ~Mediator() override = default; // ScannerBroker::Observer - void OnDeviceFound(const FastPairDevice& device) override; - void OnDeviceLost(const FastPairDevice& device) override; + void OnDeviceFound(FastPairDevice& device) override; + void OnDeviceLost(FastPairDevice& device) override; void StartScanning(); diff --git a/fastpair/scanning/BUILD b/fastpair/scanning/BUILD index aa2afbf9..e1dc5370 100644 --- a/fastpair/scanning/BUILD +++ b/fastpair/scanning/BUILD @@ -29,7 +29,7 @@ cc_library( ], deps = [ "//fastpair/common", - "//fastpair/internal/ble", + "//fastpair/internal/mediums", "//fastpair/scanning/fastpair:scanning", "//internal/base", "//internal/platform:base", @@ -68,7 +68,7 @@ cc_test( deps = [ ":scanner", "//fastpair/common", - "//fastpair/internal/ble", + "//fastpair/internal/mediums", "//fastpair/proto:fastpair_cc_proto", "//fastpair/server_access:test_support", "//internal/platform:base", diff --git a/fastpair/scanning/fastpair/BUILD b/fastpair/scanning/fastpair/BUILD index a1c758a6..2f3bd825 100644 --- a/fastpair/scanning/fastpair/BUILD +++ b/fastpair/scanning/fastpair/BUILD @@ -33,7 +33,7 @@ cc_library( deps = [ "//fastpair/common", "//fastpair/dataparser", - "//fastpair/internal/ble", + "//fastpair/internal/mediums", "//fastpair/proto:fastpair_cc_proto", "//fastpair/repository", "//fastpair/server_access", @@ -46,6 +46,7 @@ cc_library( "@com_google_absl//absl/functional:bind_front", "@com_google_absl//absl/strings", "@com_google_absl//absl/synchronization", + "@com_google_absl//absl/time", ], ) @@ -79,6 +80,7 @@ cc_test( deps = [ ":scanning", "//fastpair/common", + "//fastpair/internal/mediums", "//internal/platform:base", "//internal/platform:comm", "//internal/platform:test_util", diff --git a/fastpair/scanning/fastpair/fake_fast_pair_scanner.h b/fastpair/scanning/fastpair/fake_fast_pair_scanner.h index 960bf83f..ed9d9254 100644 --- a/fastpair/scanning/fastpair/fake_fast_pair_scanner.h +++ b/fastpair/scanning/fastpair/fake_fast_pair_scanner.h @@ -32,6 +32,7 @@ class FakeFastPairScanner final : public FastPairScanner { void RemoveObserver(Observer* observer) override; void NotifyDeviceFound(const BlePeripheral& peripheral); void NotifyDeviceLost(const BlePeripheral& peripheral); + void StartScanning() override {}; private: ObserverList observer_; diff --git a/fastpair/scanning/fastpair/fast_pair_discoverable_scanner_impl.cc b/fastpair/scanning/fastpair/fast_pair_discoverable_scanner_impl.cc index cc3daaa1..37fb3c62 100644 --- a/fastpair/scanning/fastpair/fast_pair_discoverable_scanner_impl.cc +++ b/fastpair/scanning/fastpair/fast_pair_discoverable_scanner_impl.cc @@ -66,19 +66,16 @@ FastPairDiscoverableScannerImpl::Factory* FastPairDiscoverableScannerImpl::Factory::g_test_factory_ = nullptr; std::unique_ptr -FastPairDiscoverableScannerImpl::Factory::Create( - std::shared_ptr scanner, - std::shared_ptr adapter, DeviceCallback found_callback, - DeviceCallback lost_callback) { +FastPairDiscoverableScannerImpl::Factory::Create(FastPairScanner& scanner, + DeviceCallback found_callback, + DeviceCallback lost_callback) { if (g_test_factory_) { - return g_test_factory_->CreateInstance( - std::move(scanner), std::move(adapter), std::move(found_callback), - std::move(lost_callback)); + return g_test_factory_->CreateInstance(scanner, std::move(found_callback), + std::move(lost_callback)); } return std::make_unique( - std::move(scanner), std::move(adapter), std::move(found_callback), - std::move(lost_callback)); + scanner, std::move(found_callback), std::move(lost_callback)); } void FastPairDiscoverableScannerImpl::Factory::SetFactoryForTesting( @@ -90,14 +87,12 @@ FastPairDiscoverableScannerImpl::Factory::~Factory() = default; // FastPairScannerImpl FastPairDiscoverableScannerImpl::FastPairDiscoverableScannerImpl( - std::shared_ptr scanner, - std::shared_ptr adapter, DeviceCallback found_callback, + FastPairScanner& scanner, DeviceCallback found_callback, DeviceCallback lost_callback) - : scanner_(std::move(scanner)), - adapter_(std::move(adapter)), + : scanner_(scanner), found_callback_(std::move(found_callback)), lost_callback_(std::move(lost_callback)) { - scanner_->AddObserver(this); + scanner_.AddObserver(this); } void FastPairDiscoverableScannerImpl::OnDeviceFound( diff --git a/fastpair/scanning/fastpair/fast_pair_discoverable_scanner_impl.h b/fastpair/scanning/fastpair/fast_pair_discoverable_scanner_impl.h index 2b798242..d2f6aeb8 100644 --- a/fastpair/scanning/fastpair/fast_pair_discoverable_scanner_impl.h +++ b/fastpair/scanning/fastpair/fast_pair_discoverable_scanner_impl.h @@ -22,6 +22,7 @@ #include "absl/synchronization/mutex.h" #include "fastpair/common/fast_pair_device.h" +#include "fastpair/internal/mediums/mediums.h" #include "fastpair/repository/device_metadata.h" #include "fastpair/scanning/fastpair/fast_pair_discoverable_scanner.h" #include "fastpair/scanning/fastpair/fast_pair_scanner.h" @@ -37,25 +38,22 @@ class FastPairDiscoverableScannerImpl : public FastPairDiscoverableScanner, class Factory { public: static std::unique_ptr Create( - std::shared_ptr scanner, - std::shared_ptr adapter, - DeviceCallback found_callback, DeviceCallback lost_callback); + FastPairScanner& scanner, DeviceCallback found_callback, + DeviceCallback lost_callback); static void SetFactoryForTesting(Factory* g_test_factory); protected: virtual ~Factory(); virtual std::unique_ptr CreateInstance( - std::shared_ptr scanner, - std::shared_ptr adapter, - DeviceCallback found_callback, DeviceCallback lost_callback) = 0; + FastPairScanner& scanner, DeviceCallback found_callback, + DeviceCallback lost_callback) = 0; private: static Factory* g_test_factory_; }; - FastPairDiscoverableScannerImpl(std::shared_ptr scanner, - std::shared_ptr adapter, + FastPairDiscoverableScannerImpl(FastPairScanner& scanner, DeviceCallback found_callback, DeviceCallback lost_callback); FastPairDiscoverableScannerImpl(const FastPairDiscoverableScannerImpl&) = @@ -75,9 +73,9 @@ class FastPairDiscoverableScannerImpl : public FastPairDiscoverableScanner, const std::string model_id, DeviceMetadata& device_metadata); void NotifyDeviceFound(FastPairDevice& device); + absl::Mutex mutex_; - std::shared_ptr scanner_; - std::shared_ptr adapter_; + FastPairScanner& scanner_; DeviceCallback found_callback_; DeviceCallback lost_callback_; absl::flat_hash_map> diff --git a/fastpair/scanning/fastpair/fast_pair_discoverable_scanner_impl_test.cc b/fastpair/scanning/fastpair/fast_pair_discoverable_scanner_impl_test.cc index 883ff12f..42a891d8 100644 --- a/fastpair/scanning/fastpair/fast_pair_discoverable_scanner_impl_test.cc +++ b/fastpair/scanning/fastpair/fast_pair_discoverable_scanner_impl_test.cc @@ -19,8 +19,6 @@ #include #include -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" #include "gtest/gtest.h" #include "absl/synchronization/notification.h" #include "fastpair/scanning/fastpair/fake_fast_pair_scanner.h" @@ -78,13 +76,11 @@ class FastPairDiscoverableScannerImplTest : public testing::Test { public: void SetUp() override { SetUpMetadata(); - scanner_ = std::make_shared(); - adapter_ = std::make_shared(); + scanner_ = std::make_unique(); } void TearDown() override { scanner_.reset(); - adapter_.reset(); repository_.reset(); } @@ -98,9 +94,8 @@ class FastPairDiscoverableScannerImplTest : public testing::Test { // void TearDown() override { discoverable_scanner_.reset(); } protected: - std::shared_ptr scanner_; + std::unique_ptr scanner_; std::unique_ptr repository_; - std::shared_ptr adapter_; DeviceCallback found_device_callback_; DeviceCallback lost_device_callback_; }; @@ -117,7 +112,7 @@ TEST_F(FastPairDiscoverableScannerImplTest, ValidModelId) { std::unique_ptr discoverable_scanner_from_factory = FastPairDiscoverableScannerImpl::Factory::Create( - scanner_, adapter_, std::move(found_device_callback_), + *scanner_, std::move(found_device_callback_), std::move(lost_device_callback_)); auto ble_peripheral = @@ -136,7 +131,7 @@ TEST_F(FastPairDiscoverableScannerImplTest, InvalidModelId) { std::unique_ptr discoverable_scanner_from_factory = FastPairDiscoverableScannerImpl::Factory::Create( - scanner_, adapter_, std::move(found_device_callback_), + *scanner_, std::move(found_device_callback_), std::move(lost_device_callback_)); auto ble_peripheral = std::make_unique( @@ -153,7 +148,7 @@ TEST_F(FastPairDiscoverableScannerImplTest, NoServiceData) { std::unique_ptr discoverable_scanner_from_factory = FastPairDiscoverableScannerImpl::Factory::Create( - scanner_, adapter_, std::move(found_device_callback_), + *scanner_, std::move(found_device_callback_), std::move(lost_device_callback_)); auto ble_peripheral = @@ -174,7 +169,7 @@ TEST_F(FastPairDiscoverableScannerImplTest, UnsupportedDeviceType) { std::unique_ptr discoverable_scanner_from_factory = FastPairDiscoverableScannerImpl::Factory::Create( - scanner_, adapter_, std::move(found_device_callback_), + *scanner_, std::move(found_device_callback_), std::move(lost_device_callback_)); auto ble_peripheral = @@ -196,7 +191,7 @@ TEST_F(FastPairDiscoverableScannerImplTest, UnsupportedNotifictionType) { std::unique_ptr discoverable_scanner_from_factory = FastPairDiscoverableScannerImpl::Factory::Create( - scanner_, adapter_, std::move(found_device_callback_), + *scanner_, std::move(found_device_callback_), std::move(lost_device_callback_)); auto ble_peripheral = @@ -222,7 +217,7 @@ TEST_F(FastPairDiscoverableScannerImplTest, UnspecifiedNotificationType) { std::unique_ptr discoverable_scanner_from_factory = FastPairDiscoverableScannerImpl::Factory::Create( - scanner_, adapter_, std::move(found_device_callback_), + *scanner_, std::move(found_device_callback_), std::move(lost_device_callback_)); auto ble_peripheral = @@ -246,7 +241,7 @@ TEST_F(FastPairDiscoverableScannerImplTest, V1NotificationType) { std::unique_ptr discoverable_scanner_from_factory = FastPairDiscoverableScannerImpl::Factory::Create( - scanner_, adapter_, std::move(found_device_callback_), + *scanner_, std::move(found_device_callback_), std::move(lost_device_callback_)); auto ble_peripheral = @@ -270,7 +265,7 @@ TEST_F(FastPairDiscoverableScannerImplTest, V2NotificationType) { std::unique_ptr discoverable_scanner_from_factory = FastPairDiscoverableScannerImpl::Factory::Create( - scanner_, adapter_, std::move(found_device_callback_), + *scanner_, std::move(found_device_callback_), std::move(lost_device_callback_)); auto ble_peripheral = @@ -287,7 +282,7 @@ TEST_F(FastPairDiscoverableScannerImplTest, NearbyShareModelId) { std::unique_ptr discoverable_scanner_from_factory = FastPairDiscoverableScannerImpl::Factory::Create( - scanner_, adapter_, std::move(found_device_callback_), + *scanner_, std::move(found_device_callback_), std::move(lost_device_callback_)); auto ble_peripheral = std::make_unique( @@ -309,7 +304,7 @@ TEST_F(FastPairDiscoverableScannerImplTest, std::unique_ptr discoverable_scanner_from_factory = FastPairDiscoverableScannerImpl::Factory::Create( - scanner_, adapter_, std::move(found_device_callback_), + *scanner_, std::move(found_device_callback_), std::move(lost_device_callback_)); auto ble_peripheral = diff --git a/fastpair/scanning/fastpair/fast_pair_scanner.h b/fastpair/scanning/fastpair/fast_pair_scanner.h index 48d54980..1ace2606 100644 --- a/fastpair/scanning/fastpair/fast_pair_scanner.h +++ b/fastpair/scanning/fastpair/fast_pair_scanner.h @@ -38,7 +38,8 @@ class FastPairScanner { virtual void AddObserver(Observer* observer) = 0; virtual void RemoveObserver(Observer* observer) = 0; - protected: + virtual void StartScanning() = 0; + virtual ~FastPairScanner() = default; }; diff --git a/fastpair/scanning/fastpair/fast_pair_scanner_impl.cc b/fastpair/scanning/fastpair/fast_pair_scanner_impl.cc index 4b4efc71..770cc092 100644 --- a/fastpair/scanning/fastpair/fast_pair_scanner_impl.cc +++ b/fastpair/scanning/fastpair/fast_pair_scanner_impl.cc @@ -17,6 +17,7 @@ #include #include +#include "absl/time/time.h" #include "fastpair/common/constant.h" #include "internal/platform/byte_array.h" #include "internal/platform/logging.h" @@ -31,31 +32,9 @@ constexpr absl::Duration kFastPairLowPowerInactiveSeconds = absl::Seconds(3); constexpr char kFastPairServiceUuid[] = "0000FE2C-0000-1000-8000-00805F9B34FB"; } // namespace -// static -FastPairScannerImpl::Factory* FastPairScannerImpl::Factory::g_test_factory_ = - nullptr; - -// static -std::shared_ptr FastPairScannerImpl::Factory::Create() { - if (g_test_factory_) { - return g_test_factory_->CreateInstance(); - } - - return std::make_shared(); -} - -// static -void FastPairScannerImpl::Factory::SetFactoryForTesting( - Factory* g_test_factory) { - g_test_factory_ = g_test_factory; -} - -FastPairScannerImpl::Factory::~Factory() = default; - // FastPairScannerImpl -FastPairScannerImpl::FastPairScannerImpl() { +FastPairScannerImpl::FastPairScannerImpl(Mediums& mediums) : mediums_(mediums) { task_runner_ = std::make_unique(1); - StartScanning(); } void FastPairScannerImpl::AddObserver(FastPairScanner::Observer* observer) { @@ -67,10 +46,12 @@ void FastPairScannerImpl::RemoveObserver(FastPairScanner::Observer* observer) { } void FastPairScannerImpl::StartScanning() { + NEARBY_LOGS(VERBOSE) << __func__; task_runner_->PostTask( [this]() { - if (ble_.Enable() && - ble_.StartScanning( + if (mediums_.GetBluetoothRadio().Enable() && + mediums_.GetBle().IsAvailable() && + mediums_.GetBle().StartScanning( kServiceId, kFastPairServiceUuid, { .peripheral_discovered_cb = @@ -108,7 +89,7 @@ void FastPairScannerImpl::StartScanning() { void FastPairScannerImpl::StopScanning() { DCHECK(IsFastPairLowPowerEnabled()); - ble_.StopScanning(kServiceId); + mediums_.GetBle().StopScanning(kServiceId); task_runner_->PostDelayedTask(kFastPairLowPowerInactiveSeconds, [this]() { StartScanning(); }); } diff --git a/fastpair/scanning/fastpair/fast_pair_scanner_impl.h b/fastpair/scanning/fastpair/fast_pair_scanner_impl.h index 9162a425..4a8a15a0 100644 --- a/fastpair/scanning/fastpair/fast_pair_scanner_impl.h +++ b/fastpair/scanning/fastpair/fast_pair_scanner_impl.h @@ -15,18 +15,14 @@ #ifndef THIRD_PARTY_NEARBY_FASTPAIR_SCANNING_FASTPAIR_FAST_PAIR_SCANNER_IMPL_H_ #define THIRD_PARTY_NEARBY_FASTPAIR_SCANNING_FASTPAIR_FAST_PAIR_SCANNER_IMPL_H_ -#include #include #include #include -#include -#include "absl/strings/string_view.h" -#include "fastpair/internal/ble/ble.h" +#include "fastpair/internal/mediums/mediums.h" #include "fastpair/scanning/fastpair/fast_pair_scanner.h" #include "internal/base/observer_list.h" #include "internal/platform/bluetooth_adapter.h" -#include "internal/platform/byte_array.h" #include "internal/platform/task_runner.h" namespace nearby { @@ -34,21 +30,7 @@ namespace fastpair { class FastPairScannerImpl : public FastPairScanner { public: - class Factory { - public: - static std::shared_ptr Create(); - - static void SetFactoryForTesting(Factory* g_test_factory); - - protected: - virtual ~Factory(); - virtual std::shared_ptr CreateInstance() = 0; - - private: - static Factory* g_test_factory_; - }; - - FastPairScannerImpl(); + explicit FastPairScannerImpl(Mediums& mediums); FastPairScannerImpl(const FastPairScannerImpl&) = delete; FastPairScannerImpl& operator=(const FastPairScannerImpl&) = delete; ~FastPairScannerImpl() override = default; @@ -65,11 +47,9 @@ class FastPairScannerImpl : public FastPairScanner { // Todo(b/267348348): Support Flags to control feature ramp bool IsFastPairLowPowerEnabled() const { return false; } - // For unit test - Ble& GetBle() { return ble_; } + void StartScanning() override; private: - void StartScanning(); void StopScanning(); std::unique_ptr task_runner_; @@ -80,7 +60,7 @@ class FastPairScannerImpl : public FastPairScanner { device_address_advertisement_data_map_; BluetoothAdapter bluetooth_adapter_; - Ble ble_; + Mediums& mediums_; ObserverList observer_; }; diff --git a/fastpair/scanning/fastpair/fast_pair_scanner_impl_test.cc b/fastpair/scanning/fastpair/fast_pair_scanner_impl_test.cc index d0e520a0..e91d5848 100644 --- a/fastpair/scanning/fastpair/fast_pair_scanner_impl_test.cc +++ b/fastpair/scanning/fastpair/fast_pair_scanner_impl_test.cc @@ -14,153 +14,86 @@ #include "fastpair/scanning/fastpair/fast_pair_scanner_impl.h" -#include #include #include -#include #include "gtest/gtest.h" +#include "absl/strings/escaping.h" #include "absl/strings/string_view.h" -#include "absl/time/time.h" +#include "fastpair/internal/mediums/mediums.h" #include "fastpair/scanning/fastpair/fast_pair_scanner.h" #include "internal/platform/bluetooth_adapter.h" #include "internal/platform/byte_array.h" +#include "internal/platform/count_down_latch.h" #include "internal/platform/medium_environment.h" namespace nearby { namespace fastpair { namespace { -// Below constants are used to construct MockBluetoothDevice for testing. -constexpr char kTestBleDeviceAddress[] = "11:12:13:14:15:16"; -constexpr char kTestModelId[] = "112233"; -constexpr absl::Duration kTaskWaitTimeout = absl::Milliseconds(200); - -class FakeBlePeripheral : public api::BlePeripheral { - public: - explicit FakeBlePeripheral(absl::string_view name, - absl::string_view service_data) { - name_ = std::string(name); - std::string service_data_str = std::string(service_data); - ByteArray advertisement_bytes(service_data_str); - advertisement_data_ = advertisement_bytes; - } - FakeBlePeripheral(const FakeBlePeripheral&) = default; - ~FakeBlePeripheral() override = default; - - std::string GetName() const override { return name_; } - - ByteArray GetAdvertisementBytes( - const std::string& service_id) const override { - return advertisement_data_; - } - - void SetName(const std::string& name) { name_ = name; } - - void SetAdvertisementBytes(ByteArray advertisement_bytes) { - advertisement_data_ = advertisement_bytes; - } - - private: - std::string name_; - ByteArray advertisement_data_; -}; +constexpr absl::Duration kTaskWaitTimeout = absl::Milliseconds(1000); +constexpr absl::string_view kServiceID{"Fast Pair"}; +constexpr absl::string_view kModelId{"718c17"}; +constexpr absl::string_view kFastPairServiceUuid{ + "0000FE2C-0000-1000-8000-00805F9B34FB"}; class FastPairScannerObserver : public FastPairScanner::Observer { public: + explicit FastPairScannerObserver(FastPairScanner* scanner, + CountDownLatch* accept_latch, + CountDownLatch* lost_latch) { + accept_latch_ = accept_latch; + lost_latch_ = lost_latch; + scanner->AddObserver(this); + } // FastPairScanner::Observer overrides void OnDeviceFound(const BlePeripheral& peripheral) override { - device_addreses_.push_back(peripheral.GetName()); - on_device_found_count_++; + accept_latch_->CountDown(); } void OnDeviceLost(const BlePeripheral& peripheral) override { - auto it = std::find(device_addreses_.begin(), device_addreses_.end(), - peripheral.GetName()); - if (it == device_addreses_.end()) return; - device_addreses_.erase(it); + lost_latch_->CountDown(); } - bool DoesDeviceListContainTestDevice(const std::string& address) { - auto it = - std::find(device_addreses_.begin(), device_addreses_.end(), address); - return it != device_addreses_.end(); - } - - int on_device_found_count() { return on_device_found_count_; } - - private: - std::vector device_addreses_; - - int on_device_found_count_ = 0; + CountDownLatch* accept_latch_ = nullptr; + CountDownLatch* lost_latch_ = nullptr; }; class FastPairScannerImplTest : public testing::Test { - public: - void SetUp() override { - env_.Start(); - scanner_ = std::make_shared(); - SystemClock::Sleep(kTaskWaitTimeout); - scanner_observer_ = std::make_unique(); - scanner_->AddObserver(scanner_observer_.get()); - } - - void TearDown() override { - scanner_->RemoveObserver(scanner_observer_.get()); - scanner_.reset(); - scanner_observer_.reset(); - env_.Stop(); - } - - void TriggerOnDeviceFound(absl::string_view address, absl::string_view data) { - auto ble_peripheral = std::make_unique(address, data); - scanner_->OnDeviceFound(BlePeripheral(ble_peripheral.get())); - } - - void TriggerOnDeviceLost(absl::string_view address, absl::string_view data) { - auto ble_peripheral = std::make_unique(address, data); - scanner_->OnDeviceLost(BlePeripheral(ble_peripheral.get())); - } - protected: MediumEnvironment& env_{MediumEnvironment::Instance()}; - std::shared_ptr scanner_; - std::unique_ptr scanner_observer_; }; -TEST_F(FastPairScannerImplTest, StartScanningSuccessfully) { - EXPECT_TRUE(scanner_->GetBle().IsScanning()); - // Not StopScanning as FastPairLowPowerDisabled -} +TEST_F(FastPairScannerImplTest, StartScanning) { + env_.Start(); -TEST_F(FastPairScannerImplTest, DeviceFoundNotifiesObservers) { - TriggerOnDeviceFound(kTestBleDeviceAddress, kTestModelId); - EXPECT_TRUE(scanner_observer_->DoesDeviceListContainTestDevice( - kTestBleDeviceAddress)); -} + // Create Fast Pair Scanner and add its observer + Mediums mediums_1; + auto scanner = std::make_unique(mediums_1); + CountDownLatch accept_latch(1); + CountDownLatch lost_latch(1); + FastPairScannerObserver observer(scanner.get(), &accept_latch, &lost_latch); -TEST_F(FastPairScannerImplTest, DeviceLostNotifiesObservers) { - TriggerOnDeviceFound(kTestBleDeviceAddress, kTestModelId); - EXPECT_TRUE(scanner_observer_->DoesDeviceListContainTestDevice( - kTestBleDeviceAddress)); - TriggerOnDeviceLost(kTestBleDeviceAddress, kTestModelId); - EXPECT_FALSE(scanner_observer_->DoesDeviceListContainTestDevice( - kTestBleDeviceAddress)); -} + // Create Advertiser and startAdvertising + Mediums mediums_2; + std::string service_id(kServiceID); + ByteArray advertisement_bytes{absl::HexStringToBytes(kModelId)}; + std::string fast_pair_service_uuid(kFastPairServiceUuid); + mediums_2.GetBle().getMedium().StartAdvertising( + service_id, advertisement_bytes, fast_pair_service_uuid); -TEST_F(FastPairScannerImplTest, DeviceFoundWithNoServiceData) {; - TriggerOnDeviceFound(kTestBleDeviceAddress, ""); - EXPECT_FALSE(scanner_observer_->DoesDeviceListContainTestDevice( - kTestBleDeviceAddress)); -} + // Fast Pair scanner startScanning + scanner->StartScanning(); + // Notify device found + EXPECT_TRUE(accept_latch.Await(kTaskWaitTimeout).result()); -TEST_F(FastPairScannerImplTest, RemoveObserver) { - scanner_->RemoveObserver(scanner_observer_.get()); - TriggerOnDeviceFound(kTestBleDeviceAddress, kTestModelId); - EXPECT_FALSE(scanner_observer_->DoesDeviceListContainTestDevice( - kTestBleDeviceAddress)); -} + // Advertiser stopAdvertising + mediums_2.GetBle().getMedium().StopAdvertising(service_id); + // Notify device lost + EXPECT_TRUE(lost_latch.Await(kTaskWaitTimeout).result()); + env_.Stop(); +} } // namespace } // namespace fastpair } // namespace nearby diff --git a/fastpair/scanning/mock_scanner_broker.h b/fastpair/scanning/mock_scanner_broker.h index 0df0bea0..29042c8d 100644 --- a/fastpair/scanning/mock_scanner_broker.h +++ b/fastpair/scanning/mock_scanner_broker.h @@ -35,13 +35,13 @@ class MockScannerBroker : public ScannerBroker { observers_.RemoveObserver(observer); } - void NotifyDeviceFound(const FastPairDevice& device) { + void NotifyDeviceFound(FastPairDevice& device) { for (auto& observer : observers_.GetObservers()) { observer->OnDeviceFound(device); } } - void NotifyDeviceLost(const FastPairDevice& device) { + void NotifyDeviceLost(FastPairDevice& device) { for (auto& observer : observers_.GetObservers()) { observer->OnDeviceLost(device); } diff --git a/fastpair/scanning/scanner_broker.h b/fastpair/scanning/scanner_broker.h index 0e191e28..3242e7b4 100644 --- a/fastpair/scanning/scanner_broker.h +++ b/fastpair/scanning/scanner_broker.h @@ -32,8 +32,8 @@ class ScannerBroker { public: virtual ~Observer() = default; - virtual void OnDeviceFound(const FastPairDevice& device) = 0; - virtual void OnDeviceLost(const FastPairDevice& device) = 0; + virtual void OnDeviceFound(FastPairDevice& device) = 0; + virtual void OnDeviceLost(FastPairDevice& device) = 0; }; virtual ~ScannerBroker() = default; diff --git a/fastpair/scanning/scanner_broker_impl.cc b/fastpair/scanning/scanner_broker_impl.cc index 36a60d80..372caddf 100644 --- a/fastpair/scanning/scanner_broker_impl.cc +++ b/fastpair/scanning/scanner_broker_impl.cc @@ -15,21 +15,17 @@ #include "fastpair/scanning/scanner_broker_impl.h" #include -#include #include "absl/functional/bind_front.h" #include "fastpair/common/fast_pair_device.h" -#include "fastpair/scanning/fastpair/fast_pair_discoverable_scanner.h" #include "fastpair/scanning/fastpair/fast_pair_discoverable_scanner_impl.h" #include "fastpair/scanning/fastpair/fast_pair_scanner_impl.h" -#include "internal/platform/bluetooth_adapter.h" #include "internal/platform/logging.h" #include "internal/platform/task_runner_impl.h" namespace nearby { namespace fastpair { -ScannerBrokerImpl::ScannerBrokerImpl() { - adapter_ = std::make_shared(); +ScannerBrokerImpl::ScannerBrokerImpl(Mediums& mediums) : mediums_(mediums) { task_runner_ = std::make_unique(1); } @@ -50,16 +46,17 @@ void ScannerBrokerImpl::StopScanning(Protocol protocol) { NEARBY_LOGS(VERBOSE) << __func__ << ": protocol=" << protocol; task_runner_->PostTask([this]() { StopFastPairScanning(); }); } + void ScannerBrokerImpl::StartFastPairScanning() { DCHECK(!fast_pair_discoverable_scanner_); - DCHECK(adapter_); NEARBY_LOGS(VERBOSE) << "Starting Fast Pair Scanning."; - scanner_ = std::make_shared(); + scanner_ = std::make_unique(mediums_); fast_pair_discoverable_scanner_ = FastPairDiscoverableScannerImpl::Factory::Create( - scanner_, adapter_, + *scanner_, absl::bind_front(&ScannerBrokerImpl::NotifyDeviceFound, this), absl::bind_front(&ScannerBrokerImpl::NotifyDeviceLost, this)); + scanner_->StartScanning(); } void ScannerBrokerImpl::StopFastPairScanning() { @@ -69,7 +66,7 @@ void ScannerBrokerImpl::StopFastPairScanning() { NEARBY_LOGS(VERBOSE) << __func__ << "Stopping Fast Pair Scanning."; } -void ScannerBrokerImpl::NotifyDeviceFound(const FastPairDevice& device) { +void ScannerBrokerImpl::NotifyDeviceFound(FastPairDevice& device) { NEARBY_LOGS(INFO) << __func__ << ": Notifying device found, model id = " << device.GetModelId(); for (auto& observer : observers_.GetObservers()) { @@ -77,7 +74,7 @@ void ScannerBrokerImpl::NotifyDeviceFound(const FastPairDevice& device) { } } -void ScannerBrokerImpl::NotifyDeviceLost(const FastPairDevice& device) { +void ScannerBrokerImpl::NotifyDeviceLost(FastPairDevice& device) { NEARBY_LOGS(INFO) << __func__ << ": Notifying device lost, model id = " << device.GetModelId(); for (auto& observer : observers_.GetObservers()) { diff --git a/fastpair/scanning/scanner_broker_impl.h b/fastpair/scanning/scanner_broker_impl.h index bb40d6b7..36774597 100644 --- a/fastpair/scanning/scanner_broker_impl.h +++ b/fastpair/scanning/scanner_broker_impl.h @@ -15,16 +15,14 @@ #ifndef THIRD_PARTY_NEARBY_FASTPAIR_SCANNING_SCANNER_BROKER_IMPL_H_ #define THIRD_PARTY_NEARBY_FASTPAIR_SCANNING_SCANNER_BROKER_IMPL_H_ -#include #include -#include #include "fastpair/common/fast_pair_device.h" +#include "fastpair/internal/mediums/mediums.h" #include "fastpair/scanning/fastpair/fast_pair_discoverable_scanner.h" #include "fastpair/scanning/fastpair/fast_pair_scanner.h" #include "fastpair/scanning/scanner_broker.h" #include "internal/base/observer_list.h" -#include "internal/platform/bluetooth_adapter.h" #include "internal/platform/task_runner.h" namespace nearby { @@ -32,7 +30,7 @@ namespace fastpair { class ScannerBrokerImpl : public ScannerBroker { public: - explicit ScannerBrokerImpl(); + explicit ScannerBrokerImpl(Mediums& mediums); ~ScannerBrokerImpl() override = default; // ScannerBroker: @@ -44,12 +42,12 @@ class ScannerBrokerImpl : public ScannerBroker { private: void StartFastPairScanning(); void StopFastPairScanning(); - void NotifyDeviceFound(const FastPairDevice& device); - void NotifyDeviceLost(const FastPairDevice& device); + void NotifyDeviceFound(FastPairDevice& device); + void NotifyDeviceLost(FastPairDevice& device); + Mediums& mediums_; std::unique_ptr task_runner_; - std::shared_ptr scanner_; - std::shared_ptr adapter_; + std::unique_ptr scanner_; std::unique_ptr fast_pair_discoverable_scanner_; ObserverList observers_; }; diff --git a/fastpair/scanning/scanner_broker_impl_test.cc b/fastpair/scanning/scanner_broker_impl_test.cc index 6b3bf46b..273dcd04 100644 --- a/fastpair/scanning/scanner_broker_impl_test.cc +++ b/fastpair/scanning/scanner_broker_impl_test.cc @@ -22,7 +22,7 @@ #include "absl/strings/string_view.h" #include "fastpair/common/fast_pair_device.h" #include "fastpair/common/protocol.h" -#include "fastpair/internal/ble/ble.h" +#include "fastpair/internal/mediums/mediums.h" #include "fastpair/proto/fastpair_rpcs.proto.h" #include "fastpair/scanning/scanner_broker.h" #include "fastpair/server_access/fake_fast_pair_repository.h" @@ -52,11 +52,11 @@ class ScannerBrokerObserver : public ScannerBroker::Observer { scanner_broker->AddObserver(this); } - void OnDeviceFound(const FastPairDevice& device) override { + void OnDeviceFound(FastPairDevice& device) override { accept_latch_->CountDown(); } - void OnDeviceLost(const FastPairDevice& device) override { + void OnDeviceLost(FastPairDevice& device) override { lost_latch_->CountDown(); } @@ -71,28 +71,40 @@ class ScannerBrokerImplTest : public testing::Test { TEST_F(ScannerBrokerImplTest, CanStartScanning) { env_.Start(); - auto repository_ = std::make_unique(); - auto scanner_broker = std::make_unique(); - proto::Device metadata; + // Setup FakeFastPairRepository std::string decoded_key; absl::Base64Unescape(kPublicAntiSpoof, &decoded_key); + proto::Device metadata; + auto repository_ = std::make_unique(); metadata.mutable_anti_spoofing_key_pair()->set_public_key(decoded_key); repository_->SetFakeMetadata(kModelId, metadata); - std::string service_id(kServiceID); - ByteArray advertisement_bytes{absl::HexStringToBytes(kModelId)}; - std::string fast_pair_service_uuid(kFastPairServiceUuid); - Ble ble; + // Create Fast Pair Scanner and add its observer + Mediums mediums_1; + auto scanner_broker = std::make_unique(mediums_1); CountDownLatch accept_latch(1); CountDownLatch lost_latch(1); ScannerBrokerObserver observer(scanner_broker.get(), &accept_latch, &lost_latch); - ble.getMedium().StartAdvertising(service_id, advertisement_bytes, - fast_pair_service_uuid); + // Create Advertiser and startAdvertising + Mediums mediums_2; + std::string service_id(kServiceID); + ByteArray advertisement_bytes{absl::HexStringToBytes(kModelId)}; + std::string fast_pair_service_uuid(kFastPairServiceUuid); + mediums_2.GetBle().getMedium().StartAdvertising( + service_id, advertisement_bytes, fast_pair_service_uuid); + + // Fast Pair scanner startScanning scanner_broker->StartScanning(Protocol::kFastPairInitialPairing); + + // Notify device found EXPECT_TRUE(accept_latch.Await(kTaskWaitTimeout).result()); - ble.getMedium().StopAdvertising(service_id); + + // Advertiser stopAdvertising + mediums_2.GetBle().getMedium().StopAdvertising(service_id); + + // Notify device lost EXPECT_TRUE(lost_latch.Await(kTaskWaitTimeout).result()); env_.Stop(); }