diff --git a/internal/platform/BUILD b/internal/platform/BUILD index 43986d0f..d4a87284 100644 --- a/internal/platform/BUILD +++ b/internal/platform/BUILD @@ -156,6 +156,7 @@ cc_library( "//connections:__subpackages__", "//internal:__pkg__", "//internal/platform/implementation:__subpackages__", + "//presence:__subpackages__", ], deps = [ "//internal/platform:base", diff --git a/presence/BUILD b/presence/BUILD index 5320ac53..2a81cac9 100644 --- a/presence/BUILD +++ b/presence/BUILD @@ -63,9 +63,12 @@ cc_library( deps = [ "//internal/platform:base", "//internal/platform:logging", + "//internal/platform/implementation:types", "//internal/proto:credential_cc_proto", + "//internal/proto:device_metadata_cc_proto", "@com_google_absl//absl/functional:any_invocable", "@com_google_absl//absl/strings", + "@com_google_absl//absl/time", "@com_google_absl//absl/types:optional", "@com_google_absl//absl/types:variant", ], @@ -91,9 +94,9 @@ cc_test( ":types", "//internal/platform/implementation/g3", # build_cleaner: keep "//internal/proto:credential_cc_proto", + "//internal/proto:device_metadata_cc_proto", "@com_github_protobuf_matchers//protobuf-matchers", "@com_google_absl//absl/strings", - "@com_google_absl//absl/types:variant", "@com_google_googletest//:gtest_main", ], ) diff --git a/presence/implementation/BUILD b/presence/implementation/BUILD index f388d0b6..1974847b 100644 --- a/presence/implementation/BUILD +++ b/presence/implementation/BUILD @@ -221,6 +221,7 @@ cc_test( "//presence/implementation/mediums", "@com_github_protobuf_matchers//protobuf-matchers", "@com_google_absl//absl/random", + "@com_google_absl//absl/time", "@com_google_googletest//:gtest_main", ], ) diff --git a/presence/implementation/scan_manager.cc b/presence/implementation/scan_manager.cc index ea7a7511..1e130766 100644 --- a/presence/implementation/scan_manager.cc +++ b/presence/implementation/scan_manager.cc @@ -102,7 +102,7 @@ std::unique_ptr ScanManager::StartScan(ScanRequest scan_request, void ScanManager::NotifyFoundBle(BleAdvertisementData data, const BlePeripheral& peripheral) { - std::vector callbacks; + std::vector> callbacks; { absl::MutexLock lock(&mutex_); auto advertisement_data = @@ -115,14 +115,17 @@ void ScanManager::NotifyFoundBle(BleAdvertisementData data, continue; } if (candidate.decoder.MatchesScanFilter(advert.value())) { - callbacks.push_back(candidate.callback); + std::string bt_addr = peripheral.GetAddress(); + DeviceMetadata metadata; + metadata.set_bluetooth_mac_address(bt_addr); + callbacks.push_back({candidate.callback, metadata}); } } } // TODO(b/256913915): Provide more information in PresenceDevice once fully // implemented for (const auto& callback : callbacks) { - callback.on_discovered_cb(PresenceDevice()); + callback.first.on_discovered_cb(PresenceDevice(callback.second)); } } diff --git a/presence/implementation/scan_manager_test.cc b/presence/implementation/scan_manager_test.cc index 5428dc45..1c30f8ca 100644 --- a/presence/implementation/scan_manager_test.cc +++ b/presence/implementation/scan_manager_test.cc @@ -26,8 +26,10 @@ #include "protobuf-matchers/protocol-buffer-matchers.h" #include "gtest/gtest.h" #include "absl/random/random.h" +#include "absl/time/time.h" #include "internal/platform/bluetooth_adapter.h" #include "internal/platform/count_down_latch.h" +#include "internal/platform/logging.h" #include "internal/platform/medium_environment.h" #include "presence/implementation/advertisement_factory.h" #include "presence/implementation/base_broadcast_request.h" @@ -176,6 +178,43 @@ TEST_F(ScanManagerTest, TestNoFilter) { EXPECT_EQ(manager.ScanningCallbacksLengthForTest(), 0); } +TEST_F(ScanManagerTest, PresenceDeviceMetadataIsRetained) { + Mediums mediums; + ScanManager manager(mediums, credential_manager_); + // Set up advertiser + location::nearby::BluetoothAdapter server_adapter; + Ble ble2(server_adapter); + std::unique_ptr advertising_session = + StartAdvertisingOn(ble2); + std::string address = server_adapter.GetMacAddress(); + ScanCallback callback = { + .start_scan_cb = + [this](Status status) { + if (status.Ok()) { + start_latch_.CountDown(); + } + }, + .on_discovered_cb = + [this, &address](PresenceDevice pd) { + if (pd.GetMetadata().has_bluetooth_mac_address() && + pd.GetMetadata().bluetooth_mac_address() == address) { + found_latch_.CountDown(); + } + }}; + // Start scanning + ScanRequest scan_request_no_filter = MakeDefaultScanRequest(); + scan_request_no_filter.scan_filters.clear(); + auto scan_session = + manager.StartScan(scan_request_no_filter, callback); + + ASSERT_EQ(manager.ScanningCallbacksLengthForTest(), 1); + ASSERT_TRUE(mediums.GetBle().IsAvailable()); + EXPECT_TRUE(start_latch_.Await().Ok()); + EXPECT_TRUE(found_latch_.Await(absl::Milliseconds(1000)).result()); + EXPECT_TRUE(scan_session->StopScan().Ok()); + EXPECT_EQ(manager.ScanningCallbacksLengthForTest(), 0); +} + TEST_F(ScanManagerTest, StopOneSessionFromAnotherDeadlock) { Mediums mediums; ScanManager manager(mediums, credential_manager_); diff --git a/presence/presence_device.cc b/presence/presence_device.cc index 1c603b4f..cf84b563 100644 --- a/presence/presence_device.cc +++ b/presence/presence_device.cc @@ -14,14 +14,21 @@ #include "presence/presence_device.h" +#include "internal/platform/implementation/system_clock.h" #include "presence/device_motion.h" namespace nearby { namespace presence { -PresenceDevice::PresenceDevice() noexcept : device_motion_(DeviceMotion()) {} -PresenceDevice::PresenceDevice(DeviceMotion device_motion) noexcept - : device_motion_(device_motion) {} +PresenceDevice::PresenceDevice(DeviceMetadata device_metadata) noexcept + : discovery_timestamp_(location::nearby::SystemClock::ElapsedRealtime()), + device_motion_(DeviceMotion()), + device_metadata_(device_metadata) {} +PresenceDevice::PresenceDevice(DeviceMotion device_motion, + DeviceMetadata device_metadata) noexcept + : discovery_timestamp_(location::nearby::SystemClock::ElapsedRealtime()), + device_motion_(device_motion), + device_metadata_(device_metadata) {} } // namespace presence } // namespace nearby diff --git a/presence/presence_device.h b/presence/presence_device.h index 509b3b44..17babb00 100644 --- a/presence/presence_device.h +++ b/presence/presence_device.h @@ -15,22 +15,39 @@ #ifndef THIRD_PARTY_NEARBY_PRESENCE_PRESENCE_DEVICE_H_ #define THIRD_PARTY_NEARBY_PRESENCE_PRESENCE_DEVICE_H_ +#include + +#include "absl/time/time.h" +#include "internal/proto/device_metadata.pb.h" #include "presence/device_motion.h" namespace nearby { namespace presence { + +using nearby::internal::DeviceMetadata; + class PresenceDevice { public: - PresenceDevice() noexcept; - explicit PresenceDevice(DeviceMotion device_motion) noexcept; + explicit PresenceDevice(DeviceMetadata metadata) noexcept; + explicit PresenceDevice(DeviceMotion device_motion, + DeviceMetadata metadata) noexcept; DeviceMotion GetDeviceMotion() const { return device_motion_; } + DeviceMetadata GetMetadata() const { return device_metadata_; } + absl::Time GetDiscoveryTimestamp() const { return discovery_timestamp_; } private: + const absl::Time discovery_timestamp_; const DeviceMotion device_motion_; + const DeviceMetadata device_metadata_; }; +// Timestamp is not used for equality since if the same device is discovered +// twice, they will have different timestamps and thus will show up as two +// different devices when they are the same device. inline bool operator==(const PresenceDevice& d1, const PresenceDevice& d2) { - return d1.GetDeviceMotion() == d2.GetDeviceMotion(); + return d1.GetDeviceMotion() == d2.GetDeviceMotion() && + d1.GetMetadata().SerializeAsString() == + d2.GetMetadata().SerializeAsString(); } inline bool operator!=(const PresenceDevice& d1, const PresenceDevice& d2) { diff --git a/presence/presence_device_test.cc b/presence/presence_device_test.cc index 4a2aca15..2e956fae 100644 --- a/presence/presence_device_test.cc +++ b/presence/presence_device_test.cc @@ -17,6 +17,7 @@ #include "gmock/gmock.h" #include "protobuf-matchers/protocol-buffer-matchers.h" #include "gtest/gtest.h" +#include "internal/proto/device_metadata.proto.h" namespace nearby { namespace presence { @@ -25,36 +26,47 @@ constexpr DeviceMotion::MotionType kDefaultMotionType = DeviceMotion::MotionType::kPointAndHold; constexpr float kDefaultConfidence = 0; constexpr float kTestConfidence = 0.1; -TEST(PresenceDeviceTest, DefaultConstructorWorks) { - PresenceDevice device; - DeviceMotion device_motion; - EXPECT_EQ(device.GetDeviceMotion(), device_motion); +constexpr absl::string_view kMacAddr = "\x4C\x8B\x1D\xCE\xBA\xD1"; + +DeviceMetadata CreateTestDeviceMetadata() { + DeviceMetadata device_metadata; + device_metadata.set_stable_device_id("test_device_id"); + device_metadata.set_account_name("test_account"); + device_metadata.set_device_name("NP test device"); + device_metadata.set_icon_url("test_image.test.com"); + device_metadata.set_bluetooth_mac_address(kMacAddr); + device_metadata.set_device_type(internal::DeviceMetadata::PHONE); + return device_metadata; } -TEST(PresenceDeviceTest, DefaultEquals) { - PresenceDevice device1; - PresenceDevice device2; +TEST(PresenceDeviceTest, DefaultMotionEquals) { + DeviceMetadata metadata = CreateTestDeviceMetadata(); + PresenceDevice device1(metadata); + PresenceDevice device2(metadata); EXPECT_EQ(device1, device2); } TEST(PresenceDeviceTest, ExplicitInitEquals) { + DeviceMetadata metadata = CreateTestDeviceMetadata(); PresenceDevice device1 = - PresenceDevice({kDefaultMotionType, kTestConfidence}); + PresenceDevice({kDefaultMotionType, kTestConfidence}, metadata); PresenceDevice device2 = - PresenceDevice({kDefaultMotionType, kTestConfidence}); + PresenceDevice({kDefaultMotionType, kTestConfidence}, metadata); EXPECT_EQ(device1, device2); } TEST(PresenceDeviceTest, ExplicitInitNotEquals) { - PresenceDevice device1 = PresenceDevice({kDefaultMotionType}); + DeviceMetadata metadata = CreateTestDeviceMetadata(); + PresenceDevice device1 = PresenceDevice({kDefaultMotionType}, metadata); PresenceDevice device2 = - PresenceDevice({kDefaultMotionType, kTestConfidence}); + PresenceDevice({kDefaultMotionType, kTestConfidence}, metadata); EXPECT_NE(device1, device2); } TEST(PresenceDeviceTest, CopyInitEquals) { + DeviceMetadata metadata = CreateTestDeviceMetadata(); PresenceDevice device1 = - PresenceDevice({kDefaultMotionType, kTestConfidence}); + PresenceDevice({kDefaultMotionType, kTestConfidence}, metadata); PresenceDevice device2 = {device1}; EXPECT_EQ(device1, device2); }