From 21d2efbccd5607fb8d9fa2b4c8f5474e4d9169af Mon Sep 17 00:00:00 2001 From: Anay Wadhera Date: Tue, 2 May 2023 16:01:21 -0700 Subject: [PATCH] Create PresenceDeviceProvider PiperOrigin-RevId: 528913199 --- connections/core.h | 5 +- internal/interop/BUILD | 1 + internal/interop/device.h | 4 -- internal/interop/device_provider.h | 5 +- internal/platform/BUILD | 1 + presence/BUILD | 8 +++ presence/implementation/service_controller.h | 1 + .../implementation/service_controller_impl.h | 2 + presence/presence_client.cc | 12 +++- presence/presence_client.h | 6 ++ presence/presence_client_test.cc | 32 +++++++++ presence/presence_device.h | 7 +- presence/presence_device_provider.h | 42 +++++++++++ presence/presence_device_provider_test.cc | 72 +++++++++++++++++++ presence/presence_service.cc | 5 +- presence/presence_service.h | 7 ++ presence/presence_service_test.cc | 5 ++ 17 files changed, 204 insertions(+), 11 deletions(-) create mode 100644 presence/presence_device_provider.h create mode 100644 presence/presence_device_provider_test.cc diff --git a/connections/core.h b/connections/core.h index 714ebbc831..7142b6e43b 100644 --- a/connections/core.h +++ b/connections/core.h @@ -17,6 +17,7 @@ #include #include +#include #include "absl/strings/string_view.h" #include "absl/types/span.h" @@ -507,7 +508,9 @@ class Core { // Registers a DeviceProvider to provide functionality for Nearby Connections // to interact with the DeviceProvider for retrieving the local device. - void RegisterDeviceProvider(NearbyDeviceProvider&& provider); + template ::value>::type* = nullptr> + void RegisterDeviceProvider(NearbyDeviceProvider* provider); private: ClientProxy client_; diff --git a/internal/interop/BUILD b/internal/interop/BUILD index 9836cef487..f5423d0644 100644 --- a/internal/interop/BUILD +++ b/internal/interop/BUILD @@ -10,6 +10,7 @@ cc_library( ], deps = [ "//internal/platform:connection_info", + "//internal/platform:types", "@com_google_absl//absl/strings", "@com_google_absl//absl/types:variant", ], diff --git a/internal/interop/device.h b/internal/interop/device.h index 82f2f9b7ce..d13979f349 100644 --- a/internal/interop/device.h +++ b/internal/interop/device.h @@ -41,10 +41,6 @@ class NearbyDevice { }; NearbyDevice() = default; virtual ~NearbyDevice() = default; - NearbyDevice(NearbyDevice&&) = default; - NearbyDevice& operator=(NearbyDevice&&) = default; - NearbyDevice(const NearbyDevice&) = delete; - NearbyDevice& operator=(const NearbyDevice&) = delete; virtual std::string GetEndpointId() const = 0; // We will be adding more ConnectionInfo types to this variant as they are // implemented. diff --git a/internal/interop/device_provider.h b/internal/interop/device_provider.h index a622601dc2..828b261311 100644 --- a/internal/interop/device_provider.h +++ b/internal/interop/device_provider.h @@ -22,10 +22,13 @@ namespace nearby { // The base device provider class for use with the Nearby Connections V3 APIs. // This class currently provides a function to get the local device for whatever // client implements it. +template ::value>::type* = nullptr> class NearbyDeviceProvider { + public: virtual ~NearbyDeviceProvider() = default; - virtual NearbyDevice* GetLocalDevice() = 0; + const virtual T& GetLocalDevice() = 0; }; } // namespace nearby diff --git a/internal/platform/BUILD b/internal/platform/BUILD index e8107092c6..ab66288cdf 100644 --- a/internal/platform/BUILD +++ b/internal/platform/BUILD @@ -348,6 +348,7 @@ cc_library( "//fastpair:__subpackages__", "//internal/base:__subpackages__", "//internal/flags:__subpackages__", + "//internal/interop:__pkg__", "//internal/platform/implementation/windows:__subpackages__", "//internal/preferences:__subpackages__", "//internal/test:__subpackages__", diff --git a/presence/BUILD b/presence/BUILD index 55b534a416..d416aee1c0 100644 --- a/presence/BUILD +++ b/presence/BUILD @@ -23,11 +23,14 @@ cc_library( ], hdrs = [ "presence_client.h", + "presence_device_provider.h", "presence_service.h", ], deps = [ ":types", + "//internal/interop:device", "//internal/platform:types", + "//internal/proto:metadata_cc_proto", "//presence/implementation:internal", # build_cleaner: keep "@com_google_absl//absl/status", "@com_google_absl//absl/status:statusor", @@ -64,6 +67,7 @@ cc_library( "//internal/interop:device", "//internal/platform:connection_info", "//internal/platform:logging", + "//internal/platform:types", "//internal/platform/implementation:types", "//internal/proto:credential_cc_proto", "//internal/proto:metadata_cc_proto", @@ -138,6 +142,7 @@ cc_test( size = "small", srcs = [ "presence_client_test.cc", + "presence_device_provider_test.cc", "presence_service_test.cc", ], shard_count = 6, @@ -145,8 +150,11 @@ cc_test( ":presence", ":types", "//internal/platform:test_util", + "//internal/platform:types", + "//internal/proto:metadata_cc_proto", "@com_github_protobuf_matchers//protobuf-matchers", "@com_google_absl//absl/status", + "@com_google_absl//absl/strings", "@com_google_googletest//:gtest_main", ] + select({ "//tools/cc_target_os:windows": [ diff --git a/presence/implementation/service_controller.h b/presence/implementation/service_controller.h index ead85a23c0..ab04172843 100644 --- a/presence/implementation/service_controller.h +++ b/presence/implementation/service_controller.h @@ -19,6 +19,7 @@ #include #include "absl/status/statusor.h" +#include "internal/proto/metadata.pb.h" #include "presence/broadcast_request.h" #include "presence/data_types.h" #include "presence/scan_request.h" diff --git a/presence/implementation/service_controller_impl.h b/presence/implementation/service_controller_impl.h index 48ea26240f..6233b772a2 100644 --- a/presence/implementation/service_controller_impl.h +++ b/presence/implementation/service_controller_impl.h @@ -20,6 +20,7 @@ #include #include "absl/status/statusor.h" +#include "internal/proto/metadata.pb.h" #include "presence/implementation/broadcast_manager.h" #include "presence/implementation/credential_manager_impl.h" #include "presence/implementation/mediums/mediums.h" @@ -52,6 +53,7 @@ class ServiceControllerImpl : public ServiceController { const std::vector& identity_types, int credential_life_cycle_days, int contiguous_copy_of_credentials, GenerateCredentialsResultCallback credentials_generated_cb) override; + ::nearby::internal::Metadata GetLocalDeviceMetadata() override { return credential_manager_.GetLocalDeviceMetadata(); } diff --git a/presence/presence_client.cc b/presence/presence_client.cc index 3241848659..b011590e88 100644 --- a/presence/presence_client.cc +++ b/presence/presence_client.cc @@ -14,13 +14,13 @@ #include "presence/presence_client.h" -#include +#include #include -#include #include "absl/status/status.h" #include "internal/platform/borrowable.h" #include "internal/platform/logging.h" +#include "presence/presence_device.h" #include "presence/presence_service.h" namespace nearby { @@ -62,5 +62,13 @@ void PresenceClient::StopBroadcast(BroadcastSessionId session_id) { } } +std::optional PresenceClient::GetLocalDevice() { + ::nearby::Borrowed borrowed = service_.Borrow(); + if (borrowed) { + return (*borrowed)->GetLocalDeviceProvider()->GetLocalDevice(); + } + return std::nullopt; +} + } // namespace presence } // namespace nearby diff --git a/presence/presence_client.h b/presence/presence_client.h index 23b7079131..16845b47c7 100644 --- a/presence/presence_client.h +++ b/presence/presence_client.h @@ -23,6 +23,7 @@ #include "internal/platform/borrowable.h" #include "presence/broadcast_request.h" #include "presence/data_types.h" +#include "presence/presence_device.h" #include "presence/scan_request.h" namespace nearby { @@ -78,6 +79,11 @@ class PresenceClient { // terminated. void StopBroadcast(BroadcastSessionId session_id); + // Returns the local PresenceDevice describing the current device's actions, + // connectivity info and unique identifier for use in Connections and + // Presence. + std::optional GetLocalDevice(); + private: BorrowablePresenceService service_; }; diff --git a/presence/presence_client_test.cc b/presence/presence_client_test.cc index 2403ad15cd..9a4585cd19 100644 --- a/presence/presence_client_test.cc +++ b/presence/presence_client_test.cc @@ -20,14 +20,18 @@ #include "absl/status/status.h" #include "internal/platform/medium_environment.h" #include "presence/data_types.h" +#include "presence/presence_device.h" #include "presence/presence_service.h" namespace nearby { namespace presence { namespace { +using ::nearby::internal::Metadata; using ::testing::status::StatusIs; +constexpr absl::string_view kMacAddr = "\x4C\x8B\x1D\xCE\xBA\xD1"; + // Creates a PresenceClient and destroys PresenceService that was used to create // it. PresenceClient CreateDefunctPresenceClient() { @@ -35,6 +39,17 @@ PresenceClient CreateDefunctPresenceClient() { return presence_service.CreatePresenceClient(); } +Metadata CreateTestMetadata() { + Metadata metadata; + metadata.set_device_type(internal::DEVICE_TYPE_PHONE); + metadata.set_account_name("test_account"); + metadata.set_device_name("NP test device"); + metadata.set_user_name("Test user"); + metadata.set_device_profile_url("test_image.test.com"); + metadata.set_bluetooth_mac_address(kMacAddr); + return metadata; +} + class PresenceClientTest : public testing::Test { protected: nearby::MediumEnvironment& env_{nearby::MediumEnvironment::Instance()}; @@ -104,6 +119,23 @@ TEST_F(PresenceClientTest, StartScanFailsWhenPresenceServiceIsGone) { env_.Stop(); } +TEST_F(PresenceClientTest, GettingDeviceWorks) { + PresenceService presence_service; + PresenceClient presence_client = presence_service.CreatePresenceClient(); + presence_service.UpdateLocalDeviceMetadata(CreateTestMetadata(), false, "", + {}, 0, 0, {}); + auto device = presence_client.GetLocalDevice(); + ASSERT_NE(device, std::nullopt); + EXPECT_EQ(device->GetEndpointId().length(), kEndpointIdLength); + EXPECT_EQ(device->GetMetadata().SerializeAsString(), + CreateTestMetadata().SerializeAsString()); +} + +TEST_F(PresenceClientTest, TestGettingDeviceDefunct) { + PresenceClient presence_client = CreateDefunctPresenceClient(); + auto device = presence_client.GetLocalDevice(); + EXPECT_EQ(device, std::nullopt); +} } // namespace } // namespace presence } // namespace nearby diff --git a/presence/presence_device.h b/presence/presence_device.h index b4455c2a9f..3d56b5db60 100644 --- a/presence/presence_device.h +++ b/presence/presence_device.h @@ -60,12 +60,13 @@ class PresenceDevice : public nearby::NearbyDevice { const override; DeviceMotion GetDeviceMotion() const { return device_motion_; } Metadata GetMetadata() const { return metadata_; } + void SetMetadata(const Metadata metadata) { metadata_ = metadata; } absl::Time GetDiscoveryTimestamp() const { return discovery_timestamp_; } private: const absl::Time discovery_timestamp_; const DeviceMotion device_motion_; - const Metadata metadata_; + Metadata metadata_; std::vector extended_properties_; std::vector actions_; std::string endpoint_id_; @@ -77,7 +78,9 @@ class PresenceDevice : public nearby::NearbyDevice { inline bool operator==(const PresenceDevice& d1, const PresenceDevice& d2) { return d1.GetDeviceMotion() == d2.GetDeviceMotion() && d1.GetMetadata().SerializeAsString() == - d2.GetMetadata().SerializeAsString(); + d2.GetMetadata().SerializeAsString() && + d1.GetActions() == d2.GetActions() && + d1.GetExtendedProperties() == d2.GetExtendedProperties(); } inline bool operator!=(const PresenceDevice& d1, const PresenceDevice& d2) { diff --git a/presence/presence_device_provider.h b/presence/presence_device_provider.h new file mode 100644 index 0000000000..45be14c80d --- /dev/null +++ b/presence/presence_device_provider.h @@ -0,0 +1,42 @@ +// 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_PRESENCE_PRESENCE_DEVICE_PROVIDER_H_ +#define THIRD_PARTY_NEARBY_PRESENCE_PRESENCE_DEVICE_PROVIDER_H_ + +#include "internal/interop/device_provider.h" +#include "internal/proto/metadata.proto.h" +#include "presence/presence_device.h" + +namespace nearby { +namespace presence { + +class PresenceDeviceProvider : public NearbyDeviceProvider { + public: + explicit PresenceDeviceProvider(::nearby::internal::Metadata metadata) + : device_{metadata} {} + + const PresenceDevice& GetLocalDevice() override { return device_; } + + void UpdateMetadata(const ::nearby::internal::Metadata& metadata) { + device_.SetMetadata(metadata); + } + + private: + PresenceDevice device_; +}; +} // namespace presence +} // namespace nearby + +#endif // THIRD_PARTY_NEARBY_PRESENCE_PRESENCE_DEVICE_PROVIDER_H_ diff --git a/presence/presence_device_provider_test.cc b/presence/presence_device_provider_test.cc new file mode 100644 index 0000000000..cf7b3e228a --- /dev/null +++ b/presence/presence_device_provider_test.cc @@ -0,0 +1,72 @@ +// 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 "presence/presence_device_provider.h" + +#include + +#include "gmock/gmock.h" +#include "protobuf-matchers/protocol-buffer-matchers.h" +#include "gtest/gtest.h" +#include "absl/strings/string_view.h" +#include "internal/proto/metadata.pb.h" +#include "internal/proto/metadata.proto.h" +#include "presence/presence_device.h" + +namespace nearby { +namespace presence { +namespace { +using ::nearby::internal::Metadata; + +constexpr absl::string_view kMacAddr = "\x4C\x8B\x1D\xCE\xBA\xD1"; + +Metadata CreateTestMetadata() { + Metadata metadata; + metadata.set_device_type(internal::DEVICE_TYPE_PHONE); + metadata.set_account_name("test_account"); + metadata.set_device_name("NP test device"); + metadata.set_user_name("Test user"); + metadata.set_device_profile_url("test_image.test.com"); + metadata.set_bluetooth_mac_address(kMacAddr); + return metadata; +} + +TEST(PresenceDeviceProviderTest, ProviderIsNotTriviallyConstructible) { + EXPECT_FALSE(std::is_trivially_constructible::value); +} + +TEST(PresenceDeviceProviderTest, DeviceProviderWorks) { + PresenceDeviceProvider provider(CreateTestMetadata()); + auto device = provider.GetLocalDevice(); + EXPECT_EQ(device.GetMetadata().SerializeAsString(), + CreateTestMetadata().SerializeAsString()); +} + +TEST(PresenceDeviceProviderTest, DeviceProviderCanUpdateDevice) { + PresenceDeviceProvider provider(CreateTestMetadata()); + auto device = provider.GetLocalDevice(); + EXPECT_EQ(device.GetMetadata().SerializeAsString(), + CreateTestMetadata().SerializeAsString()); + Metadata new_metadata = CreateTestMetadata(); + new_metadata.set_device_name("NP interop device"); + provider.UpdateMetadata(new_metadata); + EXPECT_NE(device.GetMetadata().SerializeAsString(), + new_metadata.SerializeAsString()); + EXPECT_EQ(provider.GetLocalDevice().GetMetadata().SerializeAsString(), + new_metadata.SerializeAsString()); +} + +} // namespace +} // namespace presence +} // namespace nearby diff --git a/presence/presence_service.cc b/presence/presence_service.cc index e4d4c3b856..5fee126860 100644 --- a/presence/presence_service.cc +++ b/presence/presence_service.cc @@ -24,7 +24,9 @@ namespace nearby { namespace presence { PresenceService::PresenceService() { - this->service_controller_ = std::make_unique(); + service_controller_ = std::make_unique(); + provider_ = std::make_unique( + service_controller_->GetLocalDeviceMetadata()); } PresenceClient PresenceService::CreatePresenceClient() { @@ -35,6 +37,7 @@ absl::StatusOr PresenceService::StartScan( ScanRequest scan_request, ScanCallback callback) { return service_controller_->StartScan(scan_request, std::move(callback)); } + void PresenceService::StopScan(ScanSessionId id) { service_controller_->StopScan(id); } diff --git a/presence/presence_service.h b/presence/presence_service.h index 651776e80b..d86b8d0925 100644 --- a/presence/presence_service.h +++ b/presence/presence_service.h @@ -20,9 +20,11 @@ #include #include "internal/platform/borrowable.h" +#include "internal/proto/metadata.proto.h" #include "presence/data_types.h" #include "presence/implementation/service_controller.h" #include "presence/presence_client.h" +#include "presence/presence_device_provider.h" namespace nearby { namespace presence { @@ -54,12 +56,16 @@ class PresenceService { const std::vector& identity_types, int credential_life_cycle_days, int contiguous_copy_of_credentials, GenerateCredentialsResultCallback credentials_generated_cb) { + provider_->UpdateMetadata(metadata); service_controller_->UpdateLocalDeviceMetadata( metadata, regen_credentials, manager_app_id, identity_types, credential_life_cycle_days, contiguous_copy_of_credentials, std::move(credentials_generated_cb)); } + PresenceDeviceProvider* GetLocalDeviceProvider() { return provider_.get(); } + + // Testing only. ::nearby::internal::Metadata GetLocalDeviceMetadata() { return service_controller_->GetLocalDeviceMetadata(); } @@ -67,6 +73,7 @@ class PresenceService { private: std::unique_ptr service_controller_; ::nearby::Lender lender_{this}; + std::unique_ptr provider_; }; } // namespace presence diff --git a/presence/presence_service_test.cc b/presence/presence_service_test.cc index b80035ca63..564754d1b0 100644 --- a/presence/presence_service_test.cc +++ b/presence/presence_service_test.cc @@ -78,6 +78,11 @@ TEST_F(PresenceServiceTest, UpdatingLocalMetadataWorks) { CreateTestMetadata("Test account").SerializeAsString()); } +TEST_F(PresenceServiceTest, TestGetDeviceProvider) { + PresenceService presence_service; + EXPECT_NE(presence_service.GetLocalDeviceProvider(), nullptr); +} + } // namespace } // namespace presence } // namespace nearby