diff --git a/fastpair/ui/BUILD b/fastpair/ui/BUILD new file mode 100644 index 00000000..e8631c0f --- /dev/null +++ b/fastpair/ui/BUILD @@ -0,0 +1,64 @@ +licenses(["notice"]) + +cc_library( + name = "fast_pair_ui", + srcs = [ + "fast_pair/fast_pair_notification_controller.cc", + "fast_pair/fast_pair_presenter_impl.cc", + ], + hdrs = [ + "actions.h", + "fast_pair/fast_pair_notification_controller.h", + "fast_pair/fast_pair_presenter.h", + "fast_pair/fast_pair_presenter_impl.h", + ], + compatible_with = ["//buildenv/target:non_prod"], + visibility = [ + "//fastpair:__subpackages__", + ], + deps = [ + "//fastpair/common", + "//fastpair/repository", + "//fastpair/server_access", + "//internal/base", + "//internal/platform:logging", + "@com_google_absl//absl/functional:any_invocable", + "@com_google_absl//absl/log:check", + "@com_google_absl//absl/strings", + ], +) + +cc_library( + name = "fake_fast_pair_ui", + hdrs = [ + "fast_pair/fake_fast_pair_notification_controller_observer.h", + "fast_pair/fake_fast_pair_presenter.h", + ], + visibility = [ + "//fastpair:__subpackages__", + ], + deps = [ + ":fast_pair_ui", + "//fastpair/repository", + ], +) + +cc_test( + name = "fast_pair_ui_test", + srcs = [ + "fast_pair/fast_pair_notification_controller_test.cc", + "fast_pair/fast_pair_presenter_impl_test.cc", + ], + deps = [ + ":fake_fast_pair_ui", + ":fast_pair_ui", + "//fastpair/common", + "//fastpair/proto:fastpair_cc_proto", + "//fastpair/repository", + "//fastpair/server_access:test_support", + "//internal/network:types", + "//internal/platform/implementation/g3", + "@com_github_protobuf_matchers//protobuf-matchers", + "@com_google_googletest//:gtest_main", + ], +) diff --git a/fastpair/ui/actions.h b/fastpair/ui/actions.h new file mode 100644 index 00000000..658100d0 --- /dev/null +++ b/fastpair/ui/actions.h @@ -0,0 +1,32 @@ +// 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_UI_ACTIONS_H_ +#define THIRD_PARTY_NEARBY_FASTPAIR_UI_ACTIONS_H_ + +namespace nearby { +namespace fastpair { + +enum class DiscoveryAction { + kPairToDevice = 0, + kDismissedByUser = 1, + kDismissedByOs = 2, + kLearnMore = 3, + kDismissedByTimeout = 4, +}; + +} // namespace fastpair +} // namespace nearby + +#endif // THIRD_PARTY_NEARBY_FASTPAIR_UI_ACTIONS_H_ diff --git a/fastpair/ui/fast_pair/fake_fast_pair_presenter.h b/fastpair/ui/fast_pair/fake_fast_pair_presenter.h index f2fe938c..c5ee2038 100644 --- a/fastpair/ui/fast_pair/fake_fast_pair_presenter.h +++ b/fastpair/ui/fast_pair/fake_fast_pair_presenter.h @@ -17,6 +17,8 @@ #include +#include "fastpair/ui/actions.h" +#include "fastpair/ui/fast_pair/fast_pair_notification_controller.h" #include "fastpair/ui/fast_pair/fast_pair_presenter_impl.h" namespace nearby { @@ -24,10 +26,11 @@ namespace fastpair { class FakeFastPairPresenter : public FastPairPresenter { public: - void ShowDiscovery( - const FastPairDevice& device, - FastPairNotificationController& notification_controller) override { + void ShowDiscovery(const FastPairDevice& device, + FastPairNotificationController& notification_controller, + DiscoveryCallback callback) override { show_discovery_ = true; + callback(DiscoveryAction::kPairToDevice); } bool show_deiscovery() { return show_discovery_; } diff --git a/fastpair/ui/fast_pair/fast_pair_notification_controller.cc b/fastpair/ui/fast_pair/fast_pair_notification_controller.cc index 35f26de6..6f8ec747 100644 --- a/fastpair/ui/fast_pair/fast_pair_notification_controller.cc +++ b/fastpair/ui/fast_pair/fast_pair_notification_controller.cc @@ -14,7 +14,13 @@ #include "fastpair/ui/fast_pair/fast_pair_notification_controller.h" +#include + +#include "absl/functional/any_invocable.h" #include "fastpair/repository/device_metadata.h" +#include "fastpair/ui/actions.h" +#include "internal/platform/logging.h" + namespace nearby { namespace fastpair { void FastPairNotificationController::AddObserver(Observer* observer) { @@ -33,9 +39,19 @@ void FastPairNotificationController::NotifyShowDiscovery( } void FastPairNotificationController::ShowGuestDiscoveryNotification( - const DeviceMetadata& device) { + const DeviceMetadata& device, DiscoveryCallback callback) { + callback_ = std::move(callback); + NEARBY_LOGS(INFO) << __func__ << "Notify show guest discovery notification. "; NotifyShowDiscovery(device); } +void FastPairNotificationController::OnDiscoveryClicked( + DiscoveryAction action) { + NEARBY_LOGS(INFO) << __func__ + << "Discovery action button is clicked in the app."; + DCHECK(callback_); + callback_(action); +} + } // namespace fastpair } // namespace nearby diff --git a/fastpair/ui/fast_pair/fast_pair_notification_controller.h b/fastpair/ui/fast_pair/fast_pair_notification_controller.h index 7095aa17..5006c565 100644 --- a/fastpair/ui/fast_pair/fast_pair_notification_controller.h +++ b/fastpair/ui/fast_pair/fast_pair_notification_controller.h @@ -18,17 +18,19 @@ #include "absl/functional/any_invocable.h" #include "absl/strings/string_view.h" #include "fastpair/repository/device_metadata.h" +#include "fastpair/ui/actions.h" #include "internal/base/observer_list.h" namespace nearby { namespace fastpair { -using RepeatingClosure = absl::AnyInvocable; + +using DiscoveryCallback = absl::AnyInvocable; + enum class FastPairNotificationDismissReason { kDismissedByUser, kDismissedByOs, kDismissedByTimeout, }; - // This controller creates and manages messages for each FastPair corresponding // notification event. class FastPairNotificationController { @@ -52,9 +54,14 @@ class FastPairNotificationController { void NotifyShowDiscovery(const DeviceMetadata& device); // Creates and displays corresponding notification. - void ShowGuestDiscoveryNotification(const DeviceMetadata& device_metadata); + void ShowGuestDiscoveryNotification(const DeviceMetadata& device_metadata, + DiscoveryCallback callback); + + // Triggers callback when the related action is clicked. + void OnDiscoveryClicked(DiscoveryAction action); private: + DiscoveryCallback callback_; ObserverList observers_; }; } // namespace fastpair diff --git a/fastpair/ui/fast_pair/fast_pair_notification_controller_test.cc b/fastpair/ui/fast_pair/fast_pair_notification_controller_test.cc index 997b8aa6..6142e2d2 100644 --- a/fastpair/ui/fast_pair/fast_pair_notification_controller_test.cc +++ b/fastpair/ui/fast_pair/fast_pair_notification_controller_test.cc @@ -14,15 +14,15 @@ #include "fastpair/ui/fast_pair/fast_pair_notification_controller.h" -#include -#include #include -#include +#include +#include #include "gmock/gmock.h" #include "protobuf-matchers/protocol-buffer-matchers.h" #include "gtest/gtest.h" #include "fastpair/repository/device_metadata.h" +#include "fastpair/ui/actions.h" #include "fastpair/ui/fast_pair/fake_fast_pair_notification_controller_observer.h" namespace nearby { @@ -39,12 +39,19 @@ class FastPairNotificationControllerTest : public ::testing::Test { notification_controller_.AddObserver(¬ification_controller_obsesrver_); } - void TriggerOnUpdateDevice(DeviceMetadata& device) { - notification_controller_.ShowGuestDiscoveryNotification(device); + void TriggerOnUpdateDevice(DeviceMetadata& device, + DiscoveryCallback callback) { + notification_controller_.ShowGuestDiscoveryNotification( + device, std::move(callback)); + } + + void DiscoveryActionClicked(DiscoveryAction action) { + discovery_action_ = action; } FastPairNotificationController notification_controller_; FakeFastPairNotificationControllerObserver notification_controller_obsesrver_; + DiscoveryAction discovery_action_; }; TEST_F(FastPairNotificationControllerTest, ShowGuestDiscoveryNotification) { @@ -52,10 +59,14 @@ TEST_F(FastPairNotificationControllerTest, ShowGuestDiscoveryNotification) { response.mutable_device()->set_id(kDeviceId); response.mutable_device()->set_name(kDeviceName); DeviceMetadata device_metadata(response); - TriggerOnUpdateDevice(device_metadata); + TriggerOnUpdateDevice(device_metadata, [this](DiscoveryAction action) { + DiscoveryActionClicked(action); + }); EXPECT_TRUE(notification_controller_obsesrver_ .CheckDeviceMetadataListContainTestDevice(kDeviceName)); EXPECT_EQ(1, notification_controller_obsesrver_.on_update_device_count()); + notification_controller_.OnDiscoveryClicked(DiscoveryAction::kPairToDevice); + EXPECT_EQ(DiscoveryAction::kPairToDevice, discovery_action_); } } // namespace diff --git a/fastpair/ui/fast_pair/fast_pair_presenter.h b/fastpair/ui/fast_pair/fast_pair_presenter.h index 93313f7e..8b758531 100644 --- a/fastpair/ui/fast_pair/fast_pair_presenter.h +++ b/fastpair/ui/fast_pair/fast_pair_presenter.h @@ -15,7 +15,11 @@ #ifndef THIRD_PARTY_NEARBY_FASTPAIR_UI_FAST_PAIR_FAST_PAIR_PRESENTER_H_ #define THIRD_PARTY_NEARBY_FASTPAIR_UI_FAST_PAIR_FAST_PAIR_PRESENTER_H_ +#include + +#include "absl/functional/any_invocable.h" #include "fastpair/common/fast_pair_device.h" +#include "fastpair/ui/actions.h" #include "fastpair/ui/fast_pair/fast_pair_notification_controller.h" namespace nearby { @@ -27,7 +31,8 @@ class FastPairPresenter { // observer_list of notification_controller is updated virtual void ShowDiscovery( const FastPairDevice& device, - FastPairNotificationController& notification_controller) = 0; + FastPairNotificationController& notification_controller, + DiscoveryCallback callback) = 0; virtual ~FastPairPresenter() = default; }; diff --git a/fastpair/ui/fast_pair/fast_pair_presenter_impl.cc b/fastpair/ui/fast_pair/fast_pair_presenter_impl.cc index a5916cdf..78b80f71 100644 --- a/fastpair/ui/fast_pair/fast_pair_presenter_impl.cc +++ b/fastpair/ui/fast_pair/fast_pair_presenter_impl.cc @@ -15,10 +15,13 @@ #include "fastpair/ui/fast_pair/fast_pair_presenter_impl.h" #include +#include +#include "absl/functional/any_invocable.h" #include "absl/strings/string_view.h" #include "fastpair/repository/device_metadata.h" #include "fastpair/server_access/fast_pair_repository.h" +#include "fastpair/ui/actions.h" #include "fastpair/ui/fast_pair/fast_pair_notification_controller.h" #include "internal/platform/logging.h" @@ -47,22 +50,24 @@ FastPairPresenterImpl::Factory::~Factory() = default; void FastPairPresenterImpl::ShowDiscovery( const FastPairDevice& device, - FastPairNotificationController& notification_controller) { + FastPairNotificationController& notification_controller, + DiscoveryCallback callback) { + callback_ = std::move(callback); FastPairRepository::Get()->GetDeviceMetadata( - device.GetModelId(), - [¬ification_controller, this](const DeviceMetadata& device_metadata) { + device.GetModelId(), [&device, ¬ification_controller, + this](const DeviceMetadata& device_metadata) { NEARBY_LOGS(INFO) << __func__ << "Retrieved metadata to notification controller."; - FastPairPresenterImpl::OnDiscoveryMetadataRetrieved( - device_metadata, notification_controller); + OnDiscoveryMetadataRetrieved(device, device_metadata, + notification_controller); }); } void FastPairPresenterImpl::OnDiscoveryMetadataRetrieved( - const DeviceMetadata& device_metadata, + const FastPairDevice& device, const DeviceMetadata& device_metadata, FastPairNotificationController& notification_controller) { - notification_controller.ShowGuestDiscoveryNotification(device_metadata); + notification_controller.ShowGuestDiscoveryNotification(device_metadata, + 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 10bd71b5..c5ee2d97 100644 --- a/fastpair/ui/fast_pair/fast_pair_presenter_impl.h +++ b/fastpair/ui/fast_pair/fast_pair_presenter_impl.h @@ -19,6 +19,7 @@ #include "fastpair/common/fast_pair_device.h" #include "fastpair/repository/device_metadata.h" +#include "fastpair/ui/actions.h" #include "fastpair/ui/fast_pair/fast_pair_notification_controller.h" #include "fastpair/ui/fast_pair/fast_pair_presenter.h" @@ -45,15 +46,16 @@ class FastPairPresenterImpl : public FastPairPresenter { FastPairPresenterImpl(const FastPairPresenterImpl&) = delete; FastPairPresenterImpl& operator=(const FastPairPresenterImpl&) = delete; - void ShowDiscovery( - const FastPairDevice& device, - FastPairNotificationController& notification_controller) override; + void ShowDiscovery(const FastPairDevice& device, + FastPairNotificationController& notification_controller, + DiscoveryCallback callback) override; private: // observer_list of notification_controller is updated void OnDiscoveryMetadataRetrieved( - const DeviceMetadata& device_metadata, + const 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 6929643e..9c33a7b8 100644 --- a/fastpair/ui/fast_pair/fast_pair_presenter_impl_test.cc +++ b/fastpair/ui/fast_pair/fast_pair_presenter_impl_test.cc @@ -22,9 +22,9 @@ #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" -#include "fastpair/ui/fast_pair/fast_pair_presenter.h" namespace nearby { namespace fastpair { @@ -42,7 +42,11 @@ class FastPairPresenterImplTest : public ::testing::Test { controller_.AddObserver(¬ification_controller_observer_); } + void OnDiscoveryAction(DiscoveryAction action) { discovery_action_ = action; } + protected: + DiscoveryAction discovery_action_; + FakeFastPairRepository repository_; FastPairPresenterImpl fast_pair_presenter_; FastPairNotificationController controller_; @@ -54,8 +58,12 @@ TEST_F(FastPairPresenterImplTest, ShowDiscovery) { Protocol::kFastPairInitialPairing); EXPECT_EQ(0, notification_controller_observer_.on_update_device_count()); - fast_pair_presenter_.ShowDiscovery(device, controller_); + fast_pair_presenter_.ShowDiscovery( + device, controller_, + [this](DiscoveryAction action) { OnDiscoveryAction(action); }); EXPECT_EQ(1, notification_controller_observer_.on_update_device_count()); + controller_.OnDiscoveryClicked(DiscoveryAction::kPairToDevice); + EXPECT_EQ(DiscoveryAction::kPairToDevice, discovery_action_); } } // namespace } // namespace fastpair