diff --git a/connections/implementation/client_proxy.cc b/connections/implementation/client_proxy.cc index ee83d3ec4d..e275b7a445 100644 --- a/connections/implementation/client_proxy.cc +++ b/connections/implementation/client_proxy.cc @@ -318,8 +318,11 @@ void ClientProxy::OnEndpointFound( MutexLock lock(&mutex_); NEARBY_LOGS(INFO) << "ClientProxy [Endpoint Found]: [enter] id=" - << endpoint_id << "; service=" << service_id << "; info=" - << absl::BytesToHexString(endpoint_info.data()); + << endpoint_id << "; service=" << service_id + << "; info=" << absl::BytesToHexString(endpoint_info.data()) + << "; medium=" + << location::nearby::proto::connections::Medium_Name( + medium); if (!IsDiscoveringServiceId(service_id)) { NEARBY_LOGS(INFO) << "ClientProxy [Endpoint Found]: Ignoring event for id=" << endpoint_id diff --git a/connections/status.cc b/connections/status.cc index 976f455ea3..46216ab320 100644 --- a/connections/status.cc +++ b/connections/status.cc @@ -53,6 +53,12 @@ std::string Status::ToString() const { return "kWifiLanError"; case Status::kPayloadUnknown: return "kPayloadUnknown"; + case Status::kReset: + return "kReset"; + case Status::kTimeout: + return "kTimeout"; + case Status::kUnknown: + // fall through default: return "Unknown"; } diff --git a/connections/status.h b/connections/status.h index cc40005c24..0c2c1fa0c7 100644 --- a/connections/status.h +++ b/connections/status.h @@ -22,7 +22,7 @@ namespace connections { // Protocol operation result: kSuccess, if operation was successful; // descriptive error code otherwise. -// LINT.IfChange +// LINT.IfChange(status_enum) struct Status { // Status is a struct, so it is possible to pass some context about failure, // by adding extra fields to it when necessary, and not change any of the @@ -44,6 +44,9 @@ struct Status { kBleError, kWifiLanError, kPayloadUnknown, + kReset, + kTimeout, + kUnknown, kNextValue, }; Value value{kError}; @@ -53,9 +56,9 @@ struct Status { std::string ToString() const; }; // LINT.ThenChange( -// //depot/google3/location/nearby/cpp/sharing/implementation/nearby_connections_manager.cc:24 -// //depot/google3/location/nearby/cpp/sharing/implementation/nearby_connections_types.h:46 -// //depot/google3/location/nearby/cpp/sharing/implementation/nearby_connections_types_test.cc +// ../sharing/nearby_connections_manager.cc:status_enum, +// ../sharing/nearby_connections_types.h:status_enum, +// ../sharing/nearby_connections_types_test.cc:status_enum // ) inline bool operator==(const Status& a, const Status& b) { diff --git a/connections/swift/NearbyCoreAdapter/Sources/GNCCoreAdapter.mm b/connections/swift/NearbyCoreAdapter/Sources/GNCCoreAdapter.mm index e439575891..ef72ededcc 100644 --- a/connections/swift/NearbyCoreAdapter/Sources/GNCCoreAdapter.mm +++ b/connections/swift/NearbyCoreAdapter/Sources/GNCCoreAdapter.mm @@ -87,6 +87,12 @@ GNCStatus GNCStatusFromCppStatus(Status status) { return GNCStatusWifiLanError; case Status::kPayloadUnknown: return GNCStatusPayloadUnknown; + case Status::kReset: + return GNCStatusReset; + case Status::kTimeout: + return GNCStatusTimeout; + case Status::kUnknown: + return GNCStatusUnknown; case Status::kNextValue: return GNCStatusUnknown; } diff --git a/connections/swift/NearbyCoreAdapter/Sources/GNCError.mm b/connections/swift/NearbyCoreAdapter/Sources/GNCError.mm index 36c6d43e57..db10fee70a 100644 --- a/connections/swift/NearbyCoreAdapter/Sources/GNCError.mm +++ b/connections/swift/NearbyCoreAdapter/Sources/GNCError.mm @@ -65,6 +65,12 @@ return [NSError errorWithDomain:GNCErrorDomain code:GNCErrorWifiLanError userInfo:nil]; case Status::kPayloadUnknown: return [NSError errorWithDomain:GNCErrorDomain code:GNCErrorPayloadUnknown userInfo:nil]; + case Status::kReset: + return [NSError errorWithDomain:GNCErrorDomain code:GNCErrorReset userInfo:nil]; + case Status::kTimeout: + return [NSError errorWithDomain:GNCErrorDomain code:GNCErrorTimeout userInfo:nil]; + case Status::kUnknown: + return [NSError errorWithDomain:GNCErrorDomain code:GNCErrorUnknown userInfo:nil]; case Status::kNextValue: return [NSError errorWithDomain:GNCErrorDomain code:GNCErrorUnknown userInfo:nil]; } diff --git a/connections/swift/NearbyCoreAdapter/Sources/Public/NearbyCoreAdapter/GNCConnectionDelegate.h b/connections/swift/NearbyCoreAdapter/Sources/Public/NearbyCoreAdapter/GNCConnectionDelegate.h index 85c6aed692..84d22a2721 100644 --- a/connections/swift/NearbyCoreAdapter/Sources/Public/NearbyCoreAdapter/GNCConnectionDelegate.h +++ b/connections/swift/NearbyCoreAdapter/Sources/Public/NearbyCoreAdapter/GNCConnectionDelegate.h @@ -35,6 +35,8 @@ typedef NS_CLOSED_ENUM(NSInteger, GNCStatus) { GNCStatusWifiLanError, GNCStatusPayloadUnknown, GNCStatusUnknown, + GNCStatusReset, + GNCStatusTimeout, }; /** diff --git a/connections/swift/NearbyCoreAdapter/Sources/Public/NearbyCoreAdapter/GNCError.h b/connections/swift/NearbyCoreAdapter/Sources/Public/NearbyCoreAdapter/GNCError.h index 4242b676c6..769523245b 100644 --- a/connections/swift/NearbyCoreAdapter/Sources/Public/NearbyCoreAdapter/GNCError.h +++ b/connections/swift/NearbyCoreAdapter/Sources/Public/NearbyCoreAdapter/GNCError.h @@ -38,4 +38,6 @@ typedef NS_ERROR_ENUM(GNCErrorDomain, GNCErrorCode){ GNCErrorBleError, GNCErrorWifiLanError, GNCErrorPayloadUnknown, + GNCErrorReset, + GNCErrorTimeout, } NS_SWIFT_NAME(NearbyError); diff --git a/fastpair/internal/BUILD b/fastpair/internal/BUILD index cbec33b4df..3742f983ac 100644 --- a/fastpair/internal/BUILD +++ b/fastpair/internal/BUILD @@ -14,6 +14,7 @@ cc_library( "//fastpair:fast_pair_controller", "//fastpair:fast_pair_events", "//fastpair:fast_pair_seeker", + "//fastpair/common", "//fastpair/internal/mediums", "//fastpair/pairing", "//fastpair/repository", @@ -39,6 +40,9 @@ cc_test( "//fastpair/common", "//fastpair/message_stream:fake_gatt_callbacks", "//fastpair/message_stream:fake_provider", + "//fastpair/proto:fastpair_cc_proto", + "//fastpair/repository", + "//fastpair/repository:device_repository", "//fastpair/repository:test_support", "//internal/account:test_support", "//internal/platform:test_util", @@ -46,7 +50,8 @@ cc_test( "//internal/platform/implementation/g3", # build_cleaner: keep "//internal/test/google3_only:test", "@com_github_protobuf_matchers//protobuf-matchers", - "@com_google_absl//absl/time", + "@com_google_absl//absl/status", + "@com_google_absl//absl/strings", "@com_google_googletest//:gtest_main", ], ) diff --git a/fastpair/internal/fast_pair_seeker_impl.cc b/fastpair/internal/fast_pair_seeker_impl.cc index 10f7bafe90..30b27f9526 100644 --- a/fastpair/internal/fast_pair_seeker_impl.cc +++ b/fastpair/internal/fast_pair_seeker_impl.cc @@ -21,11 +21,13 @@ #include "absl/status/status.h" #include "absl/strings/str_format.h" +#include "fastpair/common/account_key.h" #include "fastpair/fast_pair_controller.h" #include "fastpair/fast_pair_events.h" #include "fastpair/pairing/pairer_broker_impl.h" #include "fastpair/scanning/scanner_broker_impl.h" #include "internal/platform/count_down_latch.h" +#include "internal/platform/logging.h" #include "internal/platform/pending_job_registry.h" #include "internal/platform/single_thread_executor.h" @@ -303,5 +305,23 @@ void FastPairSeekerImpl::OnRetroactivePairFound(FastPairDevice& device) { callbacks_.on_pair_event(device, PairEvent{.is_paired = true}); } +void FastPairSeekerImpl::ForgetDeviceByAccountKey( + const AccountKey& account_key) { + NEARBY_LOGS(VERBOSE) << __func__; + auto opt_device = devices_->FindDevice(account_key); + if (!opt_device.has_value()) { + NEARBY_LOGS(INFO) << __func__ << "No FP device matching the account key."; + } else { + devices_->RemoveDevice(opt_device.value()); + } + + repository_->DeleteAssociatedDeviceByAccountKey( + account_key, [&](absl::Status success) { + if (!success.ok()) return; + NEARBY_LOGS(VERBOSE) << "Deleted associated devcie by account key"; + // Temporary solution to refresh the saved_devices_sheet. + repository_->GetUserSavedDevices(); + }); +} } // namespace fastpair } // namespace nearby diff --git a/fastpair/internal/fast_pair_seeker_impl.h b/fastpair/internal/fast_pair_seeker_impl.h index 8984b22e6a..bf096f2b6e 100644 --- a/fastpair/internal/fast_pair_seeker_impl.h +++ b/fastpair/internal/fast_pair_seeker_impl.h @@ -43,6 +43,7 @@ class FastPairSeekerExt : public FastPairSeeker { // Handle the state changes of screen lock. virtual void SetIsScreenLocked(bool is_locked) = 0; + virtual void ForgetDeviceByAccountKey(const AccountKey& account_key) = 0; }; class FastPairSeekerImpl : public FastPairSeekerExt, @@ -91,6 +92,7 @@ class FastPairSeekerImpl : public FastPairSeekerExt, absl::Status StartFastPairScan() override; absl::Status StopFastPairScan() override; void SetIsScreenLocked(bool is_locked) override; + void ForgetDeviceByAccountKey(const AccountKey& account_key) override; // From BluetoothClassicMedium::Observer. void DeviceAdded(BluetoothDevice& device) override; diff --git a/fastpair/internal/fast_pair_seeker_impl_test.cc b/fastpair/internal/fast_pair_seeker_impl_test.cc index 9957265c3d..09556b8e48 100644 --- a/fastpair/internal/fast_pair_seeker_impl_test.cc +++ b/fastpair/internal/fast_pair_seeker_impl_test.cc @@ -18,18 +18,27 @@ #include #include +#include #include "gmock/gmock.h" #include "protobuf-matchers/protocol-buffer-matchers.h" #include "gtest/gtest.h" +#include "absl/status/status.h" +#include "absl/strings/escaping.h" +#include "fastpair/common/fast_pair_device.h" #include "fastpair/common/fast_pair_prefs.h" #include "fastpair/fast_pair_events.h" #include "fastpair/fast_pair_seeker.h" #include "fastpair/message_stream/fake_gatt_callbacks.h" #include "fastpair/message_stream/fake_provider.h" +#include "fastpair/proto/data.proto.h" +#include "fastpair/proto/enum.proto.h" #include "fastpair/repository/fake_fast_pair_repository.h" +#include "fastpair/repository/fast_pair_device_repository.h" +#include "fastpair/repository/fast_pair_repository.h" #include "internal/account/fake_account_manager.h" #include "internal/platform/count_down_latch.h" +#include "internal/platform/logging.h" #include "internal/platform/medium_environment.h" #include "internal/platform/single_thread_executor.h" #include "internal/platform/task_runner_impl.h" @@ -61,6 +70,19 @@ class MediumEnvironmentStarter { ~MediumEnvironmentStarter() { MediumEnvironment::Instance().Stop(); } }; +class FastPairRepositoryObserver : public FastPairRepository::Observer { + public: + explicit FastPairRepositoryObserver(CountDownLatch* latch) { latch_ = latch; } + + void OnGetUserSavedDevices( + const proto::OptInStatus& opt_in_status, + const std::vector& devices) override { + latch_->CountDown(); + } + + CountDownLatch* latch_ = nullptr; +}; + class FastPairSeekerImplTest : public testing::Test { protected: FastPairSeekerImplTest() { @@ -222,6 +244,63 @@ TEST_F(FastPairSeekerImplTest, InitialPairing) { fast_pair_seeker_.reset(); } +TEST_F(FastPairSeekerImplTest, ForgetDeviceByAccountKey) { + NEARBY_LOG_SET_SEVERITY(VERBOSE); + FakeProvider provider; + CountDownLatch discover_latch(1); + CountDownLatch pair_latch(1); + fast_pair_seeker_ = std::make_unique( + FastPairSeekerImpl::ServiceCallbacks{ + .on_initial_discovery = + [&](const FastPairDevice& device, InitialDiscoveryEvent event) { + EXPECT_EQ(device.GetModelId(), kModelId); + EXPECT_OK(fast_pair_seeker_->StartInitialPairing( + device, {}, + {.on_pairing_result = [&](const FastPairDevice& device, + absl::Status status) { + EXPECT_EQ(device.GetBleAddress(), + provider.GetMacAddress()); + EXPECT_OK(status); + pair_latch.CountDown(); + }})); + discover_latch.CountDown(); + }}, + &executor_, account_manager_.get(), &devices_, repository_.get()); + + EXPECT_OK(fast_pair_seeker_->StartFastPairScan()); + provider.PrepareForInitialPairing( + { + .private_key = absl::HexStringToBytes(kBobPrivateKey), + .public_key = absl::HexStringToBytes(kBobPublicKey), + .model_id = std::string(kModelId), + .pass_key = std::string(kPasskey), + }, + &fake_gatt_callbacks_); + + discover_latch.Await(); + pair_latch.Await(); + auto fp_device = devices_.FindDevice(provider.GetMacAddress()); + ASSERT_TRUE(fp_device.has_value()); + EXPECT_EQ(provider.GetAccountKey(), fp_device.value()->GetAccountKey()); + + // Adds FastPairRepository observer. + CountDownLatch repository_latch(1); + FastPairRepositoryObserver observer(&repository_latch); + repository_->AddObserver(&observer); + // Adds FastPairDeviceRepository observer. + CountDownLatch devices_latch(1); + FastPairDeviceRepository::RemoveDeviceCallback callback = + [&](const FastPairDevice& device) { devices_latch.CountDown(); }; + devices_.AddObserver(&callback); + + fast_pair_seeker_->ForgetDeviceByAccountKey( + fp_device.value()->GetAccountKey()); + repository_latch.Await(); + devices_latch.Await(); + EXPECT_FALSE(devices_.FindDevice(provider.GetMacAddress()).has_value()); + fast_pair_seeker_.reset(); +} + TEST_F(FastPairSeekerImplTest, RetroactivePairingWithUserConsent) { NEARBY_LOG_SET_SEVERITY(VERBOSE); FakeProvider provider; diff --git a/fastpair/keyed_service/BUILD b/fastpair/keyed_service/BUILD deleted file mode 100644 index b5046e28f2..0000000000 --- a/fastpair/keyed_service/BUILD +++ /dev/null @@ -1,79 +0,0 @@ -# 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. - -licenses(["notice"]) - -cc_library( - name = "keyed_service", - srcs = [ - "fast_pair_mediator.cc", - "fast_pair_mediator_factory.cc", - ], - hdrs = [ - "fast_pair_mediator.h", - "fast_pair_mediator_factory.h", - ], - visibility = [ - "//fastpair:__subpackages__", - ], - deps = [ - "//fastpair/common", - "//fastpair/internal/mediums", - "//fastpair/pairing", - "//fastpair/repository", - "//fastpair/repository:device_repository", - "//fastpair/repository:repository_impl", - "//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", - ], -) - -cc_test( - name = "fast_pair_mediator_test", - size = "small", - srcs = [ - "fast_pair_mediator_factory_test.cc", - "fast_pair_mediator_test.cc", - ], - shard_count = 16, - deps = [ - ":keyed_service", - "//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 deleted file mode 100644 index 16850e2cd3..0000000000 --- a/fastpair/keyed_service/fast_pair_mediator.cc +++ /dev/null @@ -1,242 +0,0 @@ -// 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/keyed_service/fast_pair_mediator.h" - -#include -#include -#include -#include -#include - -#include "absl/status/status.h" -#include "fastpair/common/fast_pair_device.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/repository/fast_pair_repository_impl.h" -#include "fastpair/scanning/scanner_broker_impl.h" -#include "fastpair/server_access/fast_pair_client_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/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 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)), - 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, - true); - const_cast(FeatureFlags::GetInstance()) - .SetFlags(fast_pair_feature_flags); - - devices_ = std::make_unique(executor_.get()); - scanner_broker_ = std::make_unique( - *mediums_, executor_.get(), devices_.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()); - pairer_broker_ = std::make_unique( - *mediums_, executor_.get(), account_manager_.get()); - scanner_broker_->AddObserver(this); - ui_broker_->AddObserver(this); - pairer_broker_->AddObserver(this); -} - -void Mediator::OnDeviceFound(FastPairDevice& device) { - NEARBY_LOGS(INFO) << __func__ << ": " << device; - if (device.ShouldShowUiNotification().value_or(false)) { - NEARBY_LOGS(INFO) << __func__ << ": Ignoring because show UI flag is false"; - return; - } - if (foreground_currently_showing_notification_) { - NEARBY_LOGS(VERBOSE) - << __func__ - << ": Already showing a notification for a different device= "; - return; - } - // Show discovery notification - foreground_currently_showing_notification_ = true; - ui_broker_->ShowDiscovery(device, *notification_controller_); -} - -void Mediator::OnDeviceLost(FastPairDevice& device) { - NEARBY_LOGS(INFO) << __func__ << ": " << device; -} - -void Mediator::OnDiscoveryAction(FastPairDevice& device, - DiscoveryAction action) { - switch (action) { - case DiscoveryAction::kPairToDevice: - NEARBY_LOGS(INFO) << __func__ << ": Action = kPairToDevice"; - pairer_broker_->PairDevice(device); - break; - case DiscoveryAction::kDismissedByOs: - NEARBY_LOGS(INFO) << __func__ << ": Action = kDismissedByOs"; - break; - case DiscoveryAction::kDismissedByUser: - // When the user explicitly dismisses the discovery notification, update - // the device's block-list value accordingly. - NEARBY_LOGS(INFO) << __func__ << ": Action = kDismissedByUser"; - foreground_currently_showing_notification_ = false; - // TODO(b/285453663): update discovery block list - break; - case DiscoveryAction::kDismissedByTimeout: - NEARBY_LOGS(INFO) << __func__ << ": Action = kDismissedByTimeout"; - foreground_currently_showing_notification_ = false; - break; - case DiscoveryAction::kLearnMore: - NEARBY_LOGS(INFO) << __func__ << ": Action = kLearnMore"; - break; - case DiscoveryAction::kDone: - NEARBY_LOGS(INFO) << __func__ << ": Action = kDone"; - foreground_currently_showing_notification_ = false; - break; - default: - NEARBY_LOGS(INFO) << __func__ << ": Action = Unknown"; - break; - } -} - -void Mediator::OnDevicePaired(FastPairDevice& device) { - NEARBY_LOGS(INFO) << __func__ << ": " << device; - ui_broker_->ShowPairingResult(device, *notification_controller_, true); -} - -void Mediator::OnAccountKeyWrite(FastPairDevice& device, - std::optional error) { - if (error.has_value()) { - NEARBY_LOGS(INFO) << __func__ << ": Device=" << device - << ",Error=" << error.value(); - return; - } - - NEARBY_LOGS(INFO) << __func__ << ": Device=" << device; - if (device.GetProtocol() == Protocol::kFastPairRetroactivePairing) { - // TODO: UI ShowAssociateAccount - } -} - -void Mediator::OnPairingComplete(FastPairDevice& device) { - NEARBY_LOGS(INFO) << __func__ << ": " << device; -} - -void Mediator::OnPairFailure(FastPairDevice& device, PairFailure failure) { - NEARBY_LOGS(INFO) << __func__ << ": " << device - << " with PairFailure: " << failure; - ui_broker_->ShowPairingResult(device, *notification_controller_, false); -} - -void Mediator::StartScanning() { - NEARBY_LOGS(VERBOSE) << __func__; - if (IsFastPairEnabled()) { - if (scanning_session_ != nullptr) { - return; - } - scanner_broker_ = std::make_unique( - *mediums_, executor_.get(), devices_.get()); - scanner_broker_->AddObserver(this); - scanning_session_ = - scanner_broker_->StartScanning(Protocol::kFastPairInitialPairing); - return; - } - scanning_session_.reset(); -} - -void Mediator::StopScanning() { - NEARBY_LOGS(VERBOSE) << __func__; - if (scanning_session_ == nullptr) { - return; - } - scanning_session_.reset(); - scanner_broker_->RemoveObserver(this); - DestroyOnExecutor(std::move(scanner_broker_), executor_.get()); -} - -bool Mediator::IsFastPairEnabled() { - // TODO(b/275452353): Add feature_status_tracker IsFastPairEnabled() - // Currently default to true. - NEARBY_LOGS(VERBOSE) << __func__ << ": " << true; - return true; -} - -void Mediator::SetIsScreenLocked(bool locked) { - executor_->Execute( - "on_lock_state_changed", - [this, locked]() ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_) { - NEARBY_LOGS(INFO) << __func__ << ": Screen lock state changed. (" - << std::boolalpha << locked << ")"; - is_screen_locked_ = locked; - InvalidateScanningState(); - }); -} - -void Mediator::InvalidateScanningState() { - NEARBY_LOGS(INFO) << __func__; - // Stop scanning when screen is off. - if (is_screen_locked_) { - StopScanning(); - NEARBY_LOGS(VERBOSE) << __func__ - << ": Stopping scanning because the screen is locked."; - return; - } - - // TODO(b/275452353): Check if bluetooth and fast pair is enabled - - // Screen is on, Bluetooth is enabled, and Fast Pair is enabled, start - // scanning. - StartScanning(); -} - -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/keyed_service/fast_pair_mediator.h b/fastpair/keyed_service/fast_pair_mediator.h deleted file mode 100644 index 16c4f6a2ec..0000000000 --- a/fastpair/keyed_service/fast_pair_mediator.h +++ /dev/null @@ -1,129 +0,0 @@ -// 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_KEYED_SERVICE_FAST_PAIR_MEDIATOR_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_KEYED_SERVICE_FAST_PAIR_MEDIATOR_H_ - -#include -#include -#include - -#include "fastpair/common/fast_pair_device.h" -#include "fastpair/internal/mediums/mediums.h" -#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/repository/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 { - -// Implements the Mediator design pattern for the components in the Fast Pair -class Mediator final : public ScannerBroker::Observer, - public UIBroker::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 authentication_manager, - std::unique_ptr http_client, - std::unique_ptr device_info); - Mediator(const Mediator&) = delete; - Mediator& operator=(const Mediator&) = delete; - ~Mediator() override { - if (scanning_session_ == nullptr) { - NEARBY_LOGS(ERROR) << __func__ << "scanner is not running"; - } - scanning_session_.reset(); - scanner_broker_->RemoveObserver(this); - DestroyOnExecutor(std::move(scanner_broker_), executor_.get()); - scanner_broker_.reset(); - ui_broker_->RemoveObserver(this); - ui_broker_.reset(); - }; - - AccountManager* GetAccountManager() { return account_manager_.get(); } - - FastPairNotificationController* GetNotificationController() { - return notification_controller_.get(); - } - - FastPairRepository* GetFastPairRepository() { - return fast_pair_repository_.get(); - } - - void StartScanning(); - void StopScanning(); - - // ScannerBroker::Observer - void OnDeviceFound(FastPairDevice& device) override; - void OnDeviceLost(FastPairDevice& device) override; - - // UIBroker::Observer - void OnDiscoveryAction(FastPairDevice& device, - DiscoveryAction action) override; - - // PairBroker:Observer - void OnDevicePaired(FastPairDevice& device) override; - void OnAccountKeyWrite(FastPairDevice& device, - std::optional error) override; - void OnPairingComplete(FastPairDevice& device) override; - void OnPairFailure(FastPairDevice& device, PairFailure failure) override; - - // Handle the state changes of screen lock. - void SetIsScreenLocked(bool is_locked); - - private: - bool IsFastPairEnabled(); - void InvalidateScanningState() ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_); - bool IsDeviceCurrentlyShowingNotification(const FastPairDevice& device); - - bool foreground_currently_showing_notification_ = false; - FastPairHttpNotifier fast_pair_http_notifier_; - std::unique_ptr executor_; - std::unique_ptr mediums_; - std::unique_ptr scanner_broker_; - std::unique_ptr scanning_session_; - std::unique_ptr ui_broker_; - std::unique_ptr pairer_broker_; - std::unique_ptr notification_controller_; - std::unique_ptr fast_pair_repository_; - 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; -}; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_KEYED_SERVICE_FAST_PAIR_MEDIATOR_H_ diff --git a/fastpair/keyed_service/fast_pair_mediator_factory.cc b/fastpair/keyed_service/fast_pair_mediator_factory.cc deleted file mode 100644 index 5e87f8f182..0000000000 --- a/fastpair/keyed_service/fast_pair_mediator_factory.cc +++ /dev/null @@ -1,47 +0,0 @@ -// 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/keyed_service/fast_pair_mediator_factory.h" - -#include - -#include "fastpair/internal/mediums/mediums.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 { -namespace fastpair { - -MediatorFactory* MediatorFactory::GetInstance() { - static MediatorFactory* instance = new MediatorFactory(); - return instance; -} - -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()); - return mediator_.get(); -} - -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/keyed_service/fast_pair_mediator_factory.h b/fastpair/keyed_service/fast_pair_mediator_factory.h deleted file mode 100644 index f1117aed1d..0000000000 --- a/fastpair/keyed_service/fast_pair_mediator_factory.h +++ /dev/null @@ -1,39 +0,0 @@ -// 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_KEYED_SERVICE_FAST_PAIR_MEDIATOR_FACTORY_H_ -#define THIRD_PARTY_NEARBY_FASTPAIR_KEYED_SERVICE_FAST_PAIR_MEDIATOR_FACTORY_H_ - -#include - -#include "fastpair/keyed_service/fast_pair_mediator.h" - -namespace nearby { -namespace fastpair { - -class MediatorFactory { - public: - // Return a singleton instance of Mediator Factory - static MediatorFactory* GetInstance(); - - Mediator* CreateMediator(); - - private: - std::unique_ptr mediator_; -}; - -} // namespace fastpair -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_FASTPAIR_KEYED_SERVICE_FAST_PAIR_MEDIATOR_FACTORY_H_ diff --git a/fastpair/keyed_service/fast_pair_mediator_factory_test.cc b/fastpair/keyed_service/fast_pair_mediator_factory_test.cc deleted file mode 100644 index 234112a245..0000000000 --- a/fastpair/keyed_service/fast_pair_mediator_factory_test.cc +++ /dev/null @@ -1,37 +0,0 @@ -// 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/keyed_service/fast_pair_mediator_factory.h" - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "fastpair/keyed_service/fast_pair_mediator.h" - -namespace nearby { -namespace fastpair { -namespace { - -TEST(MediatorFactoryTest, checkMediatorCreateWithFactory) { - MediatorFactory *factory_ = nullptr; - Mediator *mediator_ = nullptr; - factory_ = MediatorFactory::GetInstance(); - EXPECT_THAT(factory_, testing::NotNull()); - mediator_ = factory_->CreateMediator(); - EXPECT_THAT(mediator_, testing::NotNull()); -} - -} // namespace -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/keyed_service/fast_pair_mediator_test.cc b/fastpair/keyed_service/fast_pair_mediator_test.cc deleted file mode 100644 index bd832bb763..0000000000 --- a/fastpair/keyed_service/fast_pair_mediator_test.cc +++ /dev/null @@ -1,290 +0,0 @@ -// 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/keyed_service/fast_pair_mediator.h" - -#include -#include -#include -#include - -#include "gmock/gmock.h" -#include "protobuf-matchers/protocol-buffer-matchers.h" -#include "gtest/gtest.h" -#include "absl/strings/escaping.h" -#include "absl/strings/string_view.h" -#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/mock_ui_broker.h" -#include "fastpair/ui/ui_broker.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 { -namespace { - -constexpr absl::string_view kModelId = "718c17"; -constexpr absl::string_view kServiceID = "Fast Pair"; -constexpr absl::string_view kFastPairServiceUuid = - "0000FE2C-0000-1000-8000-00805F9B34FB"; -constexpr int kNotDiscoverableAdvHeader = 0b00000110; -constexpr int kAccountKeyFilterHeader = 0b01100000; -constexpr int kSaltHeader = 0b00010001; -constexpr absl::string_view kAccountKeyFilter("112233445566"); -constexpr absl::string_view kSalt("01"); - -constexpr absl::string_view kModelId2 = "9adb11"; -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(); - ui_broker_ = std::make_unique(); - mock_ui_broker_ = static_cast(ui_broker_.get()); - - notification_controller_ = - std::make_unique(); - - executor_ = std::make_unique(); - } - - void TearDown() override { - executor_.reset(); - mediums_.reset(); - ui_broker_.reset(); - mock_ui_broker_ = nullptr; - notification_controller_.reset(); - mediator_.reset(); - 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_; - std::unique_ptr ui_broker_; - std::unique_ptr notification_controller_; - 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 Advertiser and startAdvertising - Mediums mediums_advertiser; - std::string service_id(kServiceID); - ByteArray advertisement_bytes{absl::HexStringToBytes(kModelId)}; - std::string fast_pair_service_uuid(kFastPairServiceUuid); - mediums_advertiser.GetBle().GetMedium().StartAdvertising( - service_id, advertisement_bytes, fast_pair_service_uuid); - - mediator_->StartScanning(); - done.WaitForNotification(); -} - -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 Advertiser and startAdvertising - Mediums mediums_advertiser; - std::string service_id(kServiceID); - ByteArray advertisement_bytes{absl::HexStringToBytes(kModelId)}; - std::string fast_pair_service_uuid(kFastPairServiceUuid); - mediums_advertiser.GetBle().GetMedium().StartAdvertising( - service_id, advertisement_bytes, fast_pair_service_uuid); - - // Create a different Advertiser and startAdvertising to cause confliction - Mediums mediums_advertiser2; - ByteArray advertisement_bytes2{absl::HexStringToBytes(kModelId2)}; - mediums_advertiser2.GetBle().GetMedium().StartAdvertising( - service_id, advertisement_bytes2, fast_pair_service_uuid); - - mediator_->StartScanning(); - done.WaitForNotification(); -} - -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 Advertiser and startAdvertising - Mediums mediums_advertiser; - std::string service_id(kServiceID); - ByteArray advertisement_bytes{absl::HexStringToBytes(kModelId)}; - std::string fast_pair_service_uuid(kFastPairServiceUuid); - mediums_advertiser.GetBle().GetMedium().StartAdvertising( - service_id, advertisement_bytes, fast_pair_service_uuid); - - // Create another same Advertiser and startAdvertising to cause confliction - Mediums mediums_advertiser2; - ByteArray advertisement_bytes2{absl::HexStringToBytes(kModelId)}; - mediums_advertiser2.GetBle().GetMedium().StartAdvertising( - service_id, advertisement_bytes2, fast_pair_service_uuid); - - mediator_->StartScanning(); - done.WaitForNotification(); -} - -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 Advertiser and advertising discoverable advertisement - Mediums mediums_advertiser; - std::string service_id(kServiceID); - ByteArray advertisement_bytes{absl::HexStringToBytes(kModelId)}; - std::string fast_pair_service_uuid(kFastPairServiceUuid); - mediums_advertiser.GetBle().GetMedium().StartAdvertising( - service_id, advertisement_bytes, fast_pair_service_uuid); - - // Create another same Advertiser and advertising non-discoverable - // advertisement to cause confliction - Mediums mediums_advertiser2; - std::vector bytes = FastPairServiceDataCreator::Builder() - .SetHeader(kNotDiscoverableAdvHeader) - .SetModelId(kModelId) - .AddExtraFieldHeader(kAccountKeyFilterHeader) - .AddExtraField(kAccountKeyFilter) - .AddExtraFieldHeader(kSaltHeader) - .AddExtraField(kSalt) - .Build() - ->CreateServiceData(); - ByteArray advertisement_bytes2{std::string(bytes.begin(), bytes.end())}; - mediums_advertiser2.GetBle().GetMedium().StartAdvertising( - service_id, advertisement_bytes2, fast_pair_service_uuid); - - mediator_->StartScanning(); - done.WaitForNotification(); -} - -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 Advertiser and startAdvertising - Mediums mediums_advertiser; - std::string service_id(kServiceID); - ByteArray advertisement_bytes{absl::HexStringToBytes(kModelId)}; - std::string fast_pair_service_uuid(kFastPairServiceUuid); - mediums_advertiser.GetBle().GetMedium().StartAdvertising( - service_id, advertisement_bytes, fast_pair_service_uuid); - - mediator_->StartScanning(); - done.WaitForNotification(); - - FastPairDevice device(kModelId, kAddress, Protocol::kFastPairInitialPairing); - mock_ui_broker_->NotifyDiscoveryAction(device, - DiscoveryAction::kDismissedByTimeout); - // Create another same Advertiser and startAdvertising to cause confliction - Mediums mediums_advertiser2; - ByteArray advertisement_bytes2{absl::HexStringToBytes(kModelId)}; - mediums_advertiser2.GetBle().GetMedium().StartAdvertising( - service_id, advertisement_bytes2, fast_pair_service_uuid); - - done.WaitForNotification(); -} - -} // namespace -} // namespace fastpair -} // namespace nearby diff --git a/fastpair/repository/BUILD b/fastpair/repository/BUILD index c6b3dff2a3..747a646217 100644 --- a/fastpair/repository/BUILD +++ b/fastpair/repository/BUILD @@ -81,6 +81,7 @@ cc_library( ":repository", "//fastpair/common", "//fastpair/proto:fastpair_cc_proto", + "//internal/base", "//internal/platform:types", "@com_google_absl//absl/container:flat_hash_map", "@com_google_absl//absl/status", @@ -115,6 +116,7 @@ cc_test( "//internal/platform:types", "//internal/platform/implementation/g3", # build_cleaner: keep "@com_github_protobuf_matchers//protobuf-matchers", + "@com_google_absl//absl/strings:string_view", "@com_google_googletest//:gtest_main", ], ) diff --git a/fastpair/repository/fake_fast_pair_repository.cc b/fastpair/repository/fake_fast_pair_repository.cc index 4c0491d7e6..713a615dc5 100644 --- a/fastpair/repository/fake_fast_pair_repository.cc +++ b/fastpair/repository/fake_fast_pair_repository.cc @@ -18,16 +18,31 @@ #include #include #include +#include +#include "absl/status/status.h" #include "absl/strings/escaping.h" #include "absl/strings/string_view.h" #include "fastpair/common/account_key.h" +#include "fastpair/common/account_key_filter.h" #include "fastpair/common/constant.h" +#include "fastpair/common/device_metadata.h" #include "fastpair/common/fast_pair_device.h" +#include "fastpair/proto/data.proto.h" +#include "fastpair/proto/enum.proto.h" #include "fastpair/proto/fastpair_rpcs.proto.h" +#include "fastpair/repository/fast_pair_repository.h" namespace nearby { namespace fastpair { +void FakeFastPairRepository::AddObserver(Observer* observer) { + observers_.AddObserver(observer); +} + +void FakeFastPairRepository::RemoveObserver(Observer* observer) { + observers_.RemoveObserver(observer); +} + void FakeFastPairRepository::SetFakeMetadata(absl::string_view hex_model_id, proto::Device metadata) { proto::GetObservedDeviceResponse response; @@ -73,6 +88,14 @@ void FakeFastPairRepository::GetDeviceMetadata( }); } +void FakeFastPairRepository::GetUserSavedDevices() { + proto::OptInStatus opt_in_status = proto::OptInStatus::OPT_IN_STATUS_UNKNOWN; + std::vector saved_devices; + for (auto& observer : observers_.GetObservers()) { + observer->OnGetUserSavedDevices(opt_in_status, saved_devices); + } +} + void FakeFastPairRepository::WriteAccountAssociationToFootprints( FastPairDevice& device, OperationCallback callback) { executor_.Execute([callback = std::move(callback), this]() mutable { diff --git a/fastpair/repository/fake_fast_pair_repository.h b/fastpair/repository/fake_fast_pair_repository.h index 5afb3d2400..ef1a7619a2 100644 --- a/fastpair/repository/fake_fast_pair_repository.h +++ b/fastpair/repository/fake_fast_pair_repository.h @@ -25,6 +25,7 @@ #include "fastpair/common/account_key.h" #include "fastpair/common/device_metadata.h" #include "fastpair/repository/fast_pair_repository.h" +#include "internal/base/observer_list.h" #include "internal/platform/single_thread_executor.h" namespace nearby { @@ -49,13 +50,13 @@ class FakeFastPairRepository : public FastPairRepository { void SetResultOfIsDeviceSavedToAccount(absl::Status status); // FastPairRepository:: - void AddObserver(Observer* observer) override{}; - void RemoveObserver(Observer* observer) override{}; + void AddObserver(Observer* observer) override; + void RemoveObserver(Observer* observer) override; void GetDeviceMetadata(absl::string_view hex_model_id, DeviceMetadataCallback callback) override; - void GetUserSavedDevices() override{}; + void GetUserSavedDevices() override; void WriteAccountAssociationToFootprints(FastPairDevice& device, OperationCallback callback) override; @@ -82,6 +83,7 @@ class FakeFastPairRepository : public FastPairRepository { absl::Status deleted_associated_device_; // Results of IsDeviceSavedToAccount absl::Status is_device_saved_to_account_; + ObserverList observers_; SingleThreadExecutor executor_; }; } // namespace fastpair diff --git a/fastpair/repository/fast_pair_device_repository.cc b/fastpair/repository/fast_pair_device_repository.cc index d210d94dc8..e219a484d5 100644 --- a/fastpair/repository/fast_pair_device_repository.cc +++ b/fastpair/repository/fast_pair_device_repository.cc @@ -19,6 +19,8 @@ #include #include +#include "fastpair/common/account_key.h" +#include "fastpair/common/fast_pair_device.h" #include "internal/platform/logging.h" #include "internal/platform/mutex_lock.h" @@ -51,7 +53,7 @@ void FastPairDeviceRepository::RemoveDevice(const FastPairDevice* device) { for (auto* callback : observers_.GetObservers()) { (*callback)(*fast_pair_device); } - NEARBY_LOGS(VERBOSE) << "Destroyed FP device: " << fast_pair_device; + NEARBY_LOGS(VERBOSE) << "Destroyed FP device: " << *fast_pair_device; }); } @@ -70,6 +72,20 @@ std::optional FastPairDeviceRepository::FindDevice( } } +std::optional FastPairDeviceRepository::FindDevice( + const AccountKey& account_key) { + MutexLock lock(&mutex_); + auto it = std::find_if(devices_.begin(), devices_.end(), + [&](const std::unique_ptr& device) { + return device->GetAccountKey() == account_key; + }); + if (it != devices_.end()) { + return it->get(); + } else { + return std::nullopt; + } +} + std::unique_ptr FastPairDeviceRepository::ExtractDevice( const FastPairDevice* device) { MutexLock lock(&mutex_); diff --git a/fastpair/repository/fast_pair_device_repository.h b/fastpair/repository/fast_pair_device_repository.h index ad70bb329c..5240122f49 100644 --- a/fastpair/repository/fast_pair_device_repository.h +++ b/fastpair/repository/fast_pair_device_repository.h @@ -54,6 +54,9 @@ class FastPairDeviceRepository { // or BLE. std::optional FindDevice(absl::string_view mac_address); + // Finds a device matching the account key. + std::optional FindDevice(const AccountKey& account_key); + void AddObserver(RemoveDeviceCallback* observer) { observers_.AddObserver(observer); } diff --git a/fastpair/repository/fast_pair_device_repository_test.cc b/fastpair/repository/fast_pair_device_repository_test.cc index 3418ae4ce4..e476e1d064 100644 --- a/fastpair/repository/fast_pair_device_repository_test.cc +++ b/fastpair/repository/fast_pair_device_repository_test.cc @@ -17,9 +17,9 @@ #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/account_key.h" #include "fastpair/common/fast_pair_device.h" #include "fastpair/common/protocol.h" #include "internal/platform/single_thread_executor.h" @@ -31,6 +31,7 @@ namespace { constexpr absl::string_view kModelId = "123456"; constexpr absl::string_view kBleAddress = "AA:BB:CC:DD:EE:FF"; constexpr absl::string_view kBtAddress = "12:34:56:78:90:AB"; +constexpr absl::string_view kAccountKey = "04b85786180add47fb81a04a8ce6b0de"; TEST(FastPairDeviceRepositoryTest, AddDevice) { SingleThreadExecutor executor; @@ -76,6 +77,24 @@ TEST(FastPairDeviceRepositoryTest, FindDeviceByBtAddress) { executor.Shutdown(); } +TEST(FastPairDeviceRepositoryTest, FindDeviceByAccountKey) { + SingleThreadExecutor executor; + FastPairDeviceRepository repo(&executor); + auto fast_pair_device = + std::make_unique(Protocol::kFastPairInitialPairing); + fast_pair_device->SetPublicAddress(kBtAddress); + fast_pair_device->SetAccountKey(AccountKey(kAccountKey)); + repo.AddDevice(std::move(fast_pair_device)); + + auto opt_device = repo.FindDevice(AccountKey(kAccountKey)); + + ASSERT_TRUE(opt_device.has_value()); + FastPairDevice* device = opt_device.value(); + ASSERT_NE(device, nullptr); + EXPECT_EQ(device->GetAccountKey().GetAsBytes(), kAccountKey); + executor.Shutdown(); +} + TEST(FastPairDeviceRepositoryTest, RemoveDevice) { SingleThreadExecutor executor; FastPairDeviceRepository repo(&executor); diff --git a/fastpair/scanning/fastpair/fast_pair_scanner_impl_test.cc b/fastpair/scanning/fastpair/fast_pair_scanner_impl_test.cc index 80c9c25401..184bd3aa42 100644 --- a/fastpair/scanning/fastpair/fast_pair_scanner_impl_test.cc +++ b/fastpair/scanning/fastpair/fast_pair_scanner_impl_test.cc @@ -16,6 +16,7 @@ #include #include +#include #include "gtest/gtest.h" #include "absl/strings/escaping.h" @@ -26,6 +27,7 @@ #include "internal/platform/byte_array.h" #include "internal/platform/count_down_latch.h" #include "internal/platform/medium_environment.h" +#include "internal/platform/single_thread_executor.h" namespace nearby { namespace fastpair { @@ -61,18 +63,16 @@ class FastPairScannerObserver : public FastPairScanner::Observer { }; class FastPairScannerImplTest : public testing::Test { - protected: - MediumEnvironment& env_{MediumEnvironment::Instance()}; - - SingleThreadExecutor executor_; + public: + void SetUp() override { MediumEnvironment::Instance().Start(); } + void TearDown() override { MediumEnvironment::Instance().Stop(); } }; TEST_F(FastPairScannerImplTest, StartScanning) { - env_.Start(); - // Create Fast Pair Scanner and add its observer Mediums mediums_1; - auto scanner = std::make_unique(mediums_1, &executor_); + SingleThreadExecutor executor; + auto scanner = std::make_unique(mediums_1, &executor); CountDownLatch accept_latch(1); CountDownLatch lost_latch(1); FastPairScannerObserver observer(scanner.get(), &accept_latch, &lost_latch); @@ -95,14 +95,14 @@ TEST_F(FastPairScannerImplTest, StartScanning) { // Notify device lost EXPECT_TRUE(lost_latch.Await(kTaskWaitTimeout).result()); scan_session.reset(); - env_.Stop(); + DestroyOnExecutor(std::move(scanner), &executor); } TEST_F(FastPairScannerImplTest, StopScanning) { - env_.Start(); // Create Fast Pair Scanner and add its observer Mediums mediums_1; - auto scanner = std::make_unique(mediums_1, &executor_); + SingleThreadExecutor executor; + auto scanner = std::make_unique(mediums_1, &executor); CountDownLatch accept_latch(1); CountDownLatch lost_latch(1); FastPairScannerObserver observer(scanner.get(), &accept_latch, &lost_latch); @@ -120,7 +120,7 @@ TEST_F(FastPairScannerImplTest, StopScanning) { mediums_2.GetBle().GetMedium().StopAdvertising(service_id); // Device lost event should not be delivered when scan session has terminated. EXPECT_FALSE(lost_latch.Await(kShortTimeout).result()); - env_.Stop(); + DestroyOnExecutor(std::move(scanner), &executor); } } // namespace diff --git a/internal/platform/flags/nearby_platform_feature_flags.h b/internal/platform/flags/nearby_platform_feature_flags.h index 0283353bb6..934574e8a9 100644 --- a/internal/platform/flags/nearby_platform_feature_flags.h +++ b/internal/platform/flags/nearby_platform_feature_flags.h @@ -15,6 +15,8 @@ #ifndef THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_FLAGS_NEARBY_PLATFORM_FEATURE_FLAGS_H_ #define THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_FLAGS_NEARBY_PLATFORM_FEATURE_FLAGS_H_ +#include + #include "absl/strings/string_view.h" #include "internal/flags/flag.h" @@ -57,7 +59,7 @@ constexpr auto kWifiHotspotConnectionMaxRetries = // The interval between 2 connectin attempts. constexpr auto kWifiHotspotConnectionIntervalMillis = - flags::Flag(kConfigPackage, "45415887", 500); + flags::Flag(kConfigPackage, "45415887", 2000); // The connection timeout to remote Wi-Fi hotspot. constexpr auto kWifiHotspotConnectionTimeoutMillis = diff --git a/internal/platform/implementation/windows/ble_v2.cc b/internal/platform/implementation/windows/ble_v2.cc index afe45ecca4..eb607be196 100644 --- a/internal/platform/implementation/windows/ble_v2.cc +++ b/internal/platform/implementation/windows/ble_v2.cc @@ -47,6 +47,7 @@ #include "winrt/Windows.Devices.Bluetooth.Advertisement.h" #include "winrt/Windows.Devices.Bluetooth.h" #include "winrt/Windows.Foundation.Collections.h" +#include "winrt/Windows.Storage.Streams.h" // NOLINT(misc-include-cleaner) namespace nearby { namespace windows { @@ -68,6 +69,8 @@ using ::winrt::Windows::Devices::Bluetooth::Advertisement:: BluetoothLEAdvertisementDataSection; using ::winrt::Windows::Devices::Bluetooth::Advertisement:: BluetoothLEAdvertisementDataTypes; +using ::winrt::Windows::Devices::Bluetooth::Advertisement:: + BluetoothLEAdvertisementFilter; // NOLINT(misc-include-cleaner) using ::winrt::Windows::Devices::Bluetooth::Advertisement:: BluetoothLEAdvertisementPublisher; using ::winrt::Windows::Devices::Bluetooth::Advertisement:: @@ -230,9 +233,19 @@ bool BleV2Medium::StartScanning(const Uuid& service_uuid, // Active mode indicates that scan request packets will be sent to query for // Scan Response watcher_.ScanningMode(BluetoothLEScanningMode::Active); - ::winrt::Windows::Devices::Bluetooth::BluetoothSignalStrengthFilter filter; - filter.SamplingInterval(TimeSpan(std::chrono::seconds(2))); - watcher_.SignalStrengthFilter(filter); + + BluetoothLEAdvertisementDataSection data_section; + data_section.DataType(0x16); + DataWriter data_writer; // NOLINT(misc-include-cleaner) + std::array service_id_data = service_uuid_.data(); + data_writer.WriteByte(service_id_data[3] & 0xff); + data_writer.WriteByte(service_id_data[2] & 0xff); + data_section.Data(data_writer.DetachBuffer()); + BluetoothLEAdvertisement advertisement; + advertisement.DataSections().Append(data_section); + BluetoothLEAdvertisementFilter advertisement_filter; + advertisement_filter.Advertisement(advertisement); + watcher_.AdvertisementFilter(advertisement_filter); watcher_.Start(); is_watcher_started_ = true; diff --git a/presence/fake_presence_client.cc b/presence/fake_presence_client.cc index a6fbe881cf..44e7344010 100644 --- a/presence/fake_presence_client.cc +++ b/presence/fake_presence_client.cc @@ -23,17 +23,6 @@ #include "presence/presence_device.h" #include "presence/scan_request.h" -namespace { - -::nearby::internal::Metadata BuildTestMetadata() { - ::nearby::internal::Metadata metadata; - metadata.set_bluetooth_mac_address("01234567"); - metadata.set_device_name("Pepper's device"); - return metadata; -} - -} // namespace - namespace nearby { namespace presence { @@ -62,19 +51,16 @@ void FakePresenceClient::CallStartScanCallback(absl::Status status) { callback_.start_scan_cb(status); } -void FakePresenceClient::CallOnDiscovered() { - PresenceDevice device{BuildTestMetadata()}; - callback_.on_discovered_cb(std::move(device)); +void FakePresenceClient::CallOnDiscovered(PresenceDevice device) { + callback_.on_discovered_cb(device); } -void FakePresenceClient::CallOnUpdated() { - PresenceDevice device{BuildTestMetadata()}; - callback_.on_updated_cb(std::move(device)); +void FakePresenceClient::CallOnUpdated(PresenceDevice device) { + callback_.on_updated_cb(device); } -void FakePresenceClient::CallOnLost() { - PresenceDevice device{BuildTestMetadata()}; - callback_.on_lost_cb(std::move(device)); +void FakePresenceClient::CallOnLost(PresenceDevice device) { + callback_.on_lost_cb(device); } } // namespace presence diff --git a/presence/fake_presence_client.h b/presence/fake_presence_client.h index 7bb8fffe2e..b2a6d81654 100644 --- a/presence/fake_presence_client.h +++ b/presence/fake_presence_client.h @@ -15,7 +15,6 @@ #ifndef THIRD_PARTY_NEARBY_PRESENCE_FAKE_PRESENCE_CLIENT_H_ #define THIRD_PARTY_NEARBY_PRESENCE_FAKE_PRESENCE_CLIENT_H_ - #include #include @@ -55,21 +54,17 @@ class FakePresenceClient : public PresenceClient { return std::nullopt; } - void SetNextScanSessionSuccess(bool success) { - next_scan_should_succeed_ = success; - } std::vector GetActiveScanSessions(); void CallStartScanCallback(absl::Status status); - void CallOnDiscovered(); - void CallOnUpdated(); - void CallOnLost(); + void CallOnDiscovered(PresenceDevice device); + void CallOnUpdated(PresenceDevice device); + void CallOnLost(PresenceDevice device); private: uint64_t current_scan_session_id_; ScanCallback callback_; std::vector active_scan_sessions_; - bool next_scan_should_succeed_ = true; }; } // namespace presence diff --git a/presence/proto/presence_frame.proto b/presence/proto/presence_frame.proto index 62fd7d474c..57d6607123 100644 --- a/presence/proto/presence_frame.proto +++ b/presence/proto/presence_frame.proto @@ -117,7 +117,7 @@ message UwbControleeCapabilities { optional bool is_ranging_interval_reconfigure_supported = 14 [default = false]; repeated int32 supported_slot_durations = 15 [packed = true]; - repeated int32 supported_ranging_intervals = 16 [packed = true]; + repeated int32 supported_ranging_update_rates = 16 [packed = true]; } /** diff --git a/proto/sharing_enums.proto b/proto/sharing_enums.proto index abb3478d17..3d2e9ceed1 100644 --- a/proto/sharing_enums.proto +++ b/proto/sharing_enums.proto @@ -310,6 +310,68 @@ enum AttachmentTransmissionStatus { // Breakdowns of FAILED_NULL_CONNECTION (Desktop side) FAILED_NULL_CONNECTION_INIT_OUTGOING = 18; FAILED_NULL_CONNECTION_DISCONNECTED = 19; + + // Breakdowns of FAILED_NULL_CONNECTION (android side) + // Connection failed due to Wifi is disconnected or Bluetooth setting is off + // or user turn on airplane mode. + FAILED_NULL_CONNECTION_LOST_CONNECTIVITY = 20; + // Unexpected connection failure. + FAILED_NULL_CONNECTION_FAILURE = 21; +} + +// Generic result status of NearbyConnections API calls. +enum ConnectionLayerStatus { + // No status is available + CONNECTION_LAYER_STATUS_UNKNOWN = 0; + // The operation was successful. + CONNECTION_LAYER_STATUS_SUCCESS = 1; + // The operation failed, without any more information. + CONNECTION_LAYER_STATUS_ERROR = 2; + // The app called an API method out of order (i.e. another method is expected + // to be called first). + CONNECTION_LAYER_STATUS_OUT_OF_ORDER_API_CALL = 3; + // The app already has active operations (advertising, discovering, or + // connected to other devices) with another Strategy. Stop these operations on + // the current Strategy before trying to advertise or discover with a new + // Strategy. + CONNECTION_LAYER_STATUS_ALREADY_HAVE_ACTIVE_STRATEGY = 4; + // The app is already advertising; call StopAdvertising() before trying to + // advertise again. + CONNECTION_LAYER_STATUS_ALREADY_ADVERTISING = 5; + // The app is already discovering; call StopDiscovery() before trying to + // discover again. + CONNECTION_LAYER_STATUS_ALREADY_DISCOVERING = 6; + // NC is already listening for incoming connections from remote endpoints. + CONNECTION_LAYER_STATUS_ALREADY_LISTENING = 7; + // An attempt to read from/write to a connected remote endpoint failed. If + // this occurs repeatedly, consider invoking DisconnectFromEndpoint(). + CONNECTION_LAYER_STATUS_END_POINT_IO_ERROR = 8; + // An attempt to interact with a remote endpoint failed because it's unknown + // to us -- it's either an endpoint that was never discovered, or an endpoint + // that never connected to us (both of which are indicative of bad input from + // the client app). + CONNECTION_LAYER_STATUS_END_POINT_UNKNOWN = 9; + // The remote endpoint rejected the connection request. + CONNECTION_LAYER_STATUS_CONNECTION_REJECTED = 10; + // The app is already connected to the specified endpoint. Multiple + // connections to a remote endpoint cannot be maintained simultaneously. + CONNECTION_LAYER_STATUS_ALREADY_CONNECTED_TO_END_POINT = 11; + // The remote endpoint is not connected; messages cannot be sent to it. + CONNECTION_LAYER_STATUS_NOT_CONNECTED_TO_END_POINT = 12; + // There was an error trying to use the device's Bluetooth capabilities. + CONNECTION_LAYER_STATUS_BLUETOOTH_ERROR = 13; + // There was an error trying to use the device's Bluetooth Low Energy + // capabilities. + CONNECTION_LAYER_STATUS_BLE_ERROR = 14; + // There was an error trying to use the device's Wi-Fi capabilities. + CONNECTION_LAYER_STATUS_WIFI_LAN_ERROR = 15; + // An attempt to interact with an in-flight Payload failed because it's + // unknown to us. + CONNECTION_LAYER_STATUS_PAYLOAD_UNKNOWN = 16; + // The connection was reset + CONNECTION_LAYER_STATUS_RESET = 17; + // The connection timed out + CONNECTION_LAYER_STATUS_TIMEOUT = 18; } // The status of processing attachments after receiver received payloads @@ -434,6 +496,49 @@ enum ServerResponseState { SERVER_RESPONSE_NOT_CONNECTED_TO_INTERNET = 10; } +// The purpose of requesting the server request. +enum SyncPurpose { + SYNC_PURPOSE_UNKNOWN = 0; + // When NearbySharingChimeraService#sync() is called. + SYNC_PURPOSE_ON_DEMAND_SYNC = 1; + // Requested by chime notification. + SYNC_PURPOSE_CHIME_NOTIFICATION = 2; + // For reqular daily sync. + SYNC_PURPOSE_DAILY_SYNC = 3; + // Wen a device opts into Nearby Share. + SYNC_PURPOSE_OPT_IN_FIRST_SYNC = 4; + // Requested when Nearby Share automatically enables a device that shares + // a single account that has already opted in on another device. + SYNC_PURPOSE_CHECK_DEFAULT_OPT_IN = 5; + // When a device enables Nearby Share. + SYNC_PURPOSE_NEARBY_SHARE_ENABLED = 6; + // When a device is in fast init advertising. + SYNC_PURPOSE_SYNC_AT_FAST_INIT = 7; + // When device start discovery. + SYNC_PURPOSE_SYNC_AT_DISCOVERY = 8; + // When device tries to load valid private certificate. + SYNC_PURPOSE_SYNC_AT_LOAD_PRIVATE_CERTIFICATE = 9; + // When device start advertiseement. + SYNC_PURPOSE_SYNC_AT_ADVERTISEMENT = 10; + // When device contacts list changes. + SYNC_PURPOSE_CONTACT_LIST_CHANGE = 11; + // When showing the C11 banner in Neary Share setting. + SYNC_PURPOSE_SHOW_C11N_VIEW = 12; + // For regular check contact reachability. + SYNC_PURPOSE_REGULAR_CHECK_CONTACT_REACHABILITY = 13; + // When selected contacts list changes in visibility setting. + SYNC_PURPOSE_VISIBILITY_SELECTED_CONTACT_CHANGE = 14; + // When switching account. + SYNC_PURPOSE_ACCOUNT_CHANGE = 15; +} + +// The device role to trigger the server request. +enum ClientRole { + CLIENT_ROLE_UNKNOWN = 0; + CLIENT_ROLE_SENDER = 1; + CLIENT_ROLE_RECEIVER = 2; +} + // The type of Nearby Sharing scanning. enum ScanType { UNKNOWN_SCAN_TYPE = 0; @@ -446,7 +551,12 @@ enum ScanType { // The type of parsing endpoint id failed type. enum ParsingFailedType { FAILED_UNKNOWN_TYPE = 0; + // NULL advertisement is returned due to sender failing to parse advertisement + // from endpointInfo byte stream from receiver advertisement. FAILED_PARSE_ADVERTISEMENT = 1; + // NULL shareTarget is returned due to sender failing to create shareTarget + // from a valid parsed advertisement stemming from issues in certificates, QR + // code tokens or device names. FAILED_CONVERT_SHARE_TARGET = 2; }