diff --git a/fastpair/BUILD b/fastpair/BUILD index 248cddf5..3387cb3d 100644 --- a/fastpair/BUILD +++ b/fastpair/BUILD @@ -97,13 +97,20 @@ cc_library( deps = [ ":fast_pair_plugin", ":fast_pair_seeker", + "//fastpair/common", "//fastpair/internal", "//fastpair/repository:device_repository", "//fastpair/server_access", + "//internal/account", + "//internal/auth:oauth_lib", + "//internal/auth:types", "//internal/flags:nearby_flags", + "//internal/network:nearby_http_client", + "//internal/network:types", "//internal/platform:base", "//internal/platform:types", "//internal/platform/flags:platform_flags", + "//internal/preferences", "@com_google_absl//absl/container:flat_hash_map", "@com_google_absl//absl/status", "@com_google_absl//absl/strings", @@ -123,10 +130,14 @@ cc_test( "//fastpair/internal", "//fastpair/message_stream:fake_provider", "//fastpair/plugins:fake_fast_pair_plugin", - "//fastpair/server_access:test_support", + "//internal/account:test_support", + "//internal/network:types", "//internal/platform:logging", "//internal/platform:test_util", + "//internal/platform:types", "//internal/platform/implementation/g3", # build_cleaner: keep + "//internal/test", + "//internal/test/google3_only:test", "@com_github_protobuf_matchers//protobuf-matchers", "@com_google_googletest//:gtest_main", ], diff --git a/fastpair/fast_pair_controller.cc b/fastpair/fast_pair_controller.cc index cf3b6ce4..ab3aed9d 100644 --- a/fastpair/fast_pair_controller.cc +++ b/fastpair/fast_pair_controller.cc @@ -92,8 +92,14 @@ FastPairController::GetDataEncryptor() { CreateDataEncryptor(); } else { FastPairRepository::Get()->GetDeviceMetadata( - device_->GetModelId(), [this](DeviceMetadata& metadata) { - device_->SetMetadata(metadata); + device_->GetModelId(), + [this](std::optional metadata) { + if (!metadata.has_value()) { + NEARBY_LOGS(WARNING) + << __func__ << ": Failed to get device metadata"; + return; + } + device_->SetMetadata(metadata.value()); CreateDataEncryptor(); }); } diff --git a/fastpair/fast_pair_service.cc b/fastpair/fast_pair_service.cc index c5783192..2d1d9b8e 100644 --- a/fastpair/fast_pair_service.cc +++ b/fastpair/fast_pair_service.cc @@ -14,36 +14,62 @@ #include "fastpair/fast_pair_service.h" -#include #include #include #include #include "absl/status/status.h" #include "absl/strings/str_format.h" +#include "fastpair/common/fast_pair_prefs.h" #include "fastpair/fast_pair_plugin.h" #include "fastpair/internal/fast_pair_seeker_impl.h" +#include "fastpair/server_access/fast_pair_client_impl.h" +#include "fastpair/server_access/fast_pair_http_notifier.h" #include "fastpair/server_access/fast_pair_repository_impl.h" +#include "internal/account/account_manager_impl.h" +#include "internal/auth/authentication_manager_impl.h" #include "internal/flags/nearby_flags.h" +#include "internal/network/http_client_impl.h" +#include "internal/platform/device_info_impl.h" #include "internal/platform/feature_flags.h" #include "internal/platform/flags/nearby_platform_feature_flags.h" #include "internal/platform/logging.h" +#include "internal/platform/task_runner_impl.h" namespace nearby { namespace fastpair { namespace { -constexpr absl::Duration kTimeout = absl::Seconds(3); +constexpr char kFastPairPreferencesFilePath[] = "Google/Nearby/FastPair"; constexpr FeatureFlags::Flags fast_pair_feature_flags = FeatureFlags::Flags{ .enable_scan_for_fast_pair_advertisement = true, }; +constexpr absl::Duration kTimeout = absl::Seconds(3); } FastPairService::FastPairService() - : FastPairService(std::make_unique()) {} + : FastPairService(std::make_unique(), + std::make_unique(), + std::make_unique()) {} -FastPairService::FastPairService(std::unique_ptr repository) - : fast_pair_repository_(std::move(repository)), +FastPairService::FastPairService( + std::unique_ptr authentication_manager, + std::unique_ptr http_client, + std::unique_ptr device_info) + : authentication_manager_(std::move(authentication_manager)), + http_client_(std::move(http_client)), + device_info_(std::move(device_info)), + task_runner_(std::make_unique(1)), + preferences_manager_(std::make_unique( + kFastPairPreferencesFilePath)), + account_manager_(AccountManagerImpl::Factory::Create( + preferences_manager_.get(), prefs::kNearbyFastPairUsersName, + authentication_manager_.get(), task_runner_.get())), + fast_pair_client_(std::make_unique( + authentication_manager_.get(), account_manager_.get(), + http_client_.get(), &fast_pair_http_notifier_, device_info_.get())), + fast_pair_repository_( + std::make_unique(fast_pair_client_.get())), on_device_destroyed_callback_( [this](const FastPairDevice& device) { OnDeviceDestroyed(device); }) { NearbyFlags::GetInstance().OverrideBoolFlagValue( @@ -52,6 +78,7 @@ FastPairService::FastPairService(std::unique_ptr repository) true); const_cast(FeatureFlags::GetInstance()) .SetFlags(fast_pair_feature_flags); + devices_.AddObserver(&on_device_destroyed_callback_); seeker_ = std::make_unique( FastPairSeekerImpl::ServiceCallbacks{ diff --git a/fastpair/fast_pair_service.h b/fastpair/fast_pair_service.h index bcd53a98..68428400 100644 --- a/fastpair/fast_pair_service.h +++ b/fastpair/fast_pair_service.h @@ -17,8 +17,6 @@ #include #include -#include -#include #include "absl/container/flat_hash_map.h" #include "absl/status/status.h" @@ -26,8 +24,16 @@ #include "fastpair/fast_pair_plugin.h" #include "fastpair/fast_pair_seeker.h" #include "fastpair/repository/fast_pair_device_repository.h" +#include "fastpair/server_access/fast_pair_client.h" +#include "fastpair/server_access/fast_pair_http_notifier.h" #include "fastpair/server_access/fast_pair_repository.h" +#include "internal/account/account_manager.h" +#include "internal/auth/authentication_manager.h" +#include "internal/network/http_client.h" +#include "internal/platform/device_info.h" #include "internal/platform/single_thread_executor.h" +#include "internal/platform/task_runner.h" +#include "internal/preferences/preferences_manager.h" namespace nearby { namespace fastpair { @@ -39,7 +45,10 @@ class FastPairService { FastPairService(); // Constructor for tests. Allows us to inject a serverless metadata // repository. - explicit FastPairService(std::unique_ptr repository); + FastPairService( + std::unique_ptr authentication_manager, + std::unique_ptr http_client, + std::unique_ptr device_info); ~FastPairService(); // Registers a plugin provider. `name` must be a unique. @@ -74,11 +83,20 @@ class FastPairService { void OnBatteryEvent(const FastPairDevice& device, BatteryEvent event); void OnRingEvent(const FastPairDevice& device, RingEvent event); void OnDeviceDestroyed(const FastPairDevice& device); + SingleThreadExecutor executor_; + FastPairHttpNotifier fast_pair_http_notifier_; std::unique_ptr seeker_; // Plugin name is the key. absl::flat_hash_map plugin_states_; FastPairDeviceRepository devices_{&executor_}; + std::unique_ptr authentication_manager_; + std::unique_ptr http_client_; + std::unique_ptr device_info_; + std::unique_ptr task_runner_; + std::unique_ptr preferences_manager_; + std::unique_ptr account_manager_; + std::unique_ptr fast_pair_client_; std::unique_ptr fast_pair_repository_; FastPairDeviceRepository::RemoveDeviceCallback on_device_destroyed_callback_; }; diff --git a/fastpair/fast_pair_service_test.cc b/fastpair/fast_pair_service_test.cc index e480b2a0..8a3407a6 100644 --- a/fastpair/fast_pair_service_test.cc +++ b/fastpair/fast_pair_service_test.cc @@ -25,23 +25,72 @@ #include "fastpair/internal/fast_pair_seeker_impl.h" #include "fastpair/message_stream/fake_provider.h" #include "fastpair/plugins/fake_fast_pair_plugin.h" -#include "fastpair/server_access/fake_fast_pair_repository.h" +#include "internal/account/fake_account_manager.h" +#include "internal/network/http_client.h" +#include "internal/platform/device_info.h" #include "internal/platform/logging.h" #include "internal/platform/medium_environment.h" +#include "internal/test/fake_device_info.h" +#include "internal/test/fake_http_client.h" +#include "internal/test/google3_only/fake_authentication_manager.h" namespace nearby { namespace fastpair { namespace { +constexpr absl::string_view kPluginName = "my plugin"; constexpr absl::string_view kModelId{"718c17"}; constexpr absl::string_view kPublicAntiSpoof = "Wuyr48lD3txnUhGiMF1IfzlTwRxxe+wMB1HLzP+" "0wVcljfT3XPoiy1fntlneziyLD5knDVAJSE+RM/zlPRP/Jg=="; - using ::testing::status::StatusIs; +class FastPairServiceTest : public ::testing::Test { + protected: + FastPairServiceTest() { + AccountManagerImpl::Factory::SetFactoryForTesting( + &account_manager_factory_); + http_client_ = std::make_unique(); + device_info_ = std::make_unique(); + authentication_manager_ = + std::make_unique(); + } + + void SetUp() override { + MediumEnvironment::Instance().Start(); + GetAuthManager()->EnableSyncMode(); + } + + void TearDown() override { MediumEnvironment::Instance().Stop(); } + + nearby::FakeAuthenticationManager* GetAuthManager() { + return reinterpret_cast( + authentication_manager_.get()); + } + + network::FakeHttpClient* GetHttpClient() { + return reinterpret_cast(http_client_.get()); + } + + void SetUpDeviceMetadata() { + proto::GetObservedDeviceResponse response_proto; + auto* device = response_proto.mutable_device(); + int64_t device_id; + CHECK(absl::SimpleHexAtoi(kModelId, &device_id)); + device->set_id(device_id); + network::HttpResponse response; + response.SetStatusCode(network::HttpStatusCode::kHttpOk); + response.SetBody(response_proto.SerializeAsString()); + GetHttpClient()->SetResponseForSyncRequest(response); + } + + FakeAccountManager::Factory account_manager_factory_; + std::unique_ptr authentication_manager_; + std::unique_ptr http_client_; + std::unique_ptr device_info_; +}; + TEST(FastPairService, RegisterUnregister) { - constexpr absl::string_view kPluginName = "my plugin"; FastPairService service; EXPECT_OK(service.RegisterPluginProvider( @@ -50,7 +99,6 @@ TEST(FastPairService, RegisterUnregister) { } TEST(FastPairService, RegisterTwiceFails) { - constexpr absl::string_view kPluginName = "my plugin"; FastPairService service; EXPECT_OK(service.RegisterPluginProvider( kPluginName, std::make_unique())); @@ -61,7 +109,6 @@ TEST(FastPairService, RegisterTwiceFails) { } TEST(FastPairService, UnregisterTwiceFails) { - constexpr absl::string_view kPluginName = "my plugin"; FastPairService service; EXPECT_OK(service.RegisterPluginProvider( kPluginName, std::make_unique())); @@ -71,12 +118,12 @@ TEST(FastPairService, UnregisterTwiceFails) { StatusIs(absl::StatusCode::kNotFound)); } -TEST(FastPairService, InitialDiscoveryEvent) { - MediumEnvironment::Instance().Start(); - constexpr absl::string_view kPluginName = "my plugin"; - auto repository = FakeFastPairRepository::Create(kModelId, kPublicAntiSpoof); +TEST_F(FastPairServiceTest, InitialDiscoveryEvent) { FakeProvider provider; - FastPairService service(std::move(repository)); + SetUpDeviceMetadata(); + FastPairService service(std::move(authentication_manager_), + std::move(http_client_), std::move(device_info_)); + CountDownLatch latch(1); auto plugin_provider = std::make_unique(); plugin_provider->on_initial_discovery_event_ = @@ -96,15 +143,14 @@ TEST(FastPairService, InitialDiscoveryEvent) { EXPECT_OK(seeker->StopFastPairScan()); EXPECT_OK(service.UnregisterPluginProvider(kPluginName)); - MediumEnvironment::Instance().Stop(); } -TEST(FastPairService, ScreenEvent) { - MediumEnvironment::Instance().Start(); - constexpr absl::string_view kPluginName = "my plugin"; - auto repository = FakeFastPairRepository::Create(kModelId, kPublicAntiSpoof); +TEST_F(FastPairServiceTest, ScreenEvent) { FakeProvider provider; - FastPairService service(std::move(repository)); + SetUpDeviceMetadata(); + FastPairService service(std::move(authentication_manager_), + std::move(http_client_), std::move(device_info_)); + CountDownLatch latch(1); auto plugin_provider = std::make_unique(); plugin_provider->on_initial_discovery_event_ = @@ -128,7 +174,6 @@ TEST(FastPairService, ScreenEvent) { EXPECT_OK(seeker->StopFastPairScan()); EXPECT_OK(service.UnregisterPluginProvider(kPluginName)); - MediumEnvironment::Instance().Stop(); } } // namespace diff --git a/fastpair/keyed_service/BUILD b/fastpair/keyed_service/BUILD index 269af047..5b2d5324 100644 --- a/fastpair/keyed_service/BUILD +++ b/fastpair/keyed_service/BUILD @@ -32,15 +32,21 @@ cc_library( "//fastpair/internal/mediums", "//fastpair/pairing", "//fastpair/repository:device_repository", - "//fastpair/retroactive", "//fastpair/scanning:scanner", "//fastpair/server_access", "//fastpair/ui:fast_pair_ui", + "//internal/account", + "//internal/auth:oauth_lib", + "//internal/auth:types", "//internal/flags:nearby_flags", + "//internal/network:nearby_http_client", + "//internal/network:types", "//internal/platform:base", "//internal/platform:logging", "//internal/platform:types", "//internal/platform/flags:platform_flags", + "//internal/preferences", + "@com_google_absl//absl/status", ], ) @@ -58,9 +64,13 @@ cc_test( "//fastpair/testing", "//fastpair/ui:fast_pair_ui", "//fastpair/ui:mock_fast_pair_ui", + "//internal/account:test_support", + "//internal/network:nearby_http_client", "//internal/platform:test_util", "//internal/platform:types", "//internal/platform/implementation/g3", # build_cleaner: keep + "//internal/test", + "//internal/test/google3_only:test", "@com_github_protobuf_matchers//protobuf-matchers", "@com_google_absl//absl/strings", "@com_google_googletest//:gtest_main", diff --git a/fastpair/keyed_service/fast_pair_mediator.cc b/fastpair/keyed_service/fast_pair_mediator.cc index c698963f..19faffd9 100644 --- a/fastpair/keyed_service/fast_pair_mediator.cc +++ b/fastpair/keyed_service/fast_pair_mediator.cc @@ -17,42 +17,53 @@ #include #include #include +#include #include +#include "absl/status/status.h" +#include "fastpair/common/fast_pair_prefs.h" #include "fastpair/common/protocol.h" #include "fastpair/internal/mediums/mediums.h" #include "fastpair/pairing/pairer_broker_impl.h" #include "fastpair/repository/fast_pair_device_repository.h" #include "fastpair/scanning/scanner_broker_impl.h" +#include "fastpair/server_access/fast_pair_client_impl.h" #include "fastpair/server_access/fast_pair_repository_impl.h" #include "fastpair/ui/actions.h" #include "fastpair/ui/fast_pair/fast_pair_notification_controller.h" #include "fastpair/ui/ui_broker_impl.h" +#include "internal/account/account_manager_impl.h" #include "internal/flags/nearby_flags.h" -#include "internal/platform/device_info_impl.h" #include "internal/platform/feature_flags.h" #include "internal/platform/flags/nearby_platform_feature_flags.h" #include "internal/platform/logging.h" #include "internal/platform/single_thread_executor.h" +#include "internal/platform/task_runner_impl.h" +#include "internal/preferences/preferences_manager.h" namespace nearby { namespace fastpair { namespace { +constexpr char kFastPairPreferencesFilePath[] = "Google/Nearby/FastPair"; constexpr FeatureFlags::Flags fast_pair_feature_flags = FeatureFlags::Flags{ .enable_scan_for_fast_pair_advertisement = true, }; } Mediator::Mediator( + std::unique_ptr executor, std::unique_ptr mediums, std::unique_ptr ui_broker, std::unique_ptr notification_controller, - std::unique_ptr fast_pair_repository, - std::unique_ptr executor) - : mediums_(std::move(mediums)), + std::unique_ptr authentication_manager, + std::unique_ptr http_client, + std::unique_ptr device_info) + : executor_(std::move(executor)), + mediums_(std::move(mediums)), ui_broker_(std::move(ui_broker)), notification_controller_(std::move(notification_controller)), - fast_pair_repository_(std::move(fast_pair_repository)), - executor_(std::move(executor)) { + authentication_manager_(std::move(authentication_manager)), + http_client_(std::move(http_client)), + device_info_(std::move(device_info)) { NearbyFlags::GetInstance().OverrideBoolFlagValue( platform::config_package_nearby::nearby_platform_feature:: kEnableBleV2Gatt, @@ -65,7 +76,17 @@ Mediator::Mediator( *mediums_, executor_.get(), devices_.get()); pairer_broker_ = std::make_unique(*mediums_, executor_.get()); - + task_runner_ = std::make_unique(1); + preferences_manager_ = std::make_unique( + kFastPairPreferencesFilePath); + account_manager_ = AccountManagerImpl::Factory::Create( + preferences_manager_.get(), prefs::kNearbyFastPairUsersName, + authentication_manager_.get(), task_runner_.get()); + fast_pair_client_ = std::make_unique( + authentication_manager_.get(), account_manager_.get(), http_client_.get(), + &fast_pair_http_notifier_, device_info_.get()); + fast_pair_repository_ = + std::make_unique(fast_pair_client_.get()); scanner_broker_->AddObserver(this); ui_broker_->AddObserver(this); pairer_broker_->AddObserver(this); diff --git a/fastpair/keyed_service/fast_pair_mediator.h b/fastpair/keyed_service/fast_pair_mediator.h index 34d30982..69dce3e3 100644 --- a/fastpair/keyed_service/fast_pair_mediator.h +++ b/fastpair/keyed_service/fast_pair_mediator.h @@ -24,10 +24,18 @@ #include "fastpair/pairing/pairer_broker.h" #include "fastpair/repository/fast_pair_device_repository.h" #include "fastpair/scanning/scanner_broker.h" +#include "fastpair/server_access/fast_pair_client.h" +#include "fastpair/server_access/fast_pair_http_notifier.h" #include "fastpair/server_access/fast_pair_repository.h" #include "fastpair/ui/fast_pair/fast_pair_notification_controller.h" #include "fastpair/ui/ui_broker.h" +#include "internal/account/account_manager.h" +#include "internal/auth/authentication_manager.h" +#include "internal/network/http_client.h" +#include "internal/platform/device_info.h" #include "internal/platform/single_thread_executor.h" +#include "internal/platform/task_runner.h" +#include "internal/preferences/preferences_manager.h" namespace nearby { namespace fastpair { @@ -38,10 +46,12 @@ class Mediator final : public ScannerBroker::Observer, public PairerBroker::Observer { public: Mediator( + std::unique_ptr executor, std::unique_ptr mediums, std::unique_ptr ui_broker, std::unique_ptr notification_controller, - std::unique_ptr fast_pair_repository, - std::unique_ptr executor); + std::unique_ptr authentication_manager, + std::unique_ptr http_client, + std::unique_ptr device_info); Mediator(const Mediator&) = delete; Mediator& operator=(const Mediator&) = delete; ~Mediator() override { @@ -60,13 +70,13 @@ class Mediator final : public ScannerBroker::Observer, return notification_controller_.get(); } + void StartScanning(); + void StopScanning(); + // ScannerBroker::Observer void OnDeviceFound(FastPairDevice& device) override; void OnDeviceLost(FastPairDevice& device) override; - void StartScanning(); - void StopScanning(); - // UIBroker::Observer void OnDiscoveryAction(FastPairDevice& device, DiscoveryAction action) override; @@ -89,7 +99,8 @@ class Mediator final : public ScannerBroker::Observer, // |device_currently_showing_notification_| can be null if there is no // notification currently displayed to the user. FastPairDevice* device_currently_showing_notification_ = nullptr; - + FastPairHttpNotifier fast_pair_http_notifier_; + std::unique_ptr executor_; std::unique_ptr mediums_; std::unique_ptr scanner_broker_; std::unique_ptr scanning_session_; @@ -97,8 +108,14 @@ class Mediator final : public ScannerBroker::Observer, std::unique_ptr pairer_broker_; std::unique_ptr notification_controller_; std::unique_ptr fast_pair_repository_; - std::unique_ptr executor_; + std::unique_ptr task_runner_; std::unique_ptr devices_; + std::unique_ptr account_manager_; + std::unique_ptr preferences_manager_; + std::unique_ptr authentication_manager_; + std::unique_ptr fast_pair_client_; + std::unique_ptr http_client_; + std::unique_ptr device_info_; bool is_screen_locked_ = false; }; diff --git a/fastpair/keyed_service/fast_pair_mediator_factory.cc b/fastpair/keyed_service/fast_pair_mediator_factory.cc index 0a0560ac..5e87f8f1 100644 --- a/fastpair/keyed_service/fast_pair_mediator_factory.cc +++ b/fastpair/keyed_service/fast_pair_mediator_factory.cc @@ -17,9 +17,11 @@ #include #include "fastpair/internal/mediums/mediums.h" -#include "fastpair/server_access/fast_pair_repository_impl.h" #include "fastpair/ui/fast_pair/fast_pair_notification_controller.h" #include "fastpair/ui/ui_broker_impl.h" +#include "internal/auth/authentication_manager_impl.h" +#include "internal/network/http_client_impl.h" +#include "internal/platform/device_info_impl.h" #include "internal/platform/single_thread_executor.h" namespace nearby { @@ -32,10 +34,12 @@ MediatorFactory* MediatorFactory::GetInstance() { Mediator* MediatorFactory::CreateMediator() { mediator_ = std::make_unique( - std::make_unique(), std::make_unique(), + std::make_unique(), std::make_unique(), + std::make_unique(), std::make_unique(), - std::make_unique(), - std::make_unique()); + std::make_unique(), + std::make_unique(), + std::make_unique()); return mediator_.get(); } diff --git a/fastpair/keyed_service/fast_pair_mediator_test.cc b/fastpair/keyed_service/fast_pair_mediator_test.cc index 22452052..a9d50dbd 100644 --- a/fastpair/keyed_service/fast_pair_mediator_test.cc +++ b/fastpair/keyed_service/fast_pair_mediator_test.cc @@ -14,7 +14,6 @@ #include "fastpair/keyed_service/fast_pair_mediator.h" -#include #include #include #include @@ -29,12 +28,16 @@ #include "fastpair/testing/fast_pair_service_data_creator.h" #include "fastpair/ui/actions.h" #include "fastpair/ui/fast_pair/fast_pair_notification_controller.h" -#include "fastpair/ui/fast_pair/mock_fast_pair_notification_controller.h" #include "fastpair/ui/mock_ui_broker.h" #include "fastpair/ui/ui_broker.h" -#include "fastpair/ui/ui_broker_impl.h" +#include "internal/account/fake_account_manager.h" +#include "internal/network/http_client_impl.h" +#include "internal/platform/device_info_impl.h" #include "internal/platform/medium_environment.h" #include "internal/platform/single_thread_executor.h" +#include "internal/test/fake_device_info.h" +#include "internal/test/fake_http_client.h" +#include "internal/test/google3_only/fake_authentication_manager.h" namespace nearby { namespace fastpair { @@ -61,19 +64,18 @@ constexpr absl::string_view kAddress = "74:74:46:01:6C:21"; class MediatorTest : public testing::Test { public: + MediatorTest() { + AccountManagerImpl::Factory::SetFactoryForTesting( + &account_manager_factory_); + http_client_ = std::make_unique(); + device_info_ = std::make_unique(); + authentication_manager_ = + std::make_unique(); + } void SetUp() override { env_.Start(); + GetAuthManager()->EnableSyncMode(); mediums_ = std::make_unique(); - - // Setup FakeFastPairRepository for two devices - repository_ = FakeFastPairRepository::Create(kModelId, kPublicAntiSpoof); - - std::string decoded_key; - absl::Base64Unescape(kPublicAntiSpoof2, &decoded_key); - proto::Device metadata; - metadata.mutable_anti_spoofing_key_pair()->set_public_key(decoded_key); - repository_->SetFakeMetadata(kModelId2, metadata); - ui_broker_ = std::make_unique(); mock_ui_broker_ = static_cast(ui_broker_.get()); @@ -94,6 +96,27 @@ class MediatorTest : public testing::Test { env_.Stop(); } + nearby::FakeAuthenticationManager* GetAuthManager() { + return reinterpret_cast( + authentication_manager_.get()); + } + + network::FakeHttpClient* GetHttpClient() { + return reinterpret_cast(http_client_.get()); + } + + void SetUpDeviceMetadata() { + proto::GetObservedDeviceResponse response_proto; + auto* device = response_proto.mutable_device(); + int64_t device_id; + CHECK(absl::SimpleHexAtoi(kModelId, &device_id)); + device->set_id(device_id); + network::HttpResponse response; + response.SetStatusCode(network::HttpStatusCode::kHttpOk); + response.SetBody(response_proto.SerializeAsString()); + GetHttpClient()->SetResponseForSyncRequest(response); + } + protected: MediumEnvironment& env_{MediumEnvironment::Instance()}; std::unique_ptr mediums_; @@ -103,20 +126,24 @@ class MediatorTest : public testing::Test { std::unique_ptr executor_; MockUIBroker* mock_ui_broker_; std::unique_ptr mediator_; + FakeAccountManager::Factory account_manager_factory_; + std::unique_ptr authentication_manager_; + std::unique_ptr http_client_; + std::unique_ptr device_info_; }; TEST_F(MediatorTest, StartScanningFoundDevice) { + SetUpDeviceMetadata(); + // Create Fast Pair Mediator + mediator_ = std::make_unique( + std::move(executor_), std::move(mediums_), std::move(ui_broker_), + std::move(notification_controller_), std::move(authentication_manager_), + std::move(http_client_), std::move(device_info_)); absl::Notification done; EXPECT_CALL(*mock_ui_broker_, ShowDiscovery).WillOnce([&done] { done.Notify(); }); - // Create Fast Pair Mediator - mediator_ = - std::make_unique(std::move(mediums_), std::move(ui_broker_), - std::move(notification_controller_), - std::move(repository_), std::move(executor_)); - // Create Advertiser and startAdvertising Mediums mediums_advertiser; std::string service_id(kServiceID); @@ -130,17 +157,17 @@ TEST_F(MediatorTest, StartScanningFoundDevice) { } TEST_F(MediatorTest, StartScanningFoundDifferentDeviceWhenDisplaying) { + SetUpDeviceMetadata(); + // Create Fast Pair Mediator + mediator_ = std::make_unique( + std::move(executor_), std::move(mediums_), std::move(ui_broker_), + std::move(notification_controller_), std::move(authentication_manager_), + std::move(http_client_), std::move(device_info_)); absl::Notification done; EXPECT_CALL(*mock_ui_broker_, ShowDiscovery).Times(1).WillOnce([&done] { done.Notify(); }); - // Create Fast Pair Mediator - mediator_ = - std::make_unique(std::move(mediums_), std::move(ui_broker_), - std::move(notification_controller_), - std::move(repository_), std::move(executor_)); - // Create Advertiser and startAdvertising Mediums mediums_advertiser; std::string service_id(kServiceID); @@ -160,17 +187,17 @@ TEST_F(MediatorTest, StartScanningFoundDifferentDeviceWhenDisplaying) { } TEST_F(MediatorTest, StartScanningFoundSameDeviceWhenDisplaying) { + SetUpDeviceMetadata(); + // Create Fast Pair Mediator + mediator_ = std::make_unique( + std::move(executor_), std::move(mediums_), std::move(ui_broker_), + std::move(notification_controller_), std::move(authentication_manager_), + std::move(http_client_), std::move(device_info_)); absl::Notification done; EXPECT_CALL(*mock_ui_broker_, ShowDiscovery).Times(1).WillOnce([&done] { done.Notify(); }); - // Create Fast Pair Mediator - mediator_ = - std::make_unique(std::move(mediums_), std::move(ui_broker_), - std::move(notification_controller_), - std::move(repository_), std::move(executor_)); - // Create Advertiser and startAdvertising Mediums mediums_advertiser; std::string service_id(kServiceID); @@ -191,17 +218,17 @@ TEST_F(MediatorTest, StartScanningFoundSameDeviceWhenDisplaying) { TEST_F(MediatorTest, StartScanningForSubsequentPairingFoundSameDeviceWhenDisplaying) { + SetUpDeviceMetadata(); + // Create Fast Pair Mediator + mediator_ = std::make_unique( + std::move(executor_), std::move(mediums_), std::move(ui_broker_), + std::move(notification_controller_), std::move(authentication_manager_), + std::move(http_client_), std::move(device_info_)); absl::Notification done; EXPECT_CALL(*mock_ui_broker_, ShowDiscovery).Times(1).WillOnce([&done] { done.Notify(); }); - // Create Fast Pair Mediator - mediator_ = - std::make_unique(std::move(mediums_), std::move(ui_broker_), - std::move(notification_controller_), - std::move(repository_), std::move(executor_)); - // Create Advertiser and advertising discoverable advertisement Mediums mediums_advertiser; std::string service_id(kServiceID); @@ -231,17 +258,19 @@ TEST_F(MediatorTest, } TEST_F(MediatorTest, OnDiscoveryActionClicked) { + SetUpDeviceMetadata(); + SetUpDeviceMetadata(); + // Create Fast Pair Mediator + mediator_ = std::make_unique( + std::move(executor_), std::move(mediums_), std::move(ui_broker_), + std::move(notification_controller_), std::move(authentication_manager_), + std::move(http_client_), std::move(device_info_)); + absl::Notification done; EXPECT_CALL(*mock_ui_broker_, ShowDiscovery).Times(2).WillOnce([&done] { done.Notify(); }); - // Create Fast Pair Mediator - mediator_ = - std::make_unique(std::move(mediums_), std::move(ui_broker_), - std::move(notification_controller_), - std::move(repository_), std::move(executor_)); - // Create Advertiser and startAdvertising Mediums mediums_advertiser; std::string service_id(kServiceID); diff --git a/fastpair/pairing/fastpair/fast_pair_pairer_impl_test.cc b/fastpair/pairing/fastpair/fast_pair_pairer_impl_test.cc index 11d0cdbf..3c7bbe66 100644 --- a/fastpair/pairing/fastpair/fast_pair_pairer_impl_test.cc +++ b/fastpair/pairing/fastpair/fast_pair_pairer_impl_test.cc @@ -142,10 +142,12 @@ class FastPairPairerImplTest : public testing::Test { device_->SetAccountKey(AccountKey(account_key_)); } CountDownLatch latch(1); - repository_->GetDeviceMetadata(kMetadataId, [&](DeviceMetadata& metadata) { - device_->SetMetadata(std::move(metadata)); - latch.CountDown(); - }); + repository_->GetDeviceMetadata( + kMetadataId, [&](std::optional metadata) { + EXPECT_TRUE(metadata.has_value()); + device_->SetMetadata(std::move(metadata.value())); + latch.CountDown(); + }); latch.Await(); } diff --git a/fastpair/pairing/pairer_broker_impl_test.cc b/fastpair/pairing/pairer_broker_impl_test.cc index 674fb8d1..a2a82582 100644 --- a/fastpair/pairing/pairer_broker_impl_test.cc +++ b/fastpair/pairing/pairer_broker_impl_test.cc @@ -186,10 +186,12 @@ class PairerBrokerImplTest : public testing::Test { device_->SetAccountKey(AccountKey(account_key_)); } CountDownLatch latch(1); - repository_->GetDeviceMetadata(kMetadataId, [&](DeviceMetadata& metadata) { - device_->SetMetadata(std::move(metadata)); - latch.CountDown(); - }); + repository_->GetDeviceMetadata( + kMetadataId, [&](std::optional metadata) { + EXPECT_TRUE(metadata.has_value()); + device_->SetMetadata(std::move(metadata.value())); + latch.CountDown(); + }); latch.Await(); } diff --git a/fastpair/scanning/fastpair/fast_pair_discoverable_scanner_impl.cc b/fastpair/scanning/fastpair/fast_pair_discoverable_scanner_impl.cc index 752b792c..dac16eaf 100644 --- a/fastpair/scanning/fastpair/fast_pair_discoverable_scanner_impl.cc +++ b/fastpair/scanning/fastpair/fast_pair_discoverable_scanner_impl.cc @@ -159,11 +159,14 @@ void FastPairDiscoverableScannerImpl::OnModelIdRetrieved( void FastPairDiscoverableScannerImpl::OnDeviceMetadataRetrieved( const std::string address, const std::string model_id, - DeviceMetadata& device_metadata) { - DCHECK(&device_metadata); + std::optional device_metadata) { + if (!device_metadata.has_value()) { + NEARBY_LOGS(WARNING) << __func__ << ": Failed to get device metadata"; + return; + } // Ignore advertisements that aren't for Fast Pair but leverage the service // UUID. - if (!IsValidDeviceType(device_metadata.GetDetails())) { + if (!IsValidDeviceType(device_metadata->GetDetails())) { NEARBY_LOGS(WARNING) << __func__ << ": Invalid device type for Fast Pair. Ignoring this advertisement"; @@ -173,7 +176,7 @@ void FastPairDiscoverableScannerImpl::OnDeviceMetadataRetrieved( // Ignore advertisements for unsupported notification types, such as // APP_LAUNCH which should launch a companion app instead of beginning Fast // Pair. - if (!IsSupportedNotificationType(device_metadata.GetDetails())) { + if (!IsSupportedNotificationType(device_metadata->GetDetails())) { NEARBY_LOGS(WARNING) << __func__ << ": Unsupported notification type for Fast Pair. " "Ignoring this advertisement"; @@ -181,7 +184,7 @@ void FastPairDiscoverableScannerImpl::OnDeviceMetadataRetrieved( } auto fast_pair_device = std::make_unique( model_id, address, Protocol::kFastPairInitialPairing); - fast_pair_device->SetMetadata(device_metadata); + fast_pair_device->SetMetadata(device_metadata.value()); executor_->Execute( "add-device", diff --git a/fastpair/scanning/fastpair/fast_pair_discoverable_scanner_impl.h b/fastpair/scanning/fastpair/fast_pair_discoverable_scanner_impl.h index 4f4c81d7..732e6607 100644 --- a/fastpair/scanning/fastpair/fast_pair_discoverable_scanner_impl.h +++ b/fastpair/scanning/fastpair/fast_pair_discoverable_scanner_impl.h @@ -74,7 +74,7 @@ class FastPairDiscoverableScannerImpl : public FastPairDiscoverableScanner, void OnModelIdRetrieved(const std::string& address, std::optional model_id); void OnDeviceMetadataRetrieved(std::string address, std::string model_id, - DeviceMetadata& device_metadata); + std::optional device_metadata); void NotifyDeviceFound(FastPairDevice& device) ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_); diff --git a/fastpair/server_access/BUILD b/fastpair/server_access/BUILD index 07fdf6d7..320ab3f4 100644 --- a/fastpair/server_access/BUILD +++ b/fastpair/server_access/BUILD @@ -63,6 +63,7 @@ cc_library( name = "test_support", srcs = ["fake_fast_pair_repository.cc"], hdrs = [ + "fake_fast_pair_client.h", "fake_fast_pair_repository.h", ], visibility = [ @@ -95,10 +96,9 @@ cc_library( ) cc_test( - name = "server_access_test", + name = "fast_pair_metadata_downloader_impl_test", srcs = [ "fast_pair_metadata_downloader_impl_test.cc", - "fast_pair_repository_impl_test.cc", ], copts = [ "-Ithird_party", @@ -115,6 +115,25 @@ cc_test( ], ) +cc_test( + name = "fast_pair_repository_impl_test", + srcs = [ + "fast_pair_repository_impl_test.cc", + ], + copts = [ + "-Ithird_party", + ], + deps = [ + ":server_access", + ":test_support", + "//fastpair/common", + "//internal/platform:types", + "//internal/platform/implementation/g3", # build_cleaner: keep + "@com_github_protobuf_matchers//protobuf-matchers", + "@com_google_googletest//:gtest_main", + ], +) + cc_test( name = "fast_pair_http_notifier_test", srcs = [ diff --git a/fastpair/server_access/fake_fast_pair_client.h b/fastpair/server_access/fake_fast_pair_client.h new file mode 100644 index 00000000..3ec9f275 --- /dev/null +++ b/fastpair/server_access/fake_fast_pair_client.h @@ -0,0 +1,123 @@ +// 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_SERVER_ACCESS_FAKE_FAST_PAIR_CLIENT_H_ +#define THIRD_PARTY_NEARBY_FASTPAIR_SERVER_ACCESS_FAKE_FAST_PAIR_CLIENT_H_ + +#include + +#include "fastpair/proto/fastpair_rpcs.proto.h" +#include "fastpair/server_access/fast_pair_client.h" + +namespace nearby { +namespace fastpair { + +// A fake implementation of the FastPairClient that stores all request +// data. Only use in unit tests. +class FakeFastPairClient : public FastPairClient { + public: + FakeFastPairClient() = default; + ~FakeFastPairClient() override = default; + proto::GetObservedDeviceRequest& get_observer_device_request() { + return get_observer_device_request_.value(); + } + + proto::GetObservedDeviceResponse& get_observer_device_response() { + return get_observer_device_response_.value(); + } + + proto::UserReadDevicesRequest& read_devices_request() { + return read_devices_request_.value(); + } + + proto::UserReadDevicesResponse& read_devices_response() { + return read_devices_response_.value(); + } + + proto::UserWriteDeviceRequest& write_device_request() { + return write_device_request_.value(); + } + + proto::UserDeleteDeviceRequest& delete_device_request() { + return delete_device_request_.value(); + } + + void SetGetObservedDeviceResponse( + absl::StatusOr response) { + get_observer_device_response_ = response; + } + + void SetUserReadDevicesResponse( + absl::StatusOr responses) { + read_devices_response_ = responses; + } + + void SetUserWriteDeviceResponse( + absl::StatusOr response) { + write_device_response_ = response; + } + + void SetUserDeleteDeviceResponse( + absl::StatusOr response) { + delete_device_response_ = response; + } + + private: + // Gets an observed device. + // Blocking function + absl::StatusOr GetObservedDevice( + const proto::GetObservedDeviceRequest& request) override { + get_observer_device_request_ = request; + return get_observer_device_response_; + } + + // Reads the user's devices. + // Blocking function + absl::StatusOr UserReadDevices( + const proto::UserReadDevicesRequest& request) override { + read_devices_request_ = request; + return read_devices_response_; + } + + // Writes a new device to a user's account. + // Blocking function + absl::StatusOr UserWriteDevice( + const proto::UserWriteDeviceRequest& request) override { + write_device_request_ = request; + return write_device_response_; + } + + // Deletes an existing device from a user's account. + // Blocking function + absl::StatusOr UserDeleteDevice( + const proto::UserDeleteDeviceRequest& request) override { + delete_device_request_ = request; + return delete_device_response_; + } + + // Requests/Responses + std::optional get_observer_device_request_; + absl::StatusOr + get_observer_device_response_; + std::optional read_devices_request_; + absl::StatusOr read_devices_response_; + std::optional write_device_request_; + absl::StatusOr write_device_response_; + std::optional delete_device_request_; + absl::StatusOr delete_device_response_; +}; +} // namespace fastpair +} // namespace nearby + +#endif // THIRD_PARTY_NEARBY_FASTPAIR_SERVER_ACCESS_FAKE_FAST_PAIR_CLIENT_H_ diff --git a/fastpair/server_access/fast_pair_client_impl.cc b/fastpair/server_access/fast_pair_client_impl.cc index c3d4a628..8a5960e8 100644 --- a/fastpair/server_access/fast_pair_client_impl.cc +++ b/fastpair/server_access/fast_pair_client_impl.cc @@ -33,7 +33,6 @@ namespace nearby { namespace fastpair { namespace { -using ::nearby::network::HttpClient; using ::nearby::network::HttpRequest; using ::nearby::network::HttpRequestMethod; using ::nearby::network::HttpResponse; @@ -89,8 +88,7 @@ Url CreateV1RequestUrl(absl::string_view request_path) { FastPairClientImpl::FastPairClientImpl( auth::AuthenticationManager* authentication_manager, - AccountManager* account_manager, - std::unique_ptr http_client, + AccountManager* account_manager, network::HttpClient* http_client, FastPairHttpNotifier* notifier, DeviceInfo* device_info) : authentication_manager_(authentication_manager), account_manager_(account_manager), @@ -199,7 +197,6 @@ FastPairClientImpl::UserWriteDevice( /*Url=*/CreateV1RequestUrl(kUserDevicesPath), RequestType::kPost, /*query parameters=*/std::nullopt, /*body=*/request.SerializeAsString()); - absl::StatusOr http_response = http_client_->GetResponse(http_request); diff --git a/fastpair/server_access/fast_pair_client_impl.h b/fastpair/server_access/fast_pair_client_impl.h index f9aba500..d86e8276 100644 --- a/fastpair/server_access/fast_pair_client_impl.h +++ b/fastpair/server_access/fast_pair_client_impl.h @@ -41,7 +41,7 @@ class FastPairClientImpl : public FastPairClient { FastPairClientImpl(auth::AuthenticationManager* authentication_manager, AccountManager* account_manager, - std::unique_ptr http_client, + network::HttpClient* http_client, FastPairHttpNotifier* notifier, DeviceInfo* device_info); FastPairClientImpl(FastPairClientImpl&) = delete; FastPairClientImpl& operator=(FastPairClientImpl&) = delete; @@ -77,7 +77,7 @@ class FastPairClientImpl : public FastPairClient { auth::AuthenticationManager* authentication_manager_ = nullptr; AccountManager* account_manager_ = nullptr; - std::unique_ptr http_client_; + network::HttpClient* http_client_; FastPairHttpNotifier* notifier_ = nullptr; DeviceInfo* device_info_ = nullptr; }; diff --git a/fastpair/server_access/fast_pair_client_impl_test.cc b/fastpair/server_access/fast_pair_client_impl_test.cc index 8ca6b21c..f2c2c0b3 100644 --- a/fastpair/server_access/fast_pair_client_impl_test.cc +++ b/fastpair/server_access/fast_pair_client_impl_test.cc @@ -37,7 +37,6 @@ #include "internal/account/fake_account_manager.h" #include "internal/auth/auth_status_util.h" #include "internal/network/http_client.h" -#include "internal/network/http_client_factory.h" #include "internal/network/http_request.h" #include "internal/network/http_response.h" #include "internal/network/http_status_code.h" @@ -57,29 +56,33 @@ using ::nearby::network::HttpResponse; using ::nearby::network::HttpStatusCode; using ::nearby::network::Url; -constexpr char kHexModelId[] = "718C17"; -constexpr char kAccessToken[] = "access_token"; -constexpr char kTestAccountId[] = "test_account_id"; -constexpr char kFastPairPreferencesFilePath[] = "Google/Nearby/FastPair"; -constexpr char kDevicesPath[] = "device/"; -constexpr char kUserDevicesPath[] = "user/devices"; -constexpr char kUserDeleteDevicePath[] = "user/device"; -constexpr char kKey[] = "key"; -constexpr char kClientId[] = "AIzaSyBv7ZrOlX5oIJLVQrZh-WkZFKm5L6FlStQ"; -const char kQueryParameterAlternateOutputKey[] = "alt"; -const char kQueryParameterAlternateOutputProto[] = "proto"; -const char kPlatformTypeHeaderName[] = "X-FastPair-Platform-Type"; -constexpr char kWindowsPlatformType[] = "OSType.WINDOWS"; -constexpr char kMode[] = "mode"; -constexpr char kReleaseMode[] = "MODE_RELEASE"; -constexpr char kTestGoogleApisUrl[] = +constexpr absl::string_view kHexModelId = "718C17"; +constexpr absl::string_view kAccessToken = "access_token"; +constexpr absl::string_view kTestAccountId = "test_account_id"; +constexpr absl::string_view kFastPairPreferencesFilePath = + "Google/Nearby/FastPair"; +constexpr absl::string_view kDevicesPath = "device/"; +constexpr absl::string_view kUserDevicesPath = "user/devices"; +constexpr absl::string_view kUserDeleteDevicePath = "user/device"; +constexpr absl::string_view kKey = "key"; +constexpr absl::string_view kClientId = + "AIzaSyBv7ZrOlX5oIJLVQrZh-WkZFKm5L6FlStQ"; +constexpr absl::string_view kQueryParameterAlternateOutputKey = "alt"; +constexpr absl::string_view kQueryParameterAlternateOutputProto = "proto"; +constexpr absl::string_view kPlatformTypeHeaderName = + "X-FastPair-Platform-Type"; +constexpr absl::string_view kWindowsPlatformType = "OSType.WINDOWS"; +constexpr absl::string_view kMode = "mode"; +constexpr absl::string_view kReleaseMode = "MODE_RELEASE"; +constexpr absl::string_view kTestGoogleApisUrl = "https://nearbydevices-pa.testgoogleapis.com"; -constexpr char kBleAddress[] = "11::22::33::44::55::66"; -constexpr char kPublicAddress[] = "20:64:DE:40:F8:93"; -constexpr char kDisplayName[] = "Test Device"; -constexpr char kInitialPairingdescription[] = "InitialPairingdescription"; -constexpr char kAccountKey[] = "04b85786180add47fb81a04a8ce6b0de"; -constexpr char kExpectedSha256Hash[] = +constexpr absl::string_view kBleAddress = "11::22::33::44::55::66"; +constexpr absl::string_view kPublicAddress = "20:64:DE:40:F8:93"; +constexpr absl::string_view kDisplayName = "Test Device"; +constexpr absl::string_view kInitialPairingdescription = + "InitialPairingdescription"; +constexpr absl::string_view kAccountKey = "04b85786180add47fb81a04a8ce6b0de"; +constexpr absl::string_view kExpectedSha256Hash = "6353c0075a35b7d81bb30a6190ab246da4b8c55a6111d387400579133c090ed8"; class MockHttpClient : public HttpClient { @@ -142,13 +145,13 @@ class FastPairClientImplTest : public ::testing::Test, void SetUp() override { GetAuthManager()->EnableSyncMode(); - auto http_client = std::make_unique<::testing::NiceMock>(); - http_client_ = - dynamic_cast<::testing::NiceMock*>(http_client.get()); - switches::SetNearbyFastPairHttpHost(kTestGoogleApisUrl); + mock_http_client_ = std::make_unique<::testing::NiceMock>(); + http_client_ = dynamic_cast<::testing::NiceMock*>( + mock_http_client_.get()); + switches::SetNearbyFastPairHttpHost(std::string(kTestGoogleApisUrl)); fast_pair_client_ = std::make_unique( authentication_manager_.get(), account_manager_.get(), - std::move(http_client), ¬ifier_, device_info_.get()); + mock_http_client_.get(), ¬ifier_, device_info_.get()); notifier_.AddObserver(this); } @@ -219,10 +222,10 @@ class FastPairClientImplTest : public ::testing::Test, std::unique_ptr authentication_manager_; std::unique_ptr account_manager_; std::unique_ptr fast_pair_client_; - std::unique_ptr http_client_factory_; std::unique_ptr device_info_; std::unique_ptr task_runner_; ::testing::NiceMock* http_client_; + std::unique_ptr mock_http_client_; FastPairHttpNotifier notifier_; }; @@ -255,17 +258,17 @@ TEST_F(FastPairClientImplTest, GetObservedDeviceSuccess) { ::testing::HasSubstr(GetUrl(kDevicesPath).GetUrlPath())); EXPECT_EQ(request.GetAllHeaders().find(kPlatformTypeHeaderName)->second, - std::vector{kWindowsPlatformType}); + std::vector{std::string(kWindowsPlatformType)}); EXPECT_EQ( ExpectQueryStringValues(request.GetAllQueryParameters(), kKey), - std::vector{kClientId}); - EXPECT_EQ( - ExpectQueryStringValues(request.GetAllQueryParameters(), - kQueryParameterAlternateOutputKey), - std::vector{kQueryParameterAlternateOutputProto}); + std::vector{std::string(kClientId)}); + EXPECT_EQ(ExpectQueryStringValues(request.GetAllQueryParameters(), + kQueryParameterAlternateOutputKey), + std::vector{ + std::string(kQueryParameterAlternateOutputProto)}); EXPECT_EQ( ExpectQueryStringValues(request.GetAllQueryParameters(), kMode), - std::vector{kReleaseMode}); + std::vector{std::string(kReleaseMode)}); proto::GetObservedDeviceRequest expected_request; EXPECT_TRUE(expected_request.ParseFromString( request_proto.SerializeAsString())); @@ -344,7 +347,7 @@ TEST_F(FastPairClientImplTest, UserReadDevicesSuccess) { http_response.SetBody(response_proto.SerializeAsString()); GetAuthManager()->SetFetchAccessTokenResult(auth::AuthStatus::SUCCESS, - kAccessToken); + std::string(kAccessToken)); // Verifies HttpRequest is as expected EXPECT_CALL(*http_client_, GetResponse) @@ -376,7 +379,7 @@ TEST_F(FastPairClientImplTest, UserReadDevicesFailureWhenNoRespsone) { proto::UserReadDevicesRequest request_proto; GetAuthManager()->SetFetchAccessTokenResult(auth::AuthStatus::SUCCESS, - kAccessToken); + std::string(kAccessToken)); // Verifies HttpRequest is as expected EXPECT_CALL(*http_client_, GetResponse) @@ -415,7 +418,7 @@ TEST_F(FastPairClientImplTest, UserReadDevicesFailureWhenParseResponse) { }); GetAuthManager()->SetFetchAccessTokenResult(auth::AuthStatus::SUCCESS, - kAccessToken); + std::string(kAccessToken)); absl::StatusOr response = fast_pair_client_->UserReadDevices(proto::UserReadDevicesRequest()); EXPECT_TRUE(absl::IsInvalidArgument(response.status())); @@ -449,7 +452,7 @@ TEST_F(FastPairClientImplTest, UserWriteDeviceSuccess) { http_response.SetBody(response_proto.SerializeAsString()); GetAuthManager()->SetFetchAccessTokenResult(auth::AuthStatus::SUCCESS, - kAccessToken); + std::string(kAccessToken)); // Verifies HttpRequest is as expected EXPECT_CALL(*http_client_, GetResponse) @@ -497,7 +500,7 @@ TEST_F(FastPairClientImplTest, UserWriteDeviceFailureWhenNoRespsone) { proto::UserWriteDeviceRequest request_proto; GetAuthManager()->SetFetchAccessTokenResult(auth::AuthStatus::SUCCESS, - kAccessToken); + std::string(kAccessToken)); // Verifies HttpRequest is as expected EXPECT_CALL(*http_client_, GetResponse) @@ -536,7 +539,7 @@ TEST_F(FastPairClientImplTest, UserWriteDeviceFailureWhenParseResponse) { }); GetAuthManager()->SetFetchAccessTokenResult(auth::AuthStatus::SUCCESS, - kAccessToken); + std::string(kAccessToken)); absl::StatusOr response = fast_pair_client_->UserWriteDevice(proto::UserWriteDeviceRequest()); EXPECT_TRUE(absl::IsInvalidArgument(response.status())); @@ -544,7 +547,7 @@ TEST_F(FastPairClientImplTest, UserWriteDeviceFailureWhenParseResponse) { TEST_F(FastPairClientImplTest, UserDeleteDeviceSuccess) { // Sets up proto::UserDeleteDeviceRequest - std::string hex_account_key = kAccountKey; + std::string hex_account_key = std::string(kAccountKey); absl::AsciiStrToUpper(&hex_account_key); proto::UserDeleteDeviceRequest request_proto; request_proto.set_hex_account_key(hex_account_key); @@ -558,7 +561,7 @@ TEST_F(FastPairClientImplTest, UserDeleteDeviceSuccess) { http_response.SetBody(response_proto.SerializeAsString()); GetAuthManager()->SetFetchAccessTokenResult(auth::AuthStatus::SUCCESS, - kAccessToken); + std::string(kAccessToken)); // Verifies HttpRequest is as expected EXPECT_CALL(*http_client_, GetResponse) @@ -591,7 +594,7 @@ TEST_F(FastPairClientImplTest, UserDeleteDeviceFailureWhenNoRespsone) { proto::UserDeleteDeviceRequest request_proto; GetAuthManager()->SetFetchAccessTokenResult(auth::AuthStatus::SUCCESS, - kAccessToken); + std::string(kAccessToken)); // Verifies HttpRequest is as expected EXPECT_CALL(*http_client_, GetResponse) @@ -630,7 +633,7 @@ TEST_F(FastPairClientImplTest, UserDeleteDeviceFailureWhenParseResponse) { }); GetAuthManager()->SetFetchAccessTokenResult(auth::AuthStatus::SUCCESS, - kAccessToken); + std::string(kAccessToken)); absl::StatusOr response = fast_pair_client_->UserDeleteDevice(proto::UserDeleteDeviceRequest()); EXPECT_TRUE(absl::IsInvalidArgument(response.status())); @@ -658,7 +661,7 @@ TEST_F(FastPairClientImplTest, ParseResponseProtoFailure) { }); GetAuthManager()->SetFetchAccessTokenResult(auth::AuthStatus::SUCCESS, - kAccessToken); + std::string(kAccessToken)); absl::StatusOr response = fast_pair_client_->UserReadDevices(proto::UserReadDevicesRequest()); EXPECT_TRUE(absl::IsInvalidArgument(response.status())); diff --git a/fastpair/server_access/fast_pair_repository.h b/fastpair/server_access/fast_pair_repository.h index 8b761fc2..46d76a86 100644 --- a/fastpair/server_access/fast_pair_repository.h +++ b/fastpair/server_access/fast_pair_repository.h @@ -26,7 +26,9 @@ namespace nearby { namespace fastpair { -using DeviceMetadataCallback = absl::AnyInvocable; +using DeviceMetadataCallback = + absl::AnyInvocable device_metadata)>; + class FastPairRepository { public: static FastPairRepository* Get(); diff --git a/fastpair/server_access/fast_pair_repository_impl.cc b/fastpair/server_access/fast_pair_repository_impl.cc index a24c985e..65ee5ca1 100644 --- a/fastpair/server_access/fast_pair_repository_impl.cc +++ b/fastpair/server_access/fast_pair_repository_impl.cc @@ -14,42 +14,49 @@ #include "fastpair/server_access/fast_pair_repository_impl.h" -#include #include #include #include #include -#include "fastpair/repository/fast_pair_metadata_repository.h" -#include "fastpair/repository/fast_pair_metadata_repository_impl.h" -#include "fastpair/server_access/fast_pair_metadata_downloader_impl.h" -#include "internal/network/http_client_factory.h" -#include "internal/network/http_client_factory_impl.h" -#include "internal/platform/logging.h" #include "absl/strings/string_view.h" +#include "fastpair/common/device_metadata.h" +#include "internal/platform/logging.h" +#include "internal/platform/single_thread_executor.h" namespace nearby { namespace fastpair { -FastPairRepositoryImpl::FastPairRepositoryImpl() - : http_factory_(std::make_unique()), - repository_factory_( - std::make_unique( - http_factory_.get())) {} - -FastPairRepositoryImpl::FastPairRepositoryImpl( - std::unique_ptr repository) - : repository_factory_(std::move(repository)) {} +FastPairRepositoryImpl::FastPairRepositoryImpl(FastPairClient* fast_pair_client) + : fast_pair_client_(fast_pair_client) {} void FastPairRepositoryImpl::GetDeviceMetadata( - absl::string_view hex_model_id, - DeviceMetadataCallback callback) { - downloader_ = FastPairMetadataDownloaderImpl::Factory::Create( - hex_model_id, repository_factory_.get(), std::move(callback), []() { - NEARBY_LOGS(INFO) << __func__ - << ": Fast Pair Metadata download failed."; + absl::string_view hex_model_id, DeviceMetadataCallback callback) { + NEARBY_LOGS(INFO) << __func__ << " with model id= " << hex_model_id; + executor_.Execute( + "Get Device Metadata", [this, hex_model_id = std::string(hex_model_id), + callback = std::move(callback)]() mutable { + NEARBY_LOGS(INFO) << __func__ << ": Start to get devic metadata."; + proto::GetObservedDeviceRequest request; + int64_t device_id; + CHECK(absl::SimpleHexAtoi(hex_model_id, &device_id)); + request.set_device_id(device_id); + request.set_mode(proto::GetObservedDeviceRequest::MODE_RELEASE); + absl::StatusOr response = + fast_pair_client_->GetObservedDevice(request); + if (response.ok()) { + NEARBY_LOGS(WARNING) << "Got GetObservedDeviceResponse from backend."; + metadata_cache_[hex_model_id] = + std::make_unique(response.value()); + // TODO(b/289139378) : save device's metadata in local cache. + callback(*metadata_cache_[hex_model_id]); + } else { + NEARBY_LOGS(WARNING) + << "Failed to get GetObservedDeviceResponse from backend."; + callback(std::nullopt); + } }); - downloader_->Run(); } + } // namespace fastpair } // namespace nearby diff --git a/fastpair/server_access/fast_pair_repository_impl.h b/fastpair/server_access/fast_pair_repository_impl.h index 06c05a35..9a12c222 100644 --- a/fastpair/server_access/fast_pair_repository_impl.h +++ b/fastpair/server_access/fast_pair_repository_impl.h @@ -16,23 +16,21 @@ #define THIRD_PARTY_NEARBY_FASTPAIR_SERVER_ACCESS_FAST_PAIR_REPOSITORY_IMPL_H_ #include -#include #include -#include -#include "fastpair/repository/fast_pair_metadata_repository.h" -#include "fastpair/server_access/fast_pair_metadata_downloader.h" -#include "fastpair/server_access/fast_pair_repository.h" -#include "internal/network/http_client_factory.h" #include "absl/strings/string_view.h" +#include "fastpair/common/device_metadata.h" +#include "fastpair/server_access/fast_pair_client.h" +#include "fastpair/server_access/fast_pair_repository.h" +#include "internal/platform/single_thread_executor.h" namespace nearby { namespace fastpair { + class FastPairRepositoryImpl : public FastPairRepository { public: - FastPairRepositoryImpl(); - explicit FastPairRepositoryImpl( - std::unique_ptr repository); + explicit FastPairRepositoryImpl(FastPairClient* fast_pair_client); + FastPairRepositoryImpl(const FastPairRepositoryImpl&) = delete; FastPairRepositoryImpl& operator=(const FastPairRepositoryImpl&) = delete; ~FastPairRepositoryImpl() override = default; @@ -41,9 +39,11 @@ class FastPairRepositoryImpl : public FastPairRepository { DeviceMetadataCallback callback) override; private: - std::unique_ptr downloader_; - std::unique_ptr http_factory_; - std::unique_ptr repository_factory_; + // A thread for running blocking tasks. + SingleThreadExecutor executor_; + FastPairClient* fast_pair_client_; + absl::flat_hash_map> + metadata_cache_; }; } // namespace fastpair } // namespace nearby diff --git a/fastpair/server_access/fast_pair_repository_impl_test.cc b/fastpair/server_access/fast_pair_repository_impl_test.cc index b8c97f1e..c6c658a6 100644 --- a/fastpair/server_access/fast_pair_repository_impl_test.cc +++ b/fastpair/server_access/fast_pair_repository_impl_test.cc @@ -14,92 +14,63 @@ #include "fastpair/server_access/fast_pair_repository_impl.h" -#include #include #include -#include -#include #include "gmock/gmock.h" #include "protobuf-matchers/protocol-buffer-matchers.h" #include "gtest/gtest.h" #include "fastpair/common/device_metadata.h" -#include "fastpair/proto/fastpair_rpcs.proto.h" -#include "fastpair/repository/fake_fast_pair_metadata_repository.h" -#include "fastpair/server_access/fast_pair_metadata_downloader.h" -#include "fastpair/server_access/fast_pair_metadata_downloader_impl.h" +#include "fastpair/server_access/fake_fast_pair_client.h" +#include "internal/platform/count_down_latch.h" namespace nearby { namespace fastpair { - -constexpr absl::Duration kWaitTimeout = absl::Milliseconds(500); -const int64_t kDeviceId = 10148625; -const char kModelId[] = "9adb11"; -const char kDeviceName[] = "Pixel Buds Pro"; - -class FakeFastPairMetadataRepositoryFactory; - namespace { -class FastPairRepositoryImplTest : public ::testing::Test { - protected: - struct Result { - bool success; - std::optional device; - }; +constexpr absl::string_view kHexModelId = "718C17"; +constexpr absl::string_view kInitialPairingdescription = + "InitialPairingdescription"; - FastPairRepositoryImplTest() {} - ~FastPairRepositoryImplTest() override = default; +// A gMock matcher to match proto values. Use this matcher like: +// request/response proto, expected_proto; +// EXPECT_THAT(proto, MatchesProto(expected_proto)); +MATCHER_P( + MatchesProto, expected_proto, + absl::StrCat(negation ? "does not match" : "matches", + testing::PrintToString(expected_proto.SerializeAsString()))) { + return arg.SerializeAsString() == expected_proto.SerializeAsString(); +} - void GetObservedDataRequestSuccess( - const proto::GetObservedDeviceResponse& response) { - FakeFastPairMetadataRepository* repository = - fake_repository_factory_->fake_repository(); - std::move(repository->get_observed_device_request()->callback)(response); - } +TEST(FastPairRepositoryImplTest, MetadataDownloadSuccess) { + FakeFastPairClient fake_fast_pair_client; + auto fast_pair_repository = + std::make_unique(&fake_fast_pair_client); - void OnSuccess(DeviceMetadata& device_metadata) { - result_ = Result(); - result_->success = true; - result_->device = device_metadata.GetDetails(); - } + // Sets up proto::GetObservedDeviceResponse + proto::GetObservedDeviceResponse response_proto; + auto* device = response_proto.mutable_device(); + int64_t device_id; + CHECK(absl::SimpleHexAtoi(kHexModelId, &device_id)); + device->set_id(device_id); + auto* observed_device_strings = response_proto.mutable_strings(); + observed_device_strings->set_initial_pairing_description( + kInitialPairingdescription); + fake_fast_pair_client.SetGetObservedDeviceResponse(response_proto); - std::optional result_; - FakeFastPairMetadataRepositoryFactory* fake_repository_factory_; - std::unique_ptr repository_; -}; - -TEST_F(FastPairRepositoryImplTest, MetadataDownloadSuccess) { - absl::Notification notification; - - auto fake_repository_factory = - std::make_unique(); - fake_repository_factory_ = fake_repository_factory.get(); - - repository_ = std::make_unique( - std::move(fake_repository_factory)); - - repository_->Get()->GetDeviceMetadata(kModelId, - [&](DeviceMetadata& device_metadata) { - OnSuccess(device_metadata); - notification.Notify(); - }); - ASSERT_TRUE(fake_repository_factory_->fake_repository() != nullptr); - FakeFastPairMetadataRepository* repository = - fake_repository_factory_->fake_repository(); - const proto::GetObservedDeviceRequest& request = - repository->get_observed_device_request()->request; - EXPECT_EQ(request.device_id(), kDeviceId); - - proto::GetObservedDeviceResponse response; - response.mutable_device()->set_id(kDeviceId); - response.mutable_device()->set_name(kDeviceName); - GetObservedDataRequestSuccess(response); - ASSERT_TRUE(result_); - EXPECT_TRUE(result_->success); - ASSERT_TRUE(result_->device); - EXPECT_EQ(result_->device->name(), kDeviceName); - EXPECT_EQ(result_->device->id(), kDeviceId); - EXPECT_TRUE(notification.WaitForNotificationWithTimeout(kWaitTimeout)); + CountDownLatch latch(1); + fast_pair_repository->GetDeviceMetadata( + kHexModelId, [&](std::optional device_metadata) { + EXPECT_TRUE(device_metadata.has_value()); + // Verifies proto::GetObservedDeviceResponse is as expected + proto::GetObservedDeviceResponse response = + device_metadata->GetResponse(); + EXPECT_THAT(response, MatchesProto(response_proto)); + EXPECT_EQ(response.device().id(), device_id); + EXPECT_EQ(response.strings().initial_pairing_description(), + kInitialPairingdescription); + latch.CountDown(); + }); + latch.Await(); } } // namespace diff --git a/fastpair/ui/BUILD b/fastpair/ui/BUILD index 5cdf2bfc..763ee129 100644 --- a/fastpair/ui/BUILD +++ b/fastpair/ui/BUILD @@ -105,7 +105,6 @@ cc_test( ":fast_pair_ui", "//fastpair/common", "//fastpair/proto:fastpair_cc_proto", - "//fastpair/server_access:test_support", "//internal/platform:types", "//internal/platform/implementation/g3", # build_cleaner: keep "@com_github_protobuf_matchers//protobuf-matchers", diff --git a/fastpair/ui/fast_pair/fast_pair_presenter_impl.cc b/fastpair/ui/fast_pair/fast_pair_presenter_impl.cc index b43f8558..b6cc5250 100644 --- a/fastpair/ui/fast_pair/fast_pair_presenter_impl.cc +++ b/fastpair/ui/fast_pair/fast_pair_presenter_impl.cc @@ -51,22 +51,8 @@ void FastPairPresenterImpl::ShowDiscovery( FastPairDevice& device, FastPairNotificationController& notification_controller, DiscoveryCallback callback) { - callback_ = std::move(callback); - FastPairRepository::Get()->GetDeviceMetadata( - device.GetModelId(), [&](const DeviceMetadata& device_metadata) { - NEARBY_LOGS(INFO) << __func__ - << "Retrieved metadata to notification controller."; - OnDiscoveryMetadataRetrieved(device, device_metadata, - notification_controller); - }); -} - -void FastPairPresenterImpl::OnDiscoveryMetadataRetrieved( - FastPairDevice& device, const DeviceMetadata& device_metadata, - FastPairNotificationController& notification_controller) { - device.SetMetadata(device_metadata); notification_controller.ShowGuestDiscoveryNotification(*device.GetMetadata(), - std::move(callback_)); + std::move(callback)); } } // namespace fastpair } // namespace nearby diff --git a/fastpair/ui/fast_pair/fast_pair_presenter_impl.h b/fastpair/ui/fast_pair/fast_pair_presenter_impl.h index f3bd50ac..cc6595d2 100644 --- a/fastpair/ui/fast_pair/fast_pair_presenter_impl.h +++ b/fastpair/ui/fast_pair/fast_pair_presenter_impl.h @@ -48,13 +48,6 @@ class FastPairPresenterImpl : public FastPairPresenter { void ShowDiscovery(FastPairDevice& device, FastPairNotificationController& notification_controller, DiscoveryCallback callback) override; - - private: - // observer_list of notification_controller is updated - void OnDiscoveryMetadataRetrieved( - FastPairDevice& device, const DeviceMetadata& device_metadata, - FastPairNotificationController& notification_controller); - DiscoveryCallback callback_; }; } // namespace fastpair } // namespace nearby diff --git a/fastpair/ui/fast_pair/fast_pair_presenter_impl_test.cc b/fastpair/ui/fast_pair/fast_pair_presenter_impl_test.cc index e110f772..cb699f4f 100644 --- a/fastpair/ui/fast_pair/fast_pair_presenter_impl_test.cc +++ b/fastpair/ui/fast_pair/fast_pair_presenter_impl_test.cc @@ -19,7 +19,6 @@ #include "gtest/gtest.h" #include "fastpair/common/fast_pair_device.h" #include "fastpair/proto/fastpair_rpcs.proto.h" -#include "fastpair/server_access/fake_fast_pair_repository.h" #include "fastpair/ui/actions.h" #include "fastpair/ui/fast_pair/fake_fast_pair_notification_controller_observer.h" #include "fastpair/ui/fast_pair/fast_pair_notification_controller.h" @@ -34,10 +33,10 @@ constexpr absl::string_view kPublicKey = "test public key"; namespace { TEST(FastPairPresenterImplTest, ShowDiscoveryForV1Version) { // Setup repository with v1 version device metadata - FakeFastPairRepository repository; - proto::Device v1_version_device; - repository.SetFakeMetadata(kModelId, v1_version_device); FastPairDevice device(kModelId, kAddress, Protocol::kFastPairInitialPairing); + proto::GetObservedDeviceResponse response; + DeviceMetadata device_metadata(response); + device.SetMetadata(device_metadata); // Register FastPairNotificationControllerObserver auto latch_1 = std::make_optional(1); @@ -66,12 +65,13 @@ TEST(FastPairPresenterImplTest, ShowDiscoveryForV1Version) { TEST(FastPairPresenterImplTest, ShowDiscoveryForHigherThanV1Version) { // Setup repository with HigherThanV1Version device metadata - FakeFastPairRepository repository; - proto::Device higher_than_v1_version_device; - higher_than_v1_version_device.mutable_anti_spoofing_key_pair() - ->set_public_key(kPublicKey); - repository.SetFakeMetadata(kModelId, higher_than_v1_version_device); FastPairDevice device(kModelId, kAddress, Protocol::kFastPairInitialPairing); + proto::GetObservedDeviceResponse response; + auto* higher_than_v1_version_device = response.mutable_device(); + higher_than_v1_version_device->mutable_anti_spoofing_key_pair() + ->set_public_key(kPublicKey); + DeviceMetadata device_metadata(response); + device.SetMetadata(device_metadata); // Register FastPairNotificationControllerObserver auto latch_1 = std::make_optional(1);