From e20fb4f75d3979cc702b1fa37e7c84ed147d59c7 Mon Sep 17 00:00:00 2001 From: Qin Wang Date: Tue, 13 Jun 2023 12:25:05 -0700 Subject: [PATCH] Add screen locked listener for fast pair windows PiperOrigin-RevId: 540038338 --- fastpair/dart/windows/BUILD | 3 +- .../dart/windows/fast_pair_service_adapter.cc | 8 +++ .../dart/windows/fast_pair_service_adapter.h | 5 +- fastpair/internal/BUILD | 2 + fastpair/internal/fast_pair_seeker_impl.cc | 27 +++++++++ fastpair/internal/fast_pair_seeker_impl.h | 7 ++- .../internal/fast_pair_seeker_impl_test.cc | 36 +++++++++++- fastpair/keyed_service/BUILD | 4 +- fastpair/keyed_service/fast_pair_mediator.cc | 55 ++++++++++++++++++- fastpair/keyed_service/fast_pair_mediator.h | 7 ++- 10 files changed, 147 insertions(+), 7 deletions(-) diff --git a/fastpair/dart/windows/BUILD b/fastpair/dart/windows/BUILD index ac27060e..d6caa612 100644 --- a/fastpair/dart/windows/BUILD +++ b/fastpair/dart/windows/BUILD @@ -56,15 +56,16 @@ lexan.cc_windows_dll( "fast_pair_service_adapter_dart.h", ], copts = [ + "-Wc++17-compat", "-Ithird_party", ], defines = [ "LOG_SEVERITY_VERBOSE", + "DART_SHARED_LIB=1", "_WIN32_WINNT=_WIN32_WINNT_WIN10", ], tags = ["windows-dll"], visibility = [ - "//fastpair:__subpackages__", "//location/nearby/apps/better_together/windows/fast_pair:__subpackages__", ], deps = [ diff --git a/fastpair/dart/windows/fast_pair_service_adapter.cc b/fastpair/dart/windows/fast_pair_service_adapter.cc index a134815c..ef7e815e 100644 --- a/fastpair/dart/windows/fast_pair_service_adapter.cc +++ b/fastpair/dart/windows/fast_pair_service_adapter.cc @@ -82,6 +82,14 @@ void __stdcall DiscoveryClicked(Mediator *pMediator, DiscoveryAction action) { ->OnDiscoveryClicked(action); } +void __stdcall SetIsScreenLocked(bool is_locked) { + if (pMediator_ == nullptr) { + NEARBY_LOGS(INFO) << "The pMediator is a null pointer."; + return; + } + NEARBY_LOGS(INFO) << "SetIsScreenLocked :" << is_locked; + pMediator_->SetIsScreenLocked(is_locked); +} } // namespace windows } // namespace fastpair } // namespace nearby diff --git a/fastpair/dart/windows/fast_pair_service_adapter.h b/fastpair/dart/windows/fast_pair_service_adapter.h index 04ec253d..19d6ce4d 100644 --- a/fastpair/dart/windows/fast_pair_service_adapter.h +++ b/fastpair/dart/windows/fast_pair_service_adapter.h @@ -30,7 +30,7 @@ namespace windows { // Initiates a default Mediator instance. Return the instance handle to client. DLL_EXPORT void *__stdcall InitMediator(); -// Starts scaning service +// Starts scanning service DLL_EXPORT void __stdcall StartScan(Mediator *pMediator); // Adds a notification controller observer to the service. @@ -44,6 +44,9 @@ DLL_EXPORT void __stdcall RemoveNotificationControllerObserver( // Triggers discovery click action DLL_EXPORT void DiscoveryClicked(Mediator *pMediator, DiscoveryAction action); +// Sends screen locked event. +DLL_EXPORT void __stdcall SetIsScreenLocked(bool is_locked); + } // namespace windows } // namespace fastpair } // namespace nearby diff --git a/fastpair/internal/BUILD b/fastpair/internal/BUILD index 95a81e29..dc0714cf 100644 --- a/fastpair/internal/BUILD +++ b/fastpair/internal/BUILD @@ -33,8 +33,10 @@ cc_test( "//fastpair/message_stream:fake_provider", "//fastpair/server_access:test_support", "//internal/platform:test_util", + "//internal/platform:types", "//internal/platform/implementation/g3", # build_cleaner: keep "@com_github_protobuf_matchers//protobuf-matchers", + "@com_google_absl//absl/time", "@com_google_googletest//:gtest_main", ], ) diff --git a/fastpair/internal/fast_pair_seeker_impl.cc b/fastpair/internal/fast_pair_seeker_impl.cc index ad148453..79259e15 100644 --- a/fastpair/internal/fast_pair_seeker_impl.cc +++ b/fastpair/internal/fast_pair_seeker_impl.cc @@ -14,6 +14,7 @@ #include "fastpair/internal/fast_pair_seeker_impl.h" +#include #include #include #include @@ -117,5 +118,31 @@ void FastPairSeekerImpl::OnPairFailure(FastPairDevice& device, << " with PairFailure: " << failure; } +void FastPairSeekerImpl::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 FastPairSeekerImpl::InvalidateScanningState() { + // Stop scanning when screen is off. + if (is_screen_locked_) { + absl::Status status = StopFastPairScan(); + 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. + absl::Status status = StartFastPairScan(); +} } // namespace fastpair } // namespace nearby diff --git a/fastpair/internal/fast_pair_seeker_impl.h b/fastpair/internal/fast_pair_seeker_impl.h index c180353d..5a9c2513 100644 --- a/fastpair/internal/fast_pair_seeker_impl.h +++ b/fastpair/internal/fast_pair_seeker_impl.h @@ -75,6 +75,9 @@ class FastPairSeekerImpl : public FastPairSeekerExt, absl::Status StartFastPairScan() override; absl::Status StopFastPairScan() override; + // Handle the state changes of screen lock. + void SetIsScreenLocked(bool is_locked); + // Internal methods, not exported to plugins. private: // From ScannerBrokerImpl::Observer. @@ -88,6 +91,8 @@ class FastPairSeekerImpl : public FastPairSeekerExt, void OnPairingComplete(FastPairDevice& device) override; void OnPairFailure(FastPairDevice& device, PairFailure failure) override; + void InvalidateScanningState() ABSL_EXCLUSIVE_LOCKS_REQUIRED(*executor_); + ServiceCallbacks callbacks_; SingleThreadExecutor* executor_; FastPairDeviceRepository* devices_; @@ -95,8 +100,8 @@ class FastPairSeekerImpl : public FastPairSeekerExt, std::unique_ptr scanner_; std::unique_ptr scanning_session_; std::unique_ptr pairer_broker_; - FastPairDevice* test_device_ = nullptr; + bool is_screen_locked_ = false; }; } // namespace fastpair diff --git a/fastpair/internal/fast_pair_seeker_impl_test.cc b/fastpair/internal/fast_pair_seeker_impl_test.cc index f5be2008..db6c2337 100644 --- a/fastpair/internal/fast_pair_seeker_impl_test.cc +++ b/fastpair/internal/fast_pair_seeker_impl_test.cc @@ -14,24 +14,32 @@ #include "fastpair/internal/fast_pair_seeker_impl.h" +#include + #include -#include +#include #include "gmock/gmock.h" #include "protobuf-matchers/protocol-buffer-matchers.h" #include "gtest/gtest.h" +#include "absl/time/clock.h" #include "fastpair/message_stream/fake_provider.h" #include "fastpair/server_access/fake_fast_pair_repository.h" +#include "internal/platform/count_down_latch.h" #include "internal/platform/medium_environment.h" namespace nearby { namespace fastpair { namespace { +constexpr absl::string_view kServiceID{"Fast Pair"}; +constexpr absl::string_view kFastPairServiceUuid{ + "0000FE2C-0000-1000-8000-00805F9B34FB"}; constexpr absl::string_view kModelId{"718c17"}; constexpr absl::string_view kPublicAntiSpoof = "Wuyr48lD3txnUhGiMF1IfzlTwRxxe+wMB1HLzP+" "0wVcljfT3XPoiy1fntlneziyLD5knDVAJSE+RM/zlPRP/Jg=="; +constexpr absl::Duration kTaskWaitTimeout = absl::Milliseconds(100); using ::testing::status::StatusIs; @@ -102,6 +110,32 @@ TEST_F(FastPairSeekerImplTest, StopFastPairScanTwiceFails) { StatusIs(absl::StatusCode::kNotFound)); } +TEST_F(FastPairSeekerImplTest, ScreenLocksDuringAdvertising) { + CountDownLatch latch(1); + fast_pair_seeker_ = std::make_unique( + FastPairSeekerImpl::ServiceCallbacks{ + .on_initial_discovery = + [&](const FastPairDevice& device, InitialDiscoveryEvent event) { + latch.CountDown(); + }}, + &executor_, &devices_); + + EXPECT_OK(fast_pair_seeker_->StartFastPairScan()); + EXPECT_THAT(fast_pair_seeker_->StartFastPairScan(), + StatusIs(absl::StatusCode::kAlreadyExists)); + + fast_pair_seeker_->SetIsScreenLocked(true); + // Create Advertiser and startAdvertising + Mediums mediums_2; + std::string service_id(kServiceID); + ByteArray advertisement_bytes{absl::HexStringToBytes(kModelId)}; + std::string fast_pair_service_uuid(kFastPairServiceUuid); + mediums_2.GetBle().GetMedium().StartAdvertising( + service_id, advertisement_bytes, fast_pair_service_uuid); + + EXPECT_FALSE(latch.Await(kTaskWaitTimeout).result()); +} + } // namespace } // namespace fastpair } // namespace nearby diff --git a/fastpair/keyed_service/BUILD b/fastpair/keyed_service/BUILD index a2495fd0..21e38764 100644 --- a/fastpair/keyed_service/BUILD +++ b/fastpair/keyed_service/BUILD @@ -24,7 +24,6 @@ cc_library( "fast_pair_mediator.h", "fast_pair_mediator_factory.h", ], - compatible_with = ["//buildenv/target:non_prod"], visibility = [ "//fastpair:__subpackages__", ], @@ -33,11 +32,14 @@ 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/flags:nearby_flags", "//internal/platform:logging", "//internal/platform:types", + "//internal/platform/flags:platform_flags", ], ) diff --git a/fastpair/keyed_service/fast_pair_mediator.cc b/fastpair/keyed_service/fast_pair_mediator.cc index c90190ab..2b93118b 100644 --- a/fastpair/keyed_service/fast_pair_mediator.cc +++ b/fastpair/keyed_service/fast_pair_mediator.cc @@ -14,6 +14,7 @@ #include "fastpair/keyed_service/fast_pair_mediator.h" +#include #include #include #include @@ -27,6 +28,9 @@ #include "fastpair/ui/actions.h" #include "fastpair/ui/fast_pair/fast_pair_notification_controller.h" #include "fastpair/ui/ui_broker_impl.h" +#include "internal/flags/nearby_flags.h" +#include "internal/platform/device_info_impl.h" +#include "internal/platform/flags/nearby_platform_feature_flags.h" #include "internal/platform/logging.h" #include "internal/platform/single_thread_executor.h" @@ -43,11 +47,16 @@ Mediator::Mediator( notification_controller_(std::move(notification_controller)), fast_pair_repository_(std::move(fast_pair_repository)), executor_(std::move(executor)) { + NearbyFlags::GetInstance().OverrideBoolFlagValue( + platform::config_package_nearby::nearby_platform_feature:: + kEnableBleV2Gatt, + true); devices_ = std::make_unique(executor_.get()); scanner_broker_ = std::make_unique( *mediums_, executor_.get(), devices_.get()); pairer_broker_ = std::make_unique(*mediums_, executor_.get()); + scanner_broker_->AddObserver(this); ui_broker_->AddObserver(this); pairer_broker_->AddObserver(this); @@ -55,7 +64,6 @@ Mediator::Mediator( void Mediator::OnDeviceFound(FastPairDevice& device) { NEARBY_LOGS(INFO) << __func__ << ": " << device; - if (IsDeviceCurrentlyShowingNotification(device)) { NEARBY_LOGS(VERBOSE) << __func__ << ": Extending notification for re-discovered device=" @@ -138,7 +146,14 @@ void Mediator::OnPairFailure(FastPairDevice& device, PairFailure failure) { } 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; @@ -146,6 +161,16 @@ void Mediator::StartScanning() { 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. @@ -171,5 +196,33 @@ bool Mediator::IsDeviceCurrentlyShowingNotification( device.GetProtocol(); } +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 index c4886ae7..34d30982 100644 --- a/fastpair/keyed_service/fast_pair_mediator.h +++ b/fastpair/keyed_service/fast_pair_mediator.h @@ -65,6 +65,7 @@ class Mediator final : public ScannerBroker::Observer, void OnDeviceLost(FastPairDevice& device) override; void StartScanning(); + void StopScanning(); // UIBroker::Observer void OnDiscoveryAction(FastPairDevice& device, @@ -77,9 +78,12 @@ class Mediator final : public ScannerBroker::Observer, 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); // |device_currently_showing_notification_| can be null if there is no @@ -95,6 +99,7 @@ class Mediator final : public ScannerBroker::Observer, std::unique_ptr fast_pair_repository_; std::unique_ptr executor_; std::unique_ptr devices_; + bool is_screen_locked_ = false; }; } // namespace fastpair