Merge branch 'google:main' into main

This commit is contained in:
Lasan Mahaliyana
2026-03-07 00:16:27 +05:30
committed by GitHub
155 changed files with 2631 additions and 1881 deletions
+3 -3
View File
@@ -3,10 +3,10 @@
{
"identity" : "abseil-cpp-swiftpm",
"kind" : "remoteSourceControl",
"location" : "https://github.com/firebase/abseil-cpp-SwiftPM.git",
"location" : "https://github.com/bourdakos1/abseil-cpp-SwiftPM.git",
"state" : {
"branch" : "main",
"revision" : "1c50c2cd0bffe5a03cde6fe17129334dcf05071b"
"branch" : "jan-lts",
"revision" : "ecabd65f38702137240fd2599f710b0f5cd89cf1"
}
},
{
+2 -2
View File
@@ -40,8 +40,8 @@ let package = Package(
dependencies: [
// Dependencies declare other packages that this package depends on.
.package(
url: "https://github.com/firebase/abseil-cpp-SwiftPM.git",
branch: "main"
url: "https://github.com/bourdakos1/abseil-cpp-SwiftPM.git",
branch: "jan-lts"
),
.package(
url: "https://github.com/firebase/boringssl-SwiftPM.git",
+16 -8
View File
@@ -138,11 +138,12 @@ void Core::RequestConnection(absl::string_view endpoint_id,
<< "Client request connection with keep-alive frame as interval="
<< connection_options.keep_alive_interval_millis
<< ", timeout=" << connection_options.keep_alive_timeout_millis
<< ", which is un-expected. Change to default.",
connection_options.keep_alive_interval_millis =
FeatureFlags::GetInstance().GetFlags().keep_alive_interval_millis;
<< ", which is un-expected. Change to default.";
FeatureFlags::Flags flags = FeatureFlags::GetInstance().GetFlags();
connection_options.keep_alive_interval_millis =
flags.keep_alive_interval_millis;
connection_options.keep_alive_timeout_millis =
FeatureFlags::GetInstance().GetFlags().keep_alive_timeout_millis;
flags.keep_alive_timeout_millis;
}
router_->RequestConnection(&client_, endpoint_id, info, connection_options,
@@ -208,6 +209,11 @@ void Core::SetCustomSavePath(absl::string_view path, ResultCallback callback) {
router_->SetCustomSavePath(&client_, path, std::move(callback));
}
void Core::OverrideSavePath(absl::string_view endpoint_id,
absl::string_view path) {
client_.OverrideSavePath(endpoint_id, path);
}
std::string Core::Dump() { return client_.Dump(); }
// V3
@@ -402,10 +408,11 @@ void Core::RequestConnectionV3(const NearbyDevice& local_device,
<< connection_options.keep_alive_interval_millis
<< ", timeout=" << connection_options.keep_alive_timeout_millis
<< ", which is un-expected. Change to default.";
FeatureFlags::Flags flags = FeatureFlags::GetInstance().GetFlags();
connection_options.keep_alive_interval_millis =
FeatureFlags::GetInstance().GetFlags().keep_alive_interval_millis;
flags.keep_alive_interval_millis;
connection_options.keep_alive_timeout_millis =
FeatureFlags::GetInstance().GetFlags().keep_alive_timeout_millis;
flags.keep_alive_timeout_millis;
}
router_->RequestConnectionV3(&client_, remote_device, std::move(info),
connection_options, std::move(result_cb));
@@ -435,10 +442,11 @@ void Core::RequestConnectionV3(const NearbyDevice& remote_device,
<< connection_options.keep_alive_interval_millis
<< ", timeout=" << connection_options.keep_alive_timeout_millis
<< ", which is un-expected. Change to default.";
FeatureFlags::Flags flags = FeatureFlags::GetInstance().GetFlags();
connection_options.keep_alive_interval_millis =
FeatureFlags::GetInstance().GetFlags().keep_alive_interval_millis;
flags.keep_alive_interval_millis;
connection_options.keep_alive_timeout_millis =
FeatureFlags::GetInstance().GetFlags().keep_alive_timeout_millis;
flags.keep_alive_timeout_millis;
}
router_->RequestConnectionV3(&client_, remote_device, std::move(info),
connection_options, std::move(result_cb));
+2 -2
View File
@@ -19,7 +19,6 @@
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "absl/strings/string_view.h"
#include "absl/types/span.h"
@@ -29,7 +28,6 @@
#include "connections/implementation/client_proxy.h"
#include "connections/implementation/service_controller_router.h"
#include "connections/listeners.h"
#include "connections/medium_selector.h"
#include "connections/out_of_band_connection_metadata.h"
#include "connections/params.h"
#include "connections/payload.h"
@@ -254,6 +252,8 @@ class Core {
//
// path - The path where the received files will be saved to.
void SetCustomSavePath(absl::string_view path, ResultCallback callback);
// Override the save path for payloads from a specific endpoint.
void OverrideSavePath(absl::string_view endpoint_id, absl::string_view path);
// Gets the local endpoint generated by Nearby Connections.
std::string GetLocalEndpointId() { return client_.GetLocalEndpointId(); }
@@ -27,54 +27,54 @@
namespace nearby::connections::dart {
NC_INSTANCE NearbyConnectionsClientState::GetOpennedService() const {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
return opened_instance_;
}
void NearbyConnectionsClientState::SetOpennedService(NC_INSTANCE nc_instance) {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
opened_instance_ = nc_instance;
}
DiscoveryListenerDart*
NearbyConnectionsClientState::GetDiscoveryListenerDart() {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
return discovery_listener_dart_.get();
}
void NearbyConnectionsClientState::SetDiscoveryListenerDart(
std::unique_ptr<DiscoveryListenerDart> discovery_listener_dart) {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
discovery_listener_dart_ = std::move(discovery_listener_dart);
}
ConnectionListenerDart*
NearbyConnectionsClientState::GetConnectionListenerDart() {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
return connection_listener_dart_.get();
}
void NearbyConnectionsClientState::SetConnectionListenerDart(
std::unique_ptr<ConnectionListenerDart> connection_listener_dart) {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
connection_listener_dart_ = std::move(connection_listener_dart);
}
PayloadListenerDart* NearbyConnectionsClientState::GetPayloadListenerDart() {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
return payload_listener_dart_.get();
}
void NearbyConnectionsClientState::SetPayloadListenerDart(
std::unique_ptr<PayloadListenerDart> payload_listener_dart) {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
payload_listener_dart_ = std::move(payload_listener_dart);
}
std::optional<Dart_Port>
NearbyConnectionsClientState::PopNearbyConnectionsApiPort(
NearbyConnectionsApi api) {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
std::deque<Dart_Port>& port_list = nearby_connections_api_ports_[api];
if (port_list.empty()) {
return std::nullopt;
@@ -87,13 +87,13 @@ NearbyConnectionsClientState::PopNearbyConnectionsApiPort(
void NearbyConnectionsClientState::PushNearbyConnectionsApiPort(
NearbyConnectionsApi api, Dart_Port dart_port) {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
std::deque<Dart_Port>& port_list = nearby_connections_api_ports_[api];
port_list.push_back(dart_port);
}
void NearbyConnectionsClientState::reset() {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
opened_instance_ = nullptr;
nearby_connections_api_ports_.clear();
discovery_listener_dart_.reset();
+1 -1
View File
@@ -227,7 +227,6 @@ cc_library(
"//connections:core_types",
"//connections/implementation/analytics",
"//connections/implementation/flags:connections_flags",
"//connections/implementation/mediums",
"//connections/v3:v3_types",
"//internal/flags:nearby_flags",
"//internal/interop:device",
@@ -583,6 +582,7 @@ cc_test(
"//internal/platform/implementation/g3", # build_cleaner: keep
"@com_github_protobuf_matchers//protobuf-matchers",
"@com_google_absl//absl/strings:string_view",
"@com_google_absl//absl/time",
"@com_google_googletest//:gtest_main",
],
)
@@ -158,7 +158,7 @@ class BaseEndpointChannel : public EndpointChannel {
// An encryptor/decryptor. May be null.
mutable Mutex crypto_mutex_;
std::shared_ptr<EncryptionContext> crypto_context_
ABSL_GUARDED_BY(crypto_mutex_) ABSL_PT_GUARDED_BY(crypto_mutex_);
ABSL_GUARDED_BY(crypto_mutex_);
mutable Mutex is_paused_mutex_;
ConditionVariable is_paused_cond_{&is_paused_mutex_};
@@ -2052,11 +2052,12 @@ Exception BasePcpHandler::OnIncomingConnection(
LOG(WARNING) << "Incoming connection has wrong keep-alive frame interval="
<< connection_options.keep_alive_interval_millis
<< ", timeout=" << connection_options.keep_alive_timeout_millis
<< " values; correct them as default.",
connection_options.keep_alive_interval_millis =
FeatureFlags::GetInstance().GetFlags().keep_alive_interval_millis;
<< " values; correct them as default.";
FeatureFlags::Flags flags = FeatureFlags::GetInstance().GetFlags();
connection_options.keep_alive_interval_millis =
flags.keep_alive_interval_millis;
connection_options.keep_alive_timeout_millis =
FeatureFlags::GetInstance().GetFlags().keep_alive_timeout_millis;
flags.keep_alive_timeout_millis;
}
const MediumMetadata& medium_metadata = connection_request.medium_metadata();
@@ -21,8 +21,8 @@
#include "absl/strings/escaping.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "connections/implementation/base_pcp_handler.h"
#include "connections/implementation/pcp.h"
#include "connections/implementation/webrtc_state.h"
#include "internal/platform/base64_utils.h"
#include "internal/platform/byte_array.h"
#include "internal/platform/logging.h"
@@ -58,6 +58,14 @@ BluetoothDeviceName::BluetoothDeviceName(Version version, Pcp pcp,
endpoint_info_ = endpoint_info;
uwb_address_ = uwb_address;
web_rtc_state_ = web_rtc_state;
if (endpoint_info_.size() > kMaxEndpointInfoLength) {
LOG(INFO)
<< "While constructing bluetooth device name, truncating Endpoint Info "
<< absl::BytesToHexString(std::string(endpoint_info_)) << " ("
<< endpoint_info_.size() << " bytes) down to " << kMaxEndpointInfoLength
<< " bytes";
endpoint_info_ = ByteArray(endpoint_info_.data(), kMaxEndpointInfoLength);
}
}
BluetoothDeviceName::BluetoothDeviceName(
@@ -154,6 +162,14 @@ BluetoothDeviceName::BluetoothDeviceName(
return;
}
endpoint_info_ = *endpoint_info_bytes;
if (endpoint_info_.size() > kMaxEndpointInfoLength) {
LOG(INFO) << "While deserializing bluetooth device name, truncating "
"Endpoint Info "
<< absl::BytesToHexString(std::string(endpoint_info_)) << " ("
<< endpoint_info_.size() << " bytes) down to "
<< kMaxEndpointInfoLength << " bytes";
endpoint_info_ = ByteArray(endpoint_info_.data(), kMaxEndpointInfoLength);
}
// If the input stream has extra bytes, it's for UWB address. The first byte
// is the address length. It can be 2-byte short address or 8-byte extended
@@ -203,23 +219,14 @@ BluetoothDeviceName::operator std::string() const {
ByteArray reserved_bytes{kReservedLength};
ByteArray usable_endpoint_info(endpoint_info_);
if (endpoint_info_.size() > kMaxEndpointInfoLength) {
LOG(INFO) << "While serializing Advertisement, truncating Endpoint Name "
<< absl::BytesToHexString(endpoint_info_.data()) << " ("
<< endpoint_info_.size() << " bytes) down to "
<< kMaxEndpointInfoLength << " bytes";
usable_endpoint_info.SetData(endpoint_info_.data(), kMaxEndpointInfoLength);
}
// clang-format off
std::string out = absl::StrCat(std::string(1, version_and_pcp_byte),
endpoint_id_,
std::string(service_id_hash_),
std::string(1, field_byte),
std::string(reserved_bytes),
std::string(1, usable_endpoint_info.size()),
std::string(usable_endpoint_info));
std::string(1, endpoint_info_.size()),
std::string(endpoint_info_));
// clang-format on
// If UWB address is available, attach it at the end.
@@ -18,8 +18,8 @@
#include <string>
#include "absl/strings/string_view.h"
#include "connections/implementation/base_pcp_handler.h"
#include "connections/implementation/pcp.h"
#include "connections/implementation/webrtc_state.h"
#include "internal/platform/byte_array.h"
namespace nearby {
@@ -80,7 +80,6 @@ class BluetoothDeviceName {
std::string endpoint_id_;
ByteArray service_id_hash_;
ByteArray endpoint_info_;
// TODO(b/169550050): Define UWB address field.
ByteArray uwb_address_;
WebRtcState web_rtc_state_{WebRtcState::kUndefined};
};
@@ -14,11 +14,12 @@
#include "connections/implementation/bluetooth_device_name.h"
#include <cstring>
#include <memory>
#include <string>
#include "gtest/gtest.h"
#include "absl/strings/string_view.h"
#include "connections/implementation/pcp.h"
#include "connections/implementation/webrtc_state.h"
#include "internal/platform/base64_utils.h"
#include "internal/platform/byte_array.h"
@@ -29,138 +30,217 @@ namespace {
constexpr BluetoothDeviceName::Version kVersion =
BluetoothDeviceName::Version::kV1;
constexpr Pcp kPcp = Pcp::kP2pCluster;
constexpr absl::string_view kEndPointID{"AB12"};
constexpr absl::string_view kServiceIDHashBytes{"\x0a\x0b\x0c"};
constexpr absl::string_view kEndPointName{"RAWK + ROWL!"};
constexpr absl::string_view kEndpointId = "ABCD";
constexpr absl::string_view kServiceIdHash = "ABC";
constexpr absl::string_view kEndpointInfo = "GG";
constexpr WebRtcState kWebRtcState = WebRtcState::kConnectable;
constexpr int kMaxEndpointInfoLength = 131;
// TODO(b/169550050): Implement UWBAddress.
TEST(BluetoothDeviceNameTest, ConstructionWorks) {
ByteArray service_id_hash{std::string(kServiceIDHashBytes)};
ByteArray endpoint_info{std::string(kEndPointName)};
BluetoothDeviceName bluetooth_device_name{
kVersion, kPcp, kEndPointID, service_id_hash,
endpoint_info, ByteArray{}, kWebRtcState};
EXPECT_TRUE(bluetooth_device_name.IsValid());
EXPECT_EQ(kVersion, bluetooth_device_name.GetVersion());
EXPECT_EQ(kPcp, bluetooth_device_name.GetPcp());
EXPECT_EQ(kEndPointID, bluetooth_device_name.GetEndpointId());
EXPECT_EQ(service_id_hash, bluetooth_device_name.GetServiceIdHash());
EXPECT_EQ(endpoint_info, bluetooth_device_name.GetEndpointInfo());
EXPECT_EQ(kWebRtcState, bluetooth_device_name.GetWebRtcState());
}
TEST(BluetoothDeviceNameTest, ConstructionWorksWithEmptyEndpointName) {
ByteArray empty_endpoint_info;
ByteArray service_id_hash{std::string(kServiceIDHashBytes)};
TEST(BluetoothDeviceNameTest, ConstructionWithUwbAddress) {
ByteArray service_id_hash{std::string(kServiceIdHash)};
ByteArray endpoint_info{std::string(kEndpointInfo)};
ByteArray uwb_address{{0x01, 0x02}};
BluetoothDeviceName bluetooth_device_name{kVersion,
kPcp,
kEndPointID,
kEndpointId,
service_id_hash,
empty_endpoint_info,
ByteArray{},
endpoint_info,
uwb_address,
kWebRtcState};
EXPECT_TRUE(bluetooth_device_name.IsValid());
EXPECT_EQ(kVersion, bluetooth_device_name.GetVersion());
EXPECT_EQ(kPcp, bluetooth_device_name.GetPcp());
EXPECT_EQ(kEndPointID, bluetooth_device_name.GetEndpointId());
EXPECT_EQ(service_id_hash, bluetooth_device_name.GetServiceIdHash());
EXPECT_EQ(empty_endpoint_info, bluetooth_device_name.GetEndpointInfo());
EXPECT_EQ(kWebRtcState, bluetooth_device_name.GetWebRtcState());
EXPECT_EQ(bluetooth_device_name.GetVersion(), kVersion);
EXPECT_EQ(bluetooth_device_name.GetPcp(), kPcp);
EXPECT_EQ(bluetooth_device_name.GetEndpointId(), kEndpointId);
EXPECT_EQ(bluetooth_device_name.GetServiceIdHash(), service_id_hash);
EXPECT_EQ(bluetooth_device_name.GetEndpointInfo(), endpoint_info);
EXPECT_EQ(bluetooth_device_name.GetUwbAddress(), uwb_address);
EXPECT_EQ(bluetooth_device_name.GetWebRtcState(), kWebRtcState);
}
TEST(BluetoothDeviceNameTest, DeserializationWithUwbAddress) {
ByteArray service_id_hash{std::string(kServiceIdHash)};
ByteArray endpoint_info{std::string(kEndpointInfo)};
ByteArray uwb_address{{0x01, 0x02}};
BluetoothDeviceName bluetooth_device_name{kVersion,
kPcp,
kEndpointId,
service_id_hash,
endpoint_info,
uwb_address,
kWebRtcState};
std::string bluetooth_device_name_string = std::string(bluetooth_device_name);
BluetoothDeviceName bluetooth_device_name_from_string(
bluetooth_device_name_string);
EXPECT_TRUE(bluetooth_device_name_from_string.IsValid());
EXPECT_EQ(bluetooth_device_name_from_string.GetVersion(), kVersion);
EXPECT_EQ(bluetooth_device_name_from_string.GetPcp(), kPcp);
EXPECT_EQ(bluetooth_device_name_from_string.GetEndpointId(), kEndpointId);
EXPECT_EQ(bluetooth_device_name_from_string.GetServiceIdHash(),
service_id_hash);
EXPECT_EQ(bluetooth_device_name_from_string.GetEndpointInfo(), endpoint_info);
EXPECT_EQ(bluetooth_device_name_from_string.GetUwbAddress(), uwb_address);
EXPECT_EQ(bluetooth_device_name_from_string.GetWebRtcState(), kWebRtcState);
}
TEST(BluetoothDeviceNameTest,
ConstructionWithEmptyUwbAddressAndEmptyEndpointName) {
ByteArray service_id_hash{std::string(kServiceIdHash)};
ByteArray empty_endpoint_info;
ByteArray uwb_address;
BluetoothDeviceName bluetooth_device_name{kVersion,
kPcp,
kEndpointId,
service_id_hash,
empty_endpoint_info,
uwb_address,
kWebRtcState};
EXPECT_TRUE(bluetooth_device_name.IsValid());
EXPECT_EQ(bluetooth_device_name.GetVersion(), kVersion);
EXPECT_EQ(bluetooth_device_name.GetPcp(), kPcp);
EXPECT_EQ(bluetooth_device_name.GetEndpointId(), kEndpointId);
EXPECT_EQ(bluetooth_device_name.GetServiceIdHash(), service_id_hash);
EXPECT_TRUE(bluetooth_device_name.GetEndpointInfo().Empty());
EXPECT_TRUE(bluetooth_device_name.GetUwbAddress().Empty());
EXPECT_EQ(bluetooth_device_name.GetWebRtcState(), kWebRtcState);
}
TEST(BluetoothDeviceNameTest, ConstructionFailsWithBadVersion) {
auto bad_version = static_cast<BluetoothDeviceName::Version>(666);
ByteArray service_id_hash{std::string(kServiceIDHashBytes)};
ByteArray endpoint_info{std::string(kEndPointName)};
BluetoothDeviceName bluetooth_device_name{
bad_version, kPcp, kEndPointID, service_id_hash,
endpoint_info, ByteArray{}, kWebRtcState};
ByteArray service_id_hash{std::string(kServiceIdHash)};
ByteArray endpoint_info{std::string(kEndpointInfo)};
ByteArray uwb_address;
BluetoothDeviceName bluetooth_device_name{bad_version,
kPcp,
kEndpointId,
service_id_hash,
endpoint_info,
uwb_address,
kWebRtcState};
EXPECT_FALSE(bluetooth_device_name.IsValid());
}
TEST(BluetoothDeviceNameTest, ConstructionFailsWithBadPcp) {
auto bad_pcp = static_cast<Pcp>(666);
ByteArray service_id_hash{std::string(kServiceIDHashBytes)};
ByteArray endpoint_info{std::string(kEndPointName)};
BluetoothDeviceName bluetooth_device_name{
kVersion, bad_pcp, kEndPointID, service_id_hash,
endpoint_info, ByteArray{}, kWebRtcState};
ByteArray service_id_hash{std::string(kServiceIdHash)};
ByteArray endpoint_info{std::string(kEndpointInfo)};
BluetoothDeviceName bluetooth_device_name{kVersion,
bad_pcp,
kEndpointId,
service_id_hash,
endpoint_info,
ByteArray{},
kWebRtcState};
EXPECT_FALSE(bluetooth_device_name.IsValid());
}
TEST(BluetoothDeviceNameTest, ConstructionFailsWithShortEndpointId) {
std::string short_endpoint_id("AB1");
ByteArray service_id_hash{std::string(kServiceIDHashBytes)};
ByteArray endpoint_info{std::string(kEndPointName)};
BluetoothDeviceName bluetooth_device_name{
kVersion, kPcp, short_endpoint_id, service_id_hash,
endpoint_info, ByteArray{}, kWebRtcState};
TEST(BluetoothDeviceNameTest, ConstructionFailsWithBadEndpointIdLength) {
ByteArray service_id_hash{std::string(kServiceIdHash)};
ByteArray endpoint_info{std::string(kEndpointInfo)};
ByteArray uwb_address;
BluetoothDeviceName bluetooth_device_name{kVersion,
kPcp,
"1",
service_id_hash,
endpoint_info,
uwb_address,
kWebRtcState};
EXPECT_FALSE(bluetooth_device_name.IsValid());
}
TEST(BluetoothDeviceNameTest, ConstructionFailsWithLongEndpointId) {
std::string long_endpoint_id("AB12X");
ByteArray service_id_hash{std::string(kServiceIDHashBytes)};
ByteArray endpoint_info{std::string(kEndPointName)};
BluetoothDeviceName bluetooth_device_name{
kVersion, kPcp, long_endpoint_id, service_id_hash,
endpoint_info, ByteArray{}, kWebRtcState};
TEST(BluetoothDeviceNameTest, ConstructionFailsWithBadServiceIdHashLength) {
ByteArray service_id_hash{"12"};
ByteArray endpoint_info{std::string(kEndpointInfo)};
ByteArray uwb_address;
BluetoothDeviceName bluetooth_device_name{kVersion,
kPcp,
kEndpointId,
service_id_hash,
endpoint_info,
uwb_address,
kWebRtcState};
EXPECT_FALSE(bluetooth_device_name.IsValid());
}
TEST(BluetoothDeviceNameTest, ConstructionFailsWithShortServiceIdHash) {
char short_service_id_hash_bytes[] = "\x0a\x0b";
ByteArray short_service_id_hash{short_service_id_hash_bytes};
ByteArray endpoint_info{std::string(kEndPointName)};
BluetoothDeviceName bluetooth_device_name{
kVersion, kPcp, kEndPointID, short_service_id_hash,
endpoint_info, ByteArray{}, kWebRtcState};
TEST(BluetoothDeviceNameTest, DeserializationFailsWithBadInput) {
BluetoothDeviceName bluetooth_device_name{"bad input"};
EXPECT_FALSE(bluetooth_device_name.IsValid());
}
TEST(BluetoothDeviceNameTest, ConstructionFailsWithLongServiceIdHash) {
char long_service_id_hash_bytes[] = "\x0a\x0b\x0c\x0d";
ByteArray long_service_id_hash{long_service_id_hash_bytes};
ByteArray endpoint_info{std::string(kEndPointName)};
TEST(BluetoothDeviceNameTest, DeserializationFailsWithShortInput) {
BluetoothDeviceName bluetooth_device_name{
kVersion, kPcp, kEndPointID, long_service_id_hash,
endpoint_info, ByteArray{}, kWebRtcState};
Base64Utils::Encode(ByteArray{"1"})};
EXPECT_FALSE(bluetooth_device_name.IsValid());
}
TEST(BluetoothDeviceNameTest, ConstructionFailsWithShortStringLength) {
char bluetooth_device_name_string[] = "X";
TEST(BluetoothDeviceNameTest, EndpointInfoTruncation) {
ByteArray service_id_hash{std::string(kServiceIdHash)};
std::string long_endpoint_info_string(150, 'a');
ByteArray endpoint_info{long_endpoint_info_string};
ByteArray uwb_address;
BluetoothDeviceName bluetooth_device_name{kVersion,
kPcp,
kEndpointId,
service_id_hash,
endpoint_info,
uwb_address,
kWebRtcState};
EXPECT_EQ(bluetooth_device_name.GetEndpointInfo().size(),
kMaxEndpointInfoLength);
ByteArray bluetooth_device_name_bytes{bluetooth_device_name_string};
BluetoothDeviceName bluetooth_device_name{
Base64Utils::Encode(bluetooth_device_name_bytes)};
std::string bluetooth_device_name_string = std::string(bluetooth_device_name);
EXPECT_FALSE(bluetooth_device_name.IsValid());
BluetoothDeviceName bluetooth_device_name_from_string(
bluetooth_device_name_string);
EXPECT_TRUE(bluetooth_device_name_from_string.IsValid());
EXPECT_EQ(bluetooth_device_name_from_string.GetEndpointInfo(),
bluetooth_device_name.GetEndpointInfo());
EXPECT_EQ(bluetooth_device_name_from_string.GetEndpointInfo().size(),
kMaxEndpointInfoLength);
}
TEST(BluetoothDeviceNameTest, DeserializationFailsWithBadVersion) {
// version=7, pcp=1
ByteArray bytes(
"\xE1"
"234567890123456",
16);
BluetoothDeviceName device_name(Base64Utils::Encode(bytes));
EXPECT_FALSE(device_name.IsValid());
}
TEST(BluetoothDeviceNameTest, DeserializationFailsWithBadPcp) {
// version=1, pcp=31
ByteArray bytes(
"\x3F"
"234567890123456",
16);
BluetoothDeviceName device_name(Base64Utils::Encode(bytes));
EXPECT_FALSE(device_name.IsValid());
}
TEST(BluetoothDeviceNameTest, InvalidToString) {
BluetoothDeviceName device_name;
EXPECT_TRUE(std::string(device_name).empty());
EXPECT_FALSE(device_name.IsValid());
}
TEST(BluetoothDeviceNameTest, ConstructionFailsWithWrongEndpointNameLength) {
// Serialize good data into a good Bluetooth Device Name.
ByteArray service_id_hash{std::string(kServiceIDHashBytes)};
ByteArray endpoint_info{std::string(kEndPointName)};
BluetoothDeviceName bluetooth_device_name{
kVersion, kPcp, kEndPointID, service_id_hash,
endpoint_info, ByteArray{}, kWebRtcState};
ByteArray service_id_hash{std::string(kServiceIdHash)};
ByteArray endpoint_info{std::string(kEndpointInfo)};
BluetoothDeviceName bluetooth_device_name{kVersion,
kPcp,
kEndpointId,
service_id_hash,
endpoint_info,
ByteArray{},
kWebRtcState};
auto bluetooth_device_name_string = std::string(bluetooth_device_name);
// Base64-decode the good Bluetooth Device Name.
@@ -182,26 +262,6 @@ TEST(BluetoothDeviceNameTest, ConstructionFailsWithWrongEndpointNameLength) {
EXPECT_FALSE(corrupt_bluetooth_device_name.IsValid());
}
TEST(BluetoothDeviceNameTest, CanParseGeneratedName) {
ByteArray service_id_hash{std::string(kServiceIDHashBytes)};
ByteArray endpoint_info{std::string(kEndPointName)};
// Build name1 from scratch.
BluetoothDeviceName name1{kVersion, kPcp, kEndPointID,
service_id_hash, endpoint_info, ByteArray{},
kWebRtcState};
// Build name2 from string composed from name1.
BluetoothDeviceName name2{std::string(name1)};
EXPECT_TRUE(name1.IsValid());
EXPECT_TRUE(name2.IsValid());
EXPECT_EQ(name1.GetVersion(), name2.GetVersion());
EXPECT_EQ(name1.GetPcp(), name2.GetPcp());
EXPECT_EQ(name1.GetEndpointId(), name2.GetEndpointId());
EXPECT_EQ(name1.GetServiceIdHash(), name2.GetServiceIdHash());
EXPECT_EQ(name1.GetEndpointInfo(), name2.GetEndpointInfo());
EXPECT_EQ(name1.GetWebRtcState(), name2.GetWebRtcState());
}
} // namespace
} // namespace connections
} // namespace nearby
+5 -8
View File
@@ -83,22 +83,19 @@ BwuManager::BwuManager(
mediums_(&mediums),
endpoint_manager_(&endpoint_manager),
channel_manager_(&channel_manager) {
FeatureFlags::Flags flags = FeatureFlags::GetInstance().GetFlags();
if (config_.bandwidth_upgrade_retry_delay == absl::ZeroDuration()) {
if (FeatureFlags::GetInstance().GetFlags().use_exp_backoff_in_bwu_retry) {
if (flags.use_exp_backoff_in_bwu_retry) {
config_.bandwidth_upgrade_retry_delay =
FeatureFlags::GetInstance()
.GetFlags()
.bwu_retry_exp_backoff_initial_delay;
flags.bwu_retry_exp_backoff_initial_delay;
} else {
config_.bandwidth_upgrade_retry_delay = absl::Seconds(5);
}
}
if (config_.bandwidth_upgrade_retry_max_delay == absl::ZeroDuration()) {
if (FeatureFlags::GetInstance().GetFlags().use_exp_backoff_in_bwu_retry) {
if (flags.use_exp_backoff_in_bwu_retry) {
config_.bandwidth_upgrade_retry_max_delay =
FeatureFlags::GetInstance()
.GetFlags()
.bwu_retry_exp_backoff_maximum_delay;
flags.bwu_retry_exp_backoff_maximum_delay;
} else {
config_.bandwidth_upgrade_retry_max_delay = absl::Seconds(10);
}
+18 -15
View File
@@ -120,6 +120,13 @@ class BwuManagerTest : public ::testing::Test {
~BwuManagerTest() override { bwu_manager_->Shutdown(); }
void SetSupportMultipleBwuMediums(bool support_multiple_bwu_mediums) {
FeatureFlags& feature_flags = FeatureFlags::GetMutableInstanceForTesting();
FeatureFlags::Flags flags = feature_flags.GetFlags();
flags.support_multiple_bwu_mediums = support_multiple_bwu_mediums;
feature_flags.SetFlags(flags);
}
// Create the initial device-to-device connection, before bandwidth upgrade.
// Typically |medium| will be Bluetooth.
FakeEndpointChannel* CreateInitialEndpoint(ClientProxy* client,
@@ -315,8 +322,7 @@ class BwuManagerTestParam : public BwuManagerTest,
public ::testing::WithParamInterface<bool> {
protected:
BwuManagerTestParam() {
FeatureFlags::GetMutableFlagsForTesting().support_multiple_bwu_mediums =
GetParam();
SetSupportMultipleBwuMediums(GetParam());
}
};
@@ -475,7 +481,7 @@ TEST_P(BwuManagerTestParam,
TEST_F(BwuManagerTest,
InitiateBwu_Revert_OnDisconnect_MultipleEndpoints_FlagEnabled) {
FeatureFlags::GetMutableFlagsForTesting().support_multiple_bwu_mediums = true;
SetSupportMultipleBwuMediums(true);
// Say we have two already upgraded WebRTC connections for the same service.
CreateInitialEndpoint(&client_, kServiceIdA, kEndpointId1, Medium::BLUETOOTH);
@@ -524,8 +530,7 @@ TEST_F(BwuManagerTest,
TEST_F(BwuManagerTest,
InitiateBwu_Revert_OnDisconnect_MultipleEndpoints_FlagDisabled) {
FeatureFlags::GetMutableFlagsForTesting().support_multiple_bwu_mediums =
false;
SetSupportMultipleBwuMediums(false);
// Say we have two already upgraded WebRTC connections for the same service.
CreateInitialEndpoint(&client_, kServiceIdA, kEndpointId1, Medium::BLUETOOTH);
@@ -581,7 +586,7 @@ TEST_F(BwuManagerTest,
TEST_F(BwuManagerTest,
InitiateBwu_Revert_OnDisconnect_MultipleServices_FlagEnabled) {
FeatureFlags::GetMutableFlagsForTesting().support_multiple_bwu_mediums = true;
SetSupportMultipleBwuMediums(true);
// Say we have two already upgraded WLAN connections for different services.
CreateInitialEndpoint(&client_, kServiceIdA, kEndpointId1, Medium::BLUETOOTH);
@@ -635,8 +640,7 @@ TEST_F(BwuManagerTest,
TEST_F(BwuManagerTest,
InitiateBwu_Revert_OnDisconnect_MultipleServices_FlagDisabled) {
FeatureFlags::GetMutableFlagsForTesting().support_multiple_bwu_mediums =
false;
SetSupportMultipleBwuMediums(false);
// Say we have two already upgraded WLAN connections for different services.
CreateInitialEndpoint(&client_, kServiceIdA, kEndpointId1, Medium::BLUETOOTH);
@@ -694,7 +698,7 @@ TEST_F(
BwuManagerTest,
InitiateBwu_Revert_OnDisconnect_MultipleServicesAndEndpoints_FlagEnabled) {
// Need support_multiple_bwu_mediums_ to run this test with multiple mediums.
FeatureFlags::GetMutableFlagsForTesting().support_multiple_bwu_mediums = true;
SetSupportMultipleBwuMediums(true);
// Say we have three upgraded connections for two different services and two
// different mediums.
@@ -843,7 +847,7 @@ TEST_F(
}
TEST_F(BwuManagerTest, InitiateBwu_Revert_OnUpgradeFailure_FlagEnabled) {
FeatureFlags::GetMutableFlagsForTesting().support_multiple_bwu_mediums = true;
SetSupportMultipleBwuMediums(true);
// Say we have two already upgraded WebRTC connections for service A.
CreateInitialEndpoint(&client_, kServiceIdA, kEndpointId1, Medium::BLUETOOTH);
@@ -880,8 +884,7 @@ TEST_F(BwuManagerTest, InitiateBwu_Revert_OnUpgradeFailure_FlagEnabled) {
}
TEST_F(BwuManagerTest, InitiateBwu_Revert_OnUpgradeFailure_FlagDisabled) {
FeatureFlags::GetMutableFlagsForTesting().support_multiple_bwu_mediums =
false;
SetSupportMultipleBwuMediums(false);
// Say we have two already upgraded WebRTC connections for service A.
CreateInitialEndpoint(&client_, kServiceIdA, kEndpointId1, Medium::BLUETOOTH);
@@ -917,7 +920,7 @@ TEST_F(BwuManagerTest, InitiateBwu_Revert_OnUpgradeFailure_FlagDisabled) {
}
TEST_F(BwuManagerTest, InitiateBwu_Revert_OnDisconnect_WifiDirect) {
FeatureFlags::GetMutableFlagsForTesting().support_multiple_bwu_mediums = true;
SetSupportMultipleBwuMediums(true);
OfflineFrame frame;
CreateInitialEndpoint(&client_, kServiceIdA, kEndpointId1, Medium::BLUETOOTH);
@@ -951,7 +954,7 @@ TEST_F(BwuManagerTest, InitiateBwu_Revert_OnDisconnect_WifiDirect) {
}
TEST_F(BwuManagerTest, InitiateBwu_Revert_OnDisconnect_Hotspot) {
FeatureFlags::GetMutableFlagsForTesting().support_multiple_bwu_mediums = true;
SetSupportMultipleBwuMediums(true);
CreateInitialEndpoint(&client_, kServiceIdA, kEndpointId1, Medium::BLUETOOTH);
@@ -981,7 +984,7 @@ TEST_F(BwuManagerTest, InitiateBwu_Revert_OnDisconnect_Hotspot) {
}
TEST_F(BwuManagerTest, InitiateBwu_Revert_OnDisconnect_Wlan) {
FeatureFlags::GetMutableFlagsForTesting().support_multiple_bwu_mediums = true;
SetSupportMultipleBwuMediums(true);
CreateInitialEndpoint(&client_, kServiceIdA, kEndpointId1, Medium::BLUETOOTH);
@@ -196,6 +196,27 @@ std::string ClientProxy::GetConnectionToken(const std::string& endpoint_id) {
return {};
}
bool ClientProxy::OverrideSavePath(absl::string_view endpoint_id,
absl::string_view path) {
MutexLock lock(&mutex_);
ConnectionPair* item = LookupConnection(endpoint_id);
if (item != nullptr) {
item->first.save_path = path;
return true;
}
return false;
}
std::string ClientProxy::GetSavePath(
absl::string_view endpoint_id) const {
MutexLock lock(&mutex_);
const ConnectionPair* item = LookupConnection(endpoint_id);
if (item != nullptr) {
return item->first.save_path;
}
return "";
}
std::optional<MacAddress> ClientProxy::GetBluetoothMacAddress(
const std::string& endpoint_id) {
auto item = bluetooth_mac_addresses_.find(endpoint_id);
@@ -77,6 +77,13 @@ class ClientProxy final {
std::string GetLocalEndpointId();
std::string GetLocalEndpointInfo() { return local_endpoint_info_; }
// Override the base for received file attachments from a specific endpoint.
// Returns true if the endpoint is found and the path is overridden.
bool OverrideSavePath(absl::string_view endpoint_id, absl::string_view path);
// Get the save path for a specific endpoint. Returns empty string if
// not set.
std::string GetSavePath(absl::string_view endpoint_id) const;
analytics::AnalyticsRecorder& GetAnalyticsRecorder() const {
return *analytics_recorder_;
}
@@ -394,6 +401,7 @@ class ClientProxy final {
std::optional<location::nearby::connections::OsInfo> os_info;
std::int32_t safe_to_disconnect_version;
std::int32_t remote_multiplex_socket_bitmask;
std::string save_path;
};
using ConnectionPair = std::pair<Connection, PayloadListener>;
@@ -21,7 +21,6 @@
#include <utility>
#include <vector>
#include "base/casts.h"
#include "gmock/gmock.h"
#include "protobuf-matchers/protocol-buffer-matchers.h"
#include "gtest/gtest.h"
@@ -65,6 +64,7 @@ using ::location::nearby::connections::OsInfo;
using ::location::nearby::proto::connections::CLIENT_SESSION;
using ::location::nearby::proto::connections::START_CLIENT_SESSION;
using ::location::nearby::proto::connections::STOP_CLIENT_SESSION;
using ::testing::IsEmpty;
using ::testing::MockFunction;
using ::testing::StrictMock;
@@ -1400,9 +1400,7 @@ TEST_F(ClientProxyTest, GetLocalDeviceWorksWithDeviceProvider) {
MockDeviceProvider provider;
client1()->RegisterDeviceProvider(&provider);
ASSERT_NE(client1()->GetLocalDeviceProvider(), nullptr);
EXPECT_CALL(*(absl::down_cast<MockDeviceProvider*>(
client1()->GetLocalDeviceProvider())),
GetLocalDevice);
EXPECT_CALL(provider, GetLocalDevice);
client1()->GetLocalDevice();
}
@@ -1612,6 +1610,23 @@ TEST_F(ClientProxyTest, NotLoadClientInfoFromPreferencesOnExpired) {
false);
}
TEST_F(ClientProxyTest, OverrideSavePath) {
Endpoint advertising_endpoint =
StartAdvertising(client1(), advertising_connection_listener_);
OnAdvertisingConnectionInitiated(client1(), advertising_endpoint);
client1()->OverrideSavePath(advertising_endpoint.id, "/tmp/test_path");
EXPECT_EQ(client1()->GetSavePath(advertising_endpoint.id), "/tmp/test_path");
}
TEST_F(ClientProxyTest, GetSavePathDefaultsToEmpty) {
Endpoint advertising_endpoint =
StartAdvertising(client1(), advertising_connection_listener_);
OnAdvertisingConnectionInitiated(client1(), advertising_endpoint);
EXPECT_THAT(client1()->GetSavePath(advertising_endpoint.id), IsEmpty());
}
} // namespace
} // namespace connections
} // namespace nearby
@@ -41,6 +41,8 @@ namespace {
using ::location::nearby::proto::connections::Medium;
constexpr size_t kChunkSize = 64 * 1024;
constexpr securegcm::UKey2Handshake::HandshakeCipher kCipher =
securegcm::UKey2Handshake::HandshakeCipher::P256_SHA512;
class FakeEndpointChannel : public EndpointChannel {
public:
@@ -166,6 +168,7 @@ TEST(EncryptionRunnerTest, ReadWrite) {
.on_failure_cb =
[&response](const std::string& endpoint_id,
EndpointChannel* channel) {
channel->Close();
response.server_status = Response::Status::kFailed;
response.latch.CountDown();
},
@@ -184,6 +187,7 @@ TEST(EncryptionRunnerTest, ReadWrite) {
.on_failure_cb =
[&response](const std::string& endpoint_id,
EndpointChannel* channel) {
channel->Close();
response.client_status = Response::Status::kFailed;
response.latch.CountDown();
},
@@ -193,6 +197,235 @@ TEST(EncryptionRunnerTest, ReadWrite) {
EXPECT_EQ(response.client_status, Response::Status::kDone);
}
TEST(EncryptionRunnerTest, ClientWriteFails) {
auto from_a_to_b = CreatePipe();
auto from_b_to_a = CreatePipe();
User user_a(/*reader=*/from_b_to_a.first.get(),
/*writer=*/from_a_to_b.second.get());
User user_b(/*reader=*/from_a_to_b.first.get(),
/*writer=*/from_b_to_a.second.get());
Response response;
response.latch = CountDownLatch(1);
// Close server's input stream, so client can't write to it.
from_b_to_a.first->Close();
user_b.crypto.StartClient(
&user_b.client, "endpoint_id", &user_b.channel,
{
.on_success_cb =
[&response](const std::string& endpoint_id,
std::unique_ptr<securegcm::UKey2Handshake> ukey2,
const std::string& auth_token,
const ByteArray& raw_auth_token) {
response.client_status = Response::Status::kDone;
response.latch.CountDown();
},
.on_failure_cb =
[&response](const std::string& endpoint_id,
EndpointChannel* channel) {
channel->Close();
response.client_status = Response::Status::kFailed;
response.latch.CountDown();
},
});
EXPECT_TRUE(response.latch.Await(absl::Milliseconds(5000)).result());
EXPECT_EQ(response.client_status, Response::Status::kFailed);
}
TEST(EncryptionRunnerTest, ServerWriteFails) {
auto from_a_to_b = CreatePipe();
auto from_b_to_a = CreatePipe();
User user_a(/*reader=*/from_b_to_a.first.get(),
/*writer=*/from_a_to_b.second.get());
User user_b(/*reader=*/from_a_to_b.first.get(),
/*writer=*/from_b_to_a.second.get());
Response response;
response.latch = CountDownLatch(1);
// Close client's input stream, so server can't write to it.
from_a_to_b.first->Close();
user_a.crypto.StartServer(
&user_a.client, "endpoint_id", &user_a.channel,
{
.on_success_cb =
[&response](const std::string& endpoint_id,
std::unique_ptr<securegcm::UKey2Handshake> ukey2,
const std::string& auth_token,
const ByteArray& raw_auth_token) {
response.server_status = Response::Status::kDone;
response.latch.CountDown();
},
.on_failure_cb =
[&response](const std::string& endpoint_id,
EndpointChannel* channel) {
channel->Close();
response.server_status = Response::Status::kFailed;
response.latch.CountDown();
},
});
user_b.crypto.StartClient(
&user_b.client, "endpoint_id", &user_b.channel,
{
.on_success_cb =
[](const std::string& endpoint_id,
std::unique_ptr<securegcm::UKey2Handshake> ukey2,
const std::string& auth_token,
const ByteArray& raw_auth_token) {},
.on_failure_cb =
[](const std::string& endpoint_id, EndpointChannel* channel) {
channel->Close();
},
});
EXPECT_TRUE(response.latch.Await(absl::Milliseconds(5000)).result());
EXPECT_EQ(response.server_status, Response::Status::kFailed);
}
TEST(EncryptionRunnerTest, ClientSendsGarbageMessage1) {
auto from_server_to_client = CreatePipe();
auto from_client_to_server = CreatePipe();
User user_a(/*reader=*/from_client_to_server.first.get(),
/*writer=*/from_server_to_client.second.get());
Response response;
response.latch = CountDownLatch(1);
user_a.crypto.StartServer(
&user_a.client, "endpoint_id", &user_a.channel,
{
.on_success_cb =
[&response](const std::string& endpoint_id,
std::unique_ptr<securegcm::UKey2Handshake> ukey2,
const std::string& auth_token,
const ByteArray& raw_auth_token) {
response.server_status = Response::Status::kDone;
response.latch.CountDown();
},
.on_failure_cb =
[&response](const std::string& endpoint_id,
EndpointChannel* channel) {
channel->Close();
response.server_status = Response::Status::kFailed;
response.latch.CountDown();
},
});
// Client writes garbage instead of message 1
from_client_to_server.second->Write("Garbage");
EXPECT_TRUE(response.latch.Await(absl::Milliseconds(5000)).result());
EXPECT_EQ(response.server_status, Response::Status::kFailed);
// Check if server sent alert message.
// The alert message should be readable from from_server_to_client.first.
auto alert = from_server_to_client.first->Read(kChunkSize);
EXPECT_TRUE(alert.ok());
EXPECT_FALSE(alert.result().Empty());
}
TEST(EncryptionRunnerTest, ServerSendsGarbageMessage2) {
auto from_server_to_client = CreatePipe();
auto from_client_to_server = CreatePipe();
User user_b(/*reader=*/from_server_to_client.first.get(),
/*writer=*/from_client_to_server.second.get());
Response response;
response.latch = CountDownLatch(1);
user_b.crypto.StartClient(
&user_b.client, "endpoint_id", &user_b.channel,
{
.on_success_cb =
[&response](const std::string& endpoint_id,
std::unique_ptr<securegcm::UKey2Handshake> ukey2,
const std::string& auth_token,
const ByteArray& raw_auth_token) {
response.client_status = Response::Status::kDone;
response.latch.CountDown();
},
.on_failure_cb =
[&response](const std::string& endpoint_id,
EndpointChannel* channel) {
channel->Close();
response.client_status = Response::Status::kFailed;
response.latch.CountDown();
},
});
// Client sends message 1.
auto client_init = from_client_to_server.first->Read(kChunkSize);
EXPECT_TRUE(client_init.ok());
// Server writes garbage instead of message 2.
from_server_to_client.second->Write("Garbage");
EXPECT_TRUE(response.latch.Await(absl::Milliseconds(5000)).result());
EXPECT_EQ(response.client_status, Response::Status::kFailed);
// Check if client sent alert message.
auto alert = from_client_to_server.first->Read(kChunkSize);
EXPECT_TRUE(alert.ok());
EXPECT_FALSE(alert.result().Empty());
}
TEST(EncryptionRunnerTest, ClientSendsGarbageMessage3) {
auto from_server_to_client = CreatePipe();
auto from_client_to_server = CreatePipe();
User user_a(/*reader=*/from_client_to_server.first.get(),
/*writer=*/from_server_to_client.second.get());
User user_b(/*reader=*/from_server_to_client.first.get(),
/*writer=*/from_client_to_server.second.get());
Response response;
response.latch = CountDownLatch(1);
user_a.crypto.StartServer(
&user_a.client, "endpoint_id", &user_a.channel,
{
.on_success_cb =
[&response](const std::string& endpoint_id,
std::unique_ptr<securegcm::UKey2Handshake> ukey2,
const std::string& auth_token,
const ByteArray& raw_auth_token) {
response.server_status = Response::Status::kDone;
response.latch.CountDown();
},
.on_failure_cb =
[&response](const std::string& endpoint_id,
EndpointChannel* channel) {
channel->Close();
response.server_status = Response::Status::kFailed;
response.latch.CountDown();
},
});
// Client starts, sends message 1
std::unique_ptr<securegcm::UKey2Handshake> client_crypto =
securegcm::UKey2Handshake::ForInitiator(kCipher);
std::unique_ptr<std::string> client_init_str =
client_crypto->GetNextHandshakeMessage();
from_client_to_server.second->Write(
ByteArray(*client_init_str).AsStringView());
// Server reads message 1, sends message 2.
// Read message 2 from server
auto server_init = from_server_to_client.first->Read(kChunkSize);
EXPECT_TRUE(server_init.ok());
// Client crypto parses message 2.
client_crypto->ParseHandshakeMessage(std::string(server_init.result()));
// Client sends garbage instead of message 3
from_client_to_server.second->Write("Garbage");
EXPECT_TRUE(response.latch.Await(absl::Milliseconds(5000)).result());
EXPECT_EQ(response.server_status, Response::Status::kFailed);
// Check if server sent alert message.
// Message 3 doesn't send alert in current UKEY2 implementation.
auto alert = from_server_to_client.first->Read(kChunkSize);
EXPECT_TRUE(alert.ok());
EXPECT_TRUE(alert.result().Empty());
}
} // namespace
} // namespace connections
} // namespace nearby
@@ -813,9 +813,8 @@ bool EndpointManager::ApplySafeToDisconnect(const std::string& endpoint_id,
// TODO(b/303544913): clean up the safe-to-disconnect logic
bool is_safe_disconnection = false;
bool send_disconnection_frame = true;
absl::Duration timeout_millis = FeatureFlags::GetInstance()
.GetFlags()
.safe_to_disconnect_ack_delay_millis;
FeatureFlags::Flags flags = FeatureFlags::GetInstance().GetFlags();
absl::Duration timeout_millis = flags.safe_to_disconnect_ack_delay_millis;
bool is_wait_for_ack = true;
switch (reason) {
case DisconnectionReason::UPGRADED:
@@ -832,9 +831,7 @@ bool EndpointManager::ApplySafeToDisconnect(const std::string& endpoint_id,
case DisconnectionReason::REMOTE_DISCONNECTION:
is_safe_disconnection = true;
send_disconnection_frame = false;
timeout_millis = FeatureFlags::GetInstance()
.GetFlags()
.safe_to_disconnect_remote_disc_delay_millis;
timeout_millis = flags.safe_to_disconnect_remote_disc_delay_millis;
is_wait_for_ack = false;
break;
default:
@@ -137,6 +137,7 @@ class MockFrameProcessor : public EndpointManager::FrameProcessor {
class SetSafeToDisconnect {
public:
SetSafeToDisconnect(bool safe_to_disconnect, bool auto_reconnect,
bool payload_received_ack,
std::int32_t safe_to_disconnect_version) {
NearbyFlags::GetInstance().OverrideBoolFlagValue(
config_package_nearby::nearby_connections_feature::
@@ -145,6 +146,10 @@ class SetSafeToDisconnect {
NearbyFlags::GetInstance().OverrideBoolFlagValue(
config_package_nearby::nearby_connections_feature::kEnableAutoReconnect,
auto_reconnect);
NearbyFlags::GetInstance().OverrideBoolFlagValue(
config_package_nearby::nearby_connections_feature::
kEnablePayloadReceivedAck,
payload_received_ack);
NearbyFlags::GetInstance().OverrideInt64FlagValue(
config_package_nearby::nearby_connections_feature::
kSafeToDisconnectVersion,
@@ -182,9 +187,7 @@ class EndpointManagerTest : public ::testing::Test {
EXPECT_TRUE(done.Await(absl::Milliseconds(1000)).result());
}
}
SetSafeToDisconnect set_safe_to_disconnect_{/*safe_to_disconnect=*/true,
/*auto_reconnect=*/false,
/*safe_to_disconnect_version=*/5};
SetSafeToDisconnect set_safe_to_disconnect_{true, false, true, 5};
std::unique_ptr<ClientProxy> client_ = std::make_unique<ClientProxy>();
ConnectionOptions connection_options_{
.keep_alive_interval_millis = 5000,
@@ -77,6 +77,9 @@ constexpr auto kEnableNearbyConnectionsPreferences =
// Enable/Disable payload manager to skip chunk update.
constexpr auto kEnablePayloadManagerToSkipChunkUpdate =
flags::Flag<bool>(kConfigPackage, "45415729", true);
// Enable/Disable payload-received-ack feature.
constexpr auto kEnablePayloadReceivedAck =
flags::Flag<bool>(kConfigPackage, "45425840", false);
// Enable/Disable safe-to-disconnect feature.
constexpr auto kEnableSafeToDisconnect =
flags::Flag<bool>(kConfigPackage, "45425789", false);
@@ -46,6 +46,17 @@ namespace {
using ::location::nearby::connections::PayloadTransferFrame;
using ::location::nearby::proto::connections::OperationResultCode;
// if custom_save_path is empty, default download path is used
std::string make_path(const std::string& custom_save_path,
const std::string& parent_folder,
const std::string& file_name) {
if (!custom_save_path.empty()) {
std::string path = absl::StrCat(custom_save_path, "/", parent_folder);
return api::ImplementationPlatform::GetCustomSavePath(path, file_name);
}
return api::ImplementationPlatform::GetDownloadPath(parent_folder, file_name);
}
class BytesInternalPayload : public InternalPayload {
public:
explicit BytesInternalPayload(Payload payload)
@@ -338,27 +349,6 @@ ErrorOr<std::unique_ptr<InternalPayload>> CreateOutgoingInternalPayload(
}
}
// if custom_save_path is empty, default download path is used
std::string make_path(const std::string& custom_save_path,
std::string& parent_folder, std::string& file_name) {
if (!custom_save_path.empty()) {
std::string path = absl::StrCat(custom_save_path, "/", parent_folder);
return api::ImplementationPlatform::GetCustomSavePath(path, file_name);
}
return api::ImplementationPlatform::GetDownloadPath(parent_folder, file_name);
}
// if custom_save_path is empty, default download path is used
std::string make_path(const std::string& custom_save_path,
std::string& parent_folder, int64_t id) {
std::string file_name(std::to_string(id));
if (!custom_save_path.empty()) {
std::string path = absl::StrCat(custom_save_path, "/", parent_folder);
return api::ImplementationPlatform::GetCustomSavePath(path, file_name);
}
return api::ImplementationPlatform::GetDownloadPath(parent_folder, file_name);
}
ErrorOr<std::unique_ptr<InternalPayload>> CreateIncomingInternalPayload(
const location::nearby::connections::PayloadTransferFrame& frame,
const std::string& custom_save_path) {
@@ -14,6 +14,7 @@
#include "connections/implementation/internal_payload_factory.h"
#include <cmath>
#include <cstddef>
#include <cstdint>
#include <memory>
@@ -22,6 +23,8 @@
#include "gtest/gtest.h"
#include "absl/strings/string_view.h"
#include "absl/time/clock.h"
#include "absl/time/time.h"
#include "connections/implementation/internal_payload.h"
#include "connections/implementation/proto/offline_wire_formats.pb.h"
#include "connections/payload.h"
@@ -30,6 +33,7 @@
#include "internal/platform/exception.h"
#include "internal/platform/expected.h"
#include "internal/platform/file.h"
#include "internal/platform/input_stream.h"
#include "internal/platform/pipe.h"
namespace nearby {
@@ -82,7 +86,7 @@ TEST(InternalPayloadFactoryTest, CanCreateInternalPayloadFromFilePayload) {
TEST(InternalPayloadFactoryTest, CanCreateInternalPayloadFromByteMessage) {
PayloadTransferFrame frame;
std::string path = "C:\\Downloads";
std::string path = ::testing::TempDir();
frame.set_packet_type(PayloadTransferFrame::DATA);
std::int64_t payload_chunk_offset = 0;
ByteArray data(kText);
@@ -108,7 +112,7 @@ TEST(InternalPayloadFactoryTest, CanCreateInternalPayloadFromByteMessage) {
TEST(InternalPayloadFactoryTest, CanCreateInternalPayloadFromStreamMessage) {
PayloadTransferFrame frame;
std::string path = "C:\\Downloads";
std::string path = ::testing::TempDir();
frame.set_packet_type(PayloadTransferFrame::DATA);
auto& header = *frame.mutable_payload_header();
header.set_type(PayloadTransferFrame::PayloadHeader::STREAM);
@@ -133,7 +137,7 @@ TEST(InternalPayloadFactoryTest, CanCreateInternalPayloadFromStreamMessage) {
TEST(InternalPayloadFactoryTest, CanCreateInternalPayloadFromFileMessage) {
PayloadTransferFrame frame;
std::string path = "/tmp/Downloads";
std::string path = ::testing::TempDir();
frame.set_packet_type(PayloadTransferFrame::DATA);
auto& header = *frame.mutable_payload_header();
header.set_type(PayloadTransferFrame::PayloadHeader::FILE);
@@ -154,7 +158,7 @@ TEST(InternalPayloadFactoryTest, CanCreateInternalPayloadFromFileMessage) {
TEST(InternalPayloadFactoryTest,
InternalPayloadFromFileMessageWithoutIdReturnsNullptr) {
PayloadTransferFrame frame;
std::string path = "/tmp/Downloads";
std::string path = ::testing::TempDir();
frame.set_packet_type(PayloadTransferFrame::DATA);
auto& header = *frame.mutable_payload_header();
header.set_type(PayloadTransferFrame::PayloadHeader::FILE);
@@ -167,7 +171,7 @@ TEST(InternalPayloadFactoryTest,
TEST(InternalPayloadFactoryTest,
CanCreateInternalPayloadFromFileMessageWithFileNameNotSet) {
PayloadTransferFrame frame;
std::string path = "/tmp/Downloads";
std::string path = ::testing::TempDir();
frame.set_packet_type(PayloadTransferFrame::DATA);
auto& header = *frame.mutable_payload_header();
header.set_type(PayloadTransferFrame::PayloadHeader::FILE);
@@ -185,7 +189,7 @@ TEST(InternalPayloadFactoryTest,
TEST(InternalPayloadFactoryTest,
CanCreateInternalPayloadFromFileMessageWithFileNameSet) {
PayloadTransferFrame frame;
std::string path = "/tmp/Downloads";
std::string path = ::testing::TempDir();
frame.set_packet_type(PayloadTransferFrame::DATA);
auto& header = *frame.mutable_payload_header();
header.set_type(PayloadTransferFrame::PayloadHeader::FILE);
@@ -202,6 +206,34 @@ TEST(InternalPayloadFactoryTest,
EXPECT_EQ(payload.GetFileName(), "test.file.name");
}
TEST(InternalPayloadFactoryTest,
VerifyFilePayloadFileNameParentFolderAndLastModifiedTime) {
PayloadTransferFrame frame;
std::string path = ::testing::TempDir();
frame.set_packet_type(PayloadTransferFrame::DATA);
auto& header = *frame.mutable_payload_header();
header.set_type(PayloadTransferFrame::PayloadHeader::FILE);
header.set_id(12345);
header.set_total_size(512);
header.set_file_name("test_file_name");
header.set_parent_folder("test_parent_folder");
int64_t time_millis = absl::ToUnixMillis(absl::Now());
header.set_last_modified_timestamp_millis(time_millis);
ErrorOr<std::unique_ptr<InternalPayload>> result =
CreateIncomingInternalPayload(frame, path);
ASSERT_FALSE(result.has_error());
std::unique_ptr<InternalPayload> internal_payload = std::move(result.value());
EXPECT_NE(internal_payload, nullptr);
EXPECT_EQ(internal_payload->GetFileName(), "test_file_name");
EXPECT_EQ(internal_payload->GetParentFolder(), "test_parent_folder");
// Allow for a 1ms error in the timestamp. This is due to the time being
// converted to a double for the proto and then back to a time.
EXPECT_LE(
std::abs(absl::ToUnixMillis(internal_payload->GetLastModifiedTime()) -
time_millis),
1);
}
TEST(InternalPayloadFactoryTest,
CreateInternalPayloadFailsIfFileCannotBeCreated) {
PayloadTransferFrame frame;
@@ -251,6 +283,30 @@ TEST(InternalPayloadFactoryTest,
EXPECT_EQ(contents_after_skip, ByteArray("456789"));
}
TEST(InternalPayloadFactoryTest,
SkipToOffsetForBytesPayloadFailsIfOffsetIsTooLarge) {
ByteArray data(kText);
ErrorOr<std::unique_ptr<InternalPayload>> result =
CreateOutgoingInternalPayload(Payload{data});
ASSERT_FALSE(result.has_error());
std::unique_ptr<InternalPayload> internal_payload = std::move(result.value());
ASSERT_NE(internal_payload, nullptr);
EXPECT_EQ(internal_payload->SkipToOffset(1024).exception(), Exception::kIo);
}
TEST(InternalPayloadFactoryTest,
AttachNextChunkForOutgoingStreamPayloadFails) {
auto [input, output] = CreatePipe();
ErrorOr<std::unique_ptr<InternalPayload>> internal_payload_result =
CreateOutgoingInternalPayload(Payload(std::move(input)));
ASSERT_FALSE(internal_payload_result.has_error());
std::unique_ptr<InternalPayload> internal_payload =
std::move(internal_payload_result.value());
EXPECT_NE(internal_payload, nullptr);
EXPECT_EQ(internal_payload->AttachNextChunk("data"),
Exception{Exception::kIo});
}
TEST(InternalPayloadFactoryTest,
SkipToOffset_StreamPayloadValidOffset_SkipsOffset) {
absl::string_view contents("0123456789");
@@ -273,6 +329,105 @@ TEST(InternalPayloadFactoryTest,
EXPECT_EQ(contents_after_skip, ByteArray("6789"));
}
TEST(InternalPayloadFactoryTest, IncomingFilePayloadBehavesCorrectly) {
PayloadTransferFrame frame;
std::string path = ::testing::TempDir();
frame.set_packet_type(PayloadTransferFrame::DATA);
auto& header = *frame.mutable_payload_header();
header.set_type(PayloadTransferFrame::PayloadHeader::FILE);
header.set_id(12345);
const int64_t total_size = 512;
header.set_total_size(total_size);
header.set_file_name("test_file_name");
header.set_parent_folder("test_parent_folder");
header.set_last_modified_timestamp_millis(1234567890);
ErrorOr<std::unique_ptr<InternalPayload>> result =
CreateIncomingInternalPayload(frame, path);
ASSERT_FALSE(result.has_error());
std::unique_ptr<InternalPayload> internal_payload = std::move(result.value());
ASSERT_NE(internal_payload, nullptr);
EXPECT_EQ(internal_payload->GetType(),
PayloadTransferFrame::PayloadHeader::FILE);
EXPECT_EQ(internal_payload->GetTotalSize(), total_size);
EXPECT_TRUE(internal_payload->DetachNextChunk(1024).Empty());
EXPECT_EQ(internal_payload->SkipToOffset(1024).exception(),
Exception::kIo);
// Attach a chunk.
std::string chunk1 = "chunk1";
ASSERT_TRUE(internal_payload->AttachNextChunk(chunk1).Ok());
// Attach another chunk.
std::string chunk2 = "chunk2";
ASSERT_TRUE(internal_payload->AttachNextChunk(chunk2).Ok());
// Close payload by attaching empty chunk.
ASSERT_TRUE(internal_payload->AttachNextChunk("").Ok());
// Verify file content.
Payload payload = internal_payload->ReleasePayload();
InputFile* input_file = payload.AsFile();
ASSERT_NE(input_file, nullptr);
std::string expected_content_str = chunk1 + chunk2;
ByteArray expected_content(expected_content_str);
ExceptionOr<ByteArray> file_content =
input_file->Read(expected_content.size());
input_file->Close();
ASSERT_TRUE(file_content.ok());
EXPECT_EQ(file_content.result(), expected_content);
}
TEST(InternalPayloadFactoryTest, IncomingStreamPayloadBehavesCorrectly) {
PayloadTransferFrame frame;
std::string path = ::testing::TempDir();
frame.set_packet_type(PayloadTransferFrame::DATA);
auto& header = *frame.mutable_payload_header();
header.set_type(PayloadTransferFrame::PayloadHeader::STREAM);
header.set_id(12345);
header.set_total_size(0);
ErrorOr<std::unique_ptr<InternalPayload>> result =
CreateIncomingInternalPayload(frame, path);
ASSERT_FALSE(result.has_error());
std::unique_ptr<InternalPayload> internal_payload = std::move(result.value());
ASSERT_NE(internal_payload, nullptr);
EXPECT_EQ(internal_payload->GetType(),
PayloadTransferFrame::PayloadHeader::STREAM);
EXPECT_EQ(internal_payload->GetTotalSize(), -1);
EXPECT_TRUE(internal_payload->DetachNextChunk(1024).Empty());
EXPECT_EQ(internal_payload->SkipToOffset(1024).exception(), Exception::kIo);
// Attach a chunk.
std::string chunk1 = "chunk1";
ASSERT_TRUE(internal_payload->AttachNextChunk(chunk1).Ok());
// Attach another chunk.
std::string chunk2 = "chunk2";
ASSERT_TRUE(internal_payload->AttachNextChunk(chunk2).Ok());
// Close payload by attaching empty chunk.
ASSERT_TRUE(internal_payload->AttachNextChunk("").Ok());
Payload payload = internal_payload->ReleasePayload();
InputStream* input_stream = payload.AsStream();
ASSERT_NE(input_stream, nullptr);
// Read from input stream to verify.
std::string result_str;
while (true) {
ExceptionOr<ByteArray> chunk = input_stream->Read(1024);
ASSERT_TRUE(chunk.ok());
if (chunk.result().Empty()) break;
result_str.append(chunk.result().data(), chunk.result().size());
}
ByteArray result_bytes(result_str);
std::string expected_content_str = chunk1 + chunk2;
ByteArray expected_content(expected_content_str);
EXPECT_EQ(result_bytes, expected_content);
input_stream->Close();
}
} // namespace
} // namespace connections
} // namespace nearby
+1
View File
@@ -179,6 +179,7 @@ cc_test(
"//internal/platform/implementation:types",
"//internal/platform/implementation/g3", # build_cleaner: keep
"@com_github_protobuf_matchers//protobuf-matchers",
"@com_google_absl//absl/container:flat_hash_map",
"@com_google_absl//absl/strings",
"@com_google_absl//absl/time",
"@com_google_googletest//:gtest_main",
+191 -4
View File
@@ -20,18 +20,15 @@
#include "gtest/gtest.h"
#include "absl/strings/string_view.h"
#include "absl/time/time.h"
#include "connections/implementation/flags/nearby_connections_feature_flags.h"
#include "internal/flags/nearby_flags.h"
#include "internal/platform/awdl.h"
#include "internal/platform/base64_utils.h"
#include "internal/platform/cancellation_flag.h"
#include "internal/platform/count_down_latch.h"
#include "internal/platform/expected.h"
#include "internal/platform/feature_flags.h"
#include "internal/platform/implementation/psk_info.h"
#include "internal/platform/logging.h"
#include "internal/platform/medium_environment.h"
#include "internal/platform/nsd_service_info.h"
#include "internal/platform/single_thread_executor.h"
namespace nearby {
namespace connections {
@@ -113,6 +110,61 @@ TEST_P(AwdlTest, CanConnect) {
env_.Stop();
}
TEST_P(AwdlTest, CanConnectWithPsk) {
FeatureFlags feature_flags = GetParam();
env_.SetFeatureFlags(feature_flags);
env_.Start();
Awdl awdl_client;
Awdl awdl_server;
std::string service_id(kServiceID);
std::string service_info_name(kServiceInfoName);
std::string endpoint_info_name(kEndpointName);
api::PskInfo psk_info;
psk_info.password = "password";
CountDownLatch discovered_latch(1);
CountDownLatch accept_latch(1);
AwdlSocket socket_for_server;
EXPECT_TRUE(awdl_server.StartAcceptingConnections(
service_id, psk_info,
[&](const std::string& service_id, AwdlSocket socket) {
socket_for_server = std::move(socket);
accept_latch.CountDown();
}));
NsdServiceInfo nsd_service_info;
nsd_service_info.SetServiceName(service_info_name);
nsd_service_info.SetTxtRecord(std::string(kEndpointInfoKey),
endpoint_info_name);
awdl_server.StartAdvertising(service_id, nsd_service_info);
NsdServiceInfo discovered_service_info;
awdl_client.StartDiscovery(
service_id,
{
.service_discovered_cb =
[&discovered_latch, &discovered_service_info](
NsdServiceInfo service_info, const std::string& service_id) {
LOG(INFO) << "Discovered service_info=" << &service_info;
discovered_service_info = service_info;
discovered_latch.CountDown();
},
});
discovered_latch.Await(kWaitDuration).result();
ASSERT_TRUE(discovered_service_info.IsValid());
CancellationFlag flag;
ErrorOr<AwdlSocket> socket_for_client_result =
awdl_client.Connect(service_id, discovered_service_info, psk_info, &flag);
EXPECT_TRUE(accept_latch.Await(kWaitDuration).result());
EXPECT_TRUE(awdl_server.StopAcceptingConnections(service_id));
EXPECT_TRUE(awdl_server.StopAdvertising(service_id));
EXPECT_TRUE(socket_for_server.IsValid());
EXPECT_TRUE(socket_for_client_result.has_value());
EXPECT_TRUE(socket_for_client_result.value().IsValid());
env_.Stop();
}
TEST_P(AwdlTest, CanCancelConnect) {
FeatureFlags feature_flags = GetParam();
env_.SetFeatureFlags(feature_flags);
@@ -206,6 +258,115 @@ TEST_F(AwdlTest, CanStartAdvertising) {
env_.Stop();
}
TEST_F(AwdlTest, StartAdvertisingFailsWithInvalidNsdServiceInfo) {
env_.Start();
Awdl awdl_a;
std::string service_id(kServiceID);
EXPECT_TRUE(awdl_a.StartAcceptingConnections(service_id, {}));
NsdServiceInfo nsd_service_info;
ErrorOr<bool> result = awdl_a.StartAdvertising(service_id, nsd_service_info);
EXPECT_FALSE(result.has_value());
EXPECT_EQ(result.error().operation_result_code().value(),
location::nearby::proto::connections::OperationResultCode::
MEDIUM_UNAVAILABLE_NSD_NOT_AVAILABLE);
env_.Stop();
}
TEST_F(AwdlTest, StopAdvertisingFailsIfNotAdvertising) {
env_.Start();
Awdl awdl_a;
std::string service_id(kServiceID);
EXPECT_FALSE(awdl_a.StopAdvertising(service_id));
env_.Stop();
}
TEST_F(AwdlTest, StartAdvertisingFailsIfAlreadyAdvertising) {
env_.Start();
Awdl awdl_a;
std::string service_id(kServiceID);
std::string service_info_name(kServiceInfoName);
std::string endpoint_info_name(kEndpointName);
EXPECT_TRUE(awdl_a.StartAcceptingConnections(service_id, {}));
NsdServiceInfo nsd_service_info;
nsd_service_info.SetServiceName(service_info_name);
nsd_service_info.SetTxtRecord(std::string(kEndpointInfoKey),
endpoint_info_name);
EXPECT_TRUE(awdl_a.StartAdvertising(service_id, nsd_service_info));
ErrorOr<bool> result = awdl_a.StartAdvertising(service_id, nsd_service_info);
EXPECT_FALSE(result.has_value());
EXPECT_EQ(result.error().operation_result_code().value(),
location::nearby::proto::connections::OperationResultCode::
CLIENT_AWDL_DUPLICATE_ADVERTISING);
EXPECT_TRUE(awdl_a.StopAdvertising(service_id));
env_.Stop();
}
TEST_F(AwdlTest, StartAdvertisingFailsIfNotAcceptingConnections) {
env_.Start();
Awdl awdl_a;
std::string service_id(kServiceID);
std::string service_info_name(kServiceInfoName);
std::string endpoint_info_name(kEndpointName);
NsdServiceInfo nsd_service_info;
nsd_service_info.SetServiceName(service_info_name);
nsd_service_info.SetTxtRecord(std::string(kEndpointInfoKey),
endpoint_info_name);
ErrorOr<bool> result = awdl_a.StartAdvertising(service_id, nsd_service_info);
EXPECT_FALSE(result.has_value());
EXPECT_EQ(result.error().operation_result_code().value(),
location::nearby::proto::connections::OperationResultCode::
CLIENT_DUPLICATE_ACCEPTING_AWDL_CONNECTION_REQUEST);
env_.Stop();
}
TEST_F(AwdlTest, StartAdvertisingUpdatesNsdServiceInfo) {
env_.Start();
Awdl awdl_a;
std::string service_id(kServiceID);
std::string service_info_name(kServiceInfoName);
std::string endpoint_info_name(kEndpointName);
EXPECT_TRUE(awdl_a.StartAcceptingConnections(service_id, {}));
NsdServiceInfo nsd_service_info;
nsd_service_info.SetServiceName(service_info_name);
nsd_service_info.SetTxtRecord(std::string(kEndpointInfoKey),
endpoint_info_name);
EXPECT_TRUE(awdl_a.StartAdvertising(service_id, nsd_service_info));
EXPECT_FALSE(nsd_service_info.GetServiceType().empty());
EXPECT_FALSE(nsd_service_info.GetIPAddress().empty());
EXPECT_GT(nsd_service_info.GetPort(), 0);
EXPECT_TRUE(awdl_a.StopAdvertising(service_id));
env_.Stop();
}
TEST_F(AwdlTest, CanStartAcceptingConnectionsWithPsk) {
env_.Start();
Awdl awdl_a;
std::string service_id(kServiceID);
std::string service_info_name(kServiceInfoName);
std::string endpoint_info_name(kEndpointName);
api::PskInfo psk_info;
psk_info.password = "password";
EXPECT_TRUE(awdl_a.StartAcceptingConnections(service_id, psk_info, {}));
NsdServiceInfo nsd_service_info;
nsd_service_info.SetServiceName(service_info_name);
nsd_service_info.SetTxtRecord(std::string(kEndpointInfoKey),
endpoint_info_name);
EXPECT_TRUE(awdl_a.StartAdvertising(service_id, nsd_service_info));
EXPECT_EQ(awdl_a.GetCredentials(service_id).password, "password");
EXPECT_TRUE(awdl_a.StopAdvertising(service_id));
env_.Stop();
}
TEST_F(AwdlTest, CanStartMultipleAdvertising) {
env_.Start();
Awdl awdl_a;
@@ -235,6 +396,32 @@ TEST_F(AwdlTest, CanStartMultipleAdvertising) {
env_.Stop();
}
TEST_F(AwdlTest, StartAcceptingConnectionsFailsWithEmptyServiceId) {
env_.Start();
Awdl awdl_a;
ErrorOr<bool> result = awdl_a.StartAcceptingConnections("", {});
EXPECT_FALSE(result.has_value());
EXPECT_EQ(result.error().operation_result_code().value(),
location::nearby::proto::connections::OperationResultCode::
NEARBY_LOCAL_CLIENT_STATE_WRONG);
env_.Stop();
}
TEST_F(AwdlTest, StartAcceptingConnectionsFailsIfAlreadyAccepting) {
env_.Start();
Awdl awdl_a;
std::string service_id(kServiceID);
EXPECT_TRUE(awdl_a.StartAcceptingConnections(service_id, {}));
ErrorOr<bool> result = awdl_a.StartAcceptingConnections(service_id, {});
EXPECT_FALSE(result.has_value());
EXPECT_EQ(result.error().operation_result_code().value(),
location::nearby::proto::connections::OperationResultCode::
CLIENT_DUPLICATE_ACCEPTING_AWDL_CONNECTION_REQUEST);
awdl_a.StopAcceptingConnections(service_id);
env_.Stop();
}
TEST_F(AwdlTest, CanStartDiscovery) {
env_.Start();
Awdl awdl_a;
+1 -4
View File
@@ -56,10 +56,7 @@ cc_library(
name = "ble_socket",
srcs = ["ble_socket.cc"],
hdrs = ["ble_socket.h"],
visibility = [
"//connections/implementation:__subpackages__",
"//internal/platform/implementation/windows:__pkg__",
],
visibility = ["//connections/implementation:__subpackages__"],
deps = [
":ble",
"//connections/implementation/flags:connections_flags",
@@ -97,12 +97,12 @@ cc_test(
"//internal/platform:test_util",
"//internal/platform:types",
"//internal/platform/implementation/g3", # buildcleaner: keep
"//third_party/protobuf",
"//third_party/webrtc/files/stable/webrtc/api:libjingle_peerconnection_api",
"//third_party/webrtc/files/stable/webrtc/api:scoped_refptr",
"@com_github_protobuf_matchers//protobuf-matchers",
"@com_google_absl//absl/strings:string_view",
"@com_google_absl//absl/time",
"@com_google_googletest//:gtest_main",
"@com_google_protobuf//:protobuf",
],
)
+35 -5
View File
@@ -543,6 +543,18 @@ void PayloadManager::OnIncomingFrame(OfflineFrame& offline_frame,
// Block any payload before the connection been accepted by both sides
// to prevent unauthorized transfer.
if (!to_client->IsConnectedToEndpoint(from_endpoint_id)) {
if (frame.packet_type() == PayloadTransferFrame::DATA) {
PendingPayloadHandle pending_payload =
pending_payloads_.GetPayload(frame.payload_header().id());
bool is_last = IsLastChunk(frame.payload_chunk());
// If payload need to be ack'd receiving, then send back the ACK frame.
if (pending_payload && is_last &&
IsPayloadReceivedAckEnabled(to_client, from_endpoint_id,
*pending_payload)) {
SendPayloadReceivedAck(to_client, *pending_payload, from_endpoint_id,
is_last);
}
}
VLOG(1) << "PayloadManager skipped process payloads before PCP connected, "
<< frame.payload_header().id();
return;
@@ -784,9 +796,12 @@ PayloadTransferFrame::PayloadChunk PayloadManager::CreatePayloadChunk(
ErrorOr<PayloadManager::PendingPayloadHandle>
PayloadManager::CreateIncomingPayload(const PayloadTransferFrame& frame,
const std::string& endpoint_id) {
const std::string& endpoint_id,
const std::string& save_path) {
ErrorOr<std::unique_ptr<InternalPayload>> result =
CreateIncomingInternalPayload(frame, custom_save_path_);
CreateIncomingInternalPayload(frame, save_path.empty()
? custom_save_path_
: save_path);
if (result.has_error()) {
return {result.error()};
}
@@ -913,7 +928,8 @@ void PayloadManager::SendPayloadReceivedAck(ClientProxy* client,
PendingPayload& pending_payload,
const std::string& endpoint_id,
bool is_last_chunk) {
if (!is_last_chunk) {
if (!is_last_chunk ||
!IsPayloadReceivedAckEnabled(client, endpoint_id, pending_payload)) {
return;
}
@@ -935,7 +951,8 @@ bool PayloadManager::WaitForReceivedAck(
PendingPayload& pending_payload,
const PayloadTransferFrame::PayloadHeader& payload_header,
std::int64_t payload_chunk_offset, bool is_last_chunk) {
if (!is_last_chunk) {
if (!is_last_chunk ||
!IsPayloadReceivedAckEnabled(client, endpoint_id, pending_payload)) {
return true;
}
@@ -1023,6 +1040,18 @@ bool PayloadManager::WaitForReceivedAck(
return true;
}
bool PayloadManager::IsPayloadReceivedAckEnabled(
ClientProxy* client, const std::string& endpoint_id,
PendingPayload& pending_payload) {
return NearbyFlags::GetInstance().GetBoolFlag(
config_package_nearby::nearby_connections_feature::
kEnablePayloadReceivedAck) &&
client->IsPayloadReceivedAckEnabled(endpoint_id) &&
(pending_payload.GetInternalPayload()->GetType() !=
nearby::connections::PayloadTransferFrame::PayloadTransferFrame::
PayloadHeader::BYTES);
}
void PayloadManager::HandleFinishedOutgoingPayload(
ClientProxy* client, const EndpointIds& finished_endpoint_ids,
const PayloadTransferFrame::PayloadHeader& payload_header,
@@ -1318,7 +1347,8 @@ void PayloadManager::ProcessDataPacket(
});
ErrorOr<PendingPayloadHandle> result =
CreateIncomingPayload(payload_transfer_frame, from_endpoint_id);
CreateIncomingPayload(payload_transfer_frame, from_endpoint_id,
to_client->GetSavePath(from_endpoint_id));
if (result.has_error()) {
LOG(WARNING) << "PayloadManager failed to create InternalPayload from "
"PayloadTransferFrame with payload_id="
+8 -1
View File
@@ -323,9 +323,13 @@ class PayloadManager : public EndpointManager::FrameProcessor {
LAST_CHUNK) != 0);
}
// Creates an incoming payload and returns a handle to it.
// If `save_path` is empty, the payload will be saved to the default save
// path set in `SetCustomSavePath()`.
ErrorOr<PendingPayloadHandle> CreateIncomingPayload(
const location::nearby::connections::PayloadTransferFrame& frame,
const std::string& endpoint_id) ABSL_LOCKS_EXCLUDED(mutex_);
const std::string& endpoint_id,
const std::string& save_path) ABSL_LOCKS_EXCLUDED(mutex_);
Payload::Id CreateOutgoingPayload(Payload payload,
const EndpointIds& endpoint_ids)
@@ -367,6 +371,9 @@ class PayloadManager : public EndpointManager::FrameProcessor {
const location::nearby::connections::PayloadTransferFrame::PayloadHeader&
payload_header,
std::int64_t payload_chunk_offset, bool is_last_chunk);
bool IsPayloadReceivedAckEnabled(ClientProxy* client,
const std::string& endpoint_id,
PendingPayload& pending_payload);
// Handles a finished outgoing payload for the given endpointIds. All
// statuses except for SUCCESS are handled here.
@@ -14,25 +14,11 @@
#include "connections/implementation/simulation_user.h"
#include <string>
#include <utility>
#include "gtest/gtest.h"
#include "absl/functional/any_invocable.h"
#include "absl/functional/bind_front.h"
#include "absl/strings/string_view.h"
#include "absl/time/time.h"
#include "connections/listeners.h"
#include "connections/out_of_band_connection_metadata.h"
#include "connections/payload.h"
#include "connections/status.h"
#include "connections/v3/connection_listening_options.h"
#include "internal/interop/device.h"
#include "internal/platform/byte_array.h"
#include "internal/platform/count_down_latch.h"
#include "internal/platform/future.h"
#include "internal/platform/logging.h"
#include "internal/platform/mutex_lock.h"
namespace nearby {
namespace connections {
+11 -24
View File
@@ -19,36 +19,21 @@
#include <cstdint>
#include <string>
#include "absl/functional/any_invocable.h"
#include "absl/strings/string_view.h"
#include "absl/time/time.h"
#include "connections/advertising_options.h"
#include "connections/connection_options.h"
#include "connections/discovery_options.h"
#include "gtest/gtest.h"
#include "connections/implementation/bwu_manager.h"
#include "connections/implementation/client_proxy.h"
#include "connections/implementation/endpoint_channel_manager.h"
#include "connections/implementation/endpoint_manager.h"
#include "connections/implementation/flags/nearby_connections_feature_flags.h"
#include "connections/implementation/injected_bluetooth_device_store.h"
#include "connections/implementation/mediums/mediums.h"
#include "connections/implementation/payload_manager.h"
#include "connections/implementation/pcp_manager.h"
#include "connections/listeners.h"
#include "connections/medium_selector.h"
#include "connections/out_of_band_connection_metadata.h"
#include "connections/payload.h"
#include "connections/status.h"
#include "connections/strategy.h"
#include "connections/v3/connection_listening_options.h"
#include "connections/v3/connections_device.h"
#include "internal/flags/nearby_flags.h"
#include "internal/interop/device.h"
#include "internal/platform/byte_array.h"
#include "internal/platform/condition_variable.h"
#include "internal/platform/count_down_latch.h"
#include "internal/platform/feature_flags.h"
#include "internal/platform/future.h"
#include "internal/platform/mutex.h"
// Test-only class to help run end-to-end simulations for nearby connections
// protocol.
@@ -62,6 +47,7 @@ namespace connections {
class SetSafeToDisconnect {
public:
explicit SetSafeToDisconnect(bool safe_to_disconnect, bool auto_reconnect,
bool payload_received_ack,
std::int32_t safe_to_disconnect_version) {
NearbyFlags::GetInstance().OverrideBoolFlagValue(
config_package_nearby::nearby_connections_feature::
@@ -70,6 +56,10 @@ class SetSafeToDisconnect {
NearbyFlags::GetInstance().OverrideBoolFlagValue(
config_package_nearby::nearby_connections_feature::kEnableAutoReconnect,
auto_reconnect);
NearbyFlags::GetInstance().OverrideBoolFlagValue(
config_package_nearby::nearby_connections_feature::
kEnablePayloadReceivedAck,
payload_received_ack);
NearbyFlags::GetInstance().OverrideInt64FlagValue(
config_package_nearby::nearby_connections_feature::
kSafeToDisconnectVersion,
@@ -88,13 +78,10 @@ class SimulationUser {
void Clear() { endpoint_id.clear(); }
};
explicit SimulationUser(
const std::string& device_name,
BooleanMediumSelector allowed = BooleanMediumSelector(),
SetSafeToDisconnect set_safe_to_disconnect =
SetSafeToDisconnect(/*safe_to_disconnect=*/true,
/*auto_reconnect=*/false,
/*safe_to_disconnect_version=*/5))
SimulationUser(const std::string& device_name,
BooleanMediumSelector allowed = BooleanMediumSelector(),
SetSafeToDisconnect set_safe_to_disconnect =
SetSafeToDisconnect(true, false, true, 5))
: info_{ByteArray{device_name}},
advertising_options_{
{
+10 -10
View File
@@ -30,7 +30,7 @@ NearbyFlags& NearbyFlags::GetInstance() {
}
bool NearbyFlags::GetBoolFlag(const flags::Flag<bool>& flag) {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
const auto& it = overrided_bool_flag_values_.find(flag.name());
if (it != overrided_bool_flag_values_.end()) {
@@ -44,7 +44,7 @@ bool NearbyFlags::GetBoolFlag(const flags::Flag<bool>& flag) {
}
int64_t NearbyFlags::GetInt64Flag(const flags::Flag<int64_t>& flag) {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
const auto& it = overrided_int64_flag_values_.find(flag.name());
if (it != overrided_int64_flag_values_.end()) {
@@ -58,7 +58,7 @@ int64_t NearbyFlags::GetInt64Flag(const flags::Flag<int64_t>& flag) {
}
double NearbyFlags::GetDoubleFlag(const flags::Flag<double>& flag) {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
const auto& it = overrided_double_flag_values_.find(flag.name());
if (it != overrided_double_flag_values_.end()) {
@@ -73,7 +73,7 @@ double NearbyFlags::GetDoubleFlag(const flags::Flag<double>& flag) {
std::string NearbyFlags::GetStringFlag(
const flags::Flag<absl::string_view>& flag) {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
const auto& it = overrided_string_flag_values_.find(flag.name());
if (it != overrided_string_flag_values_.end()) {
@@ -87,36 +87,36 @@ std::string NearbyFlags::GetStringFlag(
}
void NearbyFlags::SetFlagReader(flags::FlagReader& flag_reader) {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
flag_reader_ = &flag_reader;
}
void NearbyFlags::OverrideBoolFlagValue(const flags::Flag<bool>& flag,
bool new_value) {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
overrided_bool_flag_values_[flag.name()] = new_value;
}
void NearbyFlags::OverrideInt64FlagValue(const flags::Flag<int64_t>& flag,
int64_t new_value) {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
overrided_int64_flag_values_[flag.name()] = new_value;
}
void NearbyFlags::OverrideDoubleFlagValue(const flags::Flag<double>& flag,
double new_value) {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
overrided_double_flag_values_[flag.name()] = new_value;
}
void NearbyFlags::OverrideStringFlagValue(
const flags::Flag<absl::string_view>& flag, absl::string_view new_value) {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
overrided_string_flag_values_[flag.name()] = std::string(new_value);
}
void NearbyFlags::ResetOverridedValues() {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
overrided_bool_flag_values_.clear();
overrided_int64_flag_values_.clear();
overrided_double_flag_values_.clear();
+2
View File
@@ -128,6 +128,7 @@ cc_library(
],
deps = [
":base",
"@com_google_absl//absl/base:core_headers",
"@com_google_absl//absl/container:flat_hash_set",
"@com_google_absl//absl/functional:any_invocable",
"@com_google_absl//absl/synchronization",
@@ -257,6 +258,7 @@ cc_library(
"//:__subpackages__",
"//location/nearby/apps:__subpackages__",
"//location/nearby/cpp:__subpackages__",
"//location/nearby/sharing/lib:__subpackages__",
"//location/nearby/sharing/sdk:__subpackages__",
"//location/nearby/testing/nearby_native:__subpackages__",
],
+1 -5
View File
@@ -28,11 +28,7 @@
namespace nearby {
std::string Base64Utils::Encode(const ByteArray& bytes) {
std::string base64_string;
absl::WebSafeBase64Escape(std::string(bytes), &base64_string);
return base64_string;
return absl::WebSafeBase64Escape(bytes.AsStringView());
}
ByteArray Base64Utils::Decode(absl::string_view base64_string) {
+9 -6
View File
@@ -13,7 +13,10 @@
// limitations under the License.
#include "internal/platform/cancellation_flag.h"
#include <memory>
#include "absl/container/flat_hash_set.h"
#include "absl/synchronization/mutex.h"
#include "internal/platform/feature_flags.h"
namespace nearby {
@@ -28,7 +31,7 @@ CancellationFlag::CancellationFlag(bool cancelled) {
}
CancellationFlag::~CancellationFlag() {
absl::MutexLock lock(mutex_.get());
absl::MutexLock lock(*mutex_);
listeners_.clear();
}
@@ -40,7 +43,7 @@ void CancellationFlag::Cancel() {
absl::flat_hash_set<CancelListener *> listeners;
{
absl::MutexLock lock(mutex_.get());
absl::MutexLock lock(*mutex_);
if (cancelled_) {
// Someone already cancelled. Return immediately.
return;
@@ -62,14 +65,14 @@ void CancellationFlag::Uncancel() {
}
{
absl::MutexLock lock(mutex_.get());
absl::MutexLock lock(*mutex_);
assert(cancelled_);
cancelled_ = false;
}
}
bool CancellationFlag::Cancelled() const {
absl::MutexLock lock(mutex_.get());
absl::MutexLock lock(*mutex_);
// Return false as no-op if feature flag is not enabled.
if (!FeatureFlags::GetInstance().GetFlags().enable_cancellation_flag) {
@@ -80,13 +83,13 @@ bool CancellationFlag::Cancelled() const {
}
void CancellationFlag::RegisterOnCancelListener(CancelListener *listener) {
absl::MutexLock lock(mutex_.get());
absl::MutexLock lock(*mutex_);
listeners_.emplace(listener);
}
void CancellationFlag::UnregisterOnCancelListener(CancelListener *listener) {
absl::MutexLock lock(mutex_.get());
absl::MutexLock lock(*mutex_);
listeners_.erase(listener);
}
+2 -1
View File
@@ -17,6 +17,7 @@
#include <memory>
#include "absl/base/thread_annotations.h"
#include "absl/container/flat_hash_set.h"
#include "absl/functional/any_invocable.h"
#include "absl/synchronization/mutex.h"
@@ -74,7 +75,7 @@ class CancellationFlag {
ABSL_LOCKS_EXCLUDED(mutex_);
int CancelListenersSize() const ABSL_LOCKS_EXCLUDED(mutex_) {
absl::MutexLock lock(mutex_.get());
absl::MutexLock lock(*mutex_);
return listeners_.size();
}
+6 -6
View File
@@ -126,18 +126,18 @@ class FeatureFlags {
return *instance;
}
const Flags& GetFlags() const ABSL_LOCKS_EXCLUDED(mutex_) {
absl::ReaderMutexLock lock(&mutex_);
return flags_;
static FeatureFlags& GetMutableInstanceForTesting() {
return const_cast<FeatureFlags&>(GetInstance());
}
static Flags& GetMutableFlagsForTesting() {
return const_cast<FeatureFlags&>(GetInstance()).flags_;
Flags GetFlags() const ABSL_LOCKS_EXCLUDED(mutex_) {
absl::ReaderMutexLock lock(mutex_);
return flags_;
}
// SetFlags for feature controlling
void SetFlags(const Flags& flags) ABSL_LOCKS_EXCLUDED(mutex_) {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
flags_ = flags;
}
+2 -2
View File
@@ -28,8 +28,8 @@ constexpr FeatureFlags::Flags kTestFeatureFlags{
TEST(FeatureFlagsTest, CastUpdateWorks) {
const FeatureFlags& features = FeatureFlags::GetInstance();
EXPECT_TRUE(features.GetFlags().enable_async_bandwidth_upgrade);
const_cast<FeatureFlags&>(FeatureFlags::GetInstance())
.SetFlags({.enable_async_bandwidth_upgrade = false});
FeatureFlags::GetMutableInstanceForTesting().SetFlags(
{.enable_async_bandwidth_upgrade = false});
EXPECT_FALSE(features.GetFlags().enable_async_bandwidth_upgrade);
}
@@ -65,10 +65,6 @@ constexpr auto kEnableIntelPieSdk =
constexpr auto kEnableNewBluetoothRefactor =
flags::Flag<bool>(kConfigPackage, "45615156", false);
// Enable/Disable use of address candidates for WifiLan upgrade in Windows.
constexpr auto kEnableWifiLanAddressCandidates =
flags::Flag<bool>(kConfigPackage, "45739995", false);
// The send buffer size of blocking socket
constexpr auto kSocketSendBufferSize =
flags::Flag<int64_t>(kConfigPackage, "45673785", 524288);
+6 -1
View File
@@ -46,6 +46,7 @@ cc_library(
"//internal/platform/implementation:__subpackages__",
"//internal/test:__subpackages__",
"//location/nearby/cpp/sharing/clients/cpp:__subpackages__",
"//location/nearby/sharing/lib:__subpackages__",
"//location/nearby/sharing/sdk/quick_share_server:__pkg__",
"//sharing:__subpackages__",
],
@@ -125,6 +126,7 @@ cc_library(
"@com_google_absl//absl/strings",
"@com_google_absl//absl/time",
"@com_google_absl//absl/types:span",
"@com_google_protobuf//:protobuf",
"@nlohmann_json//:json",
],
)
@@ -225,7 +227,10 @@ cc_library(
name = "platform_impl",
testonly = True,
tags = ["keep_dep"], # Prevent build_cleaner from removing the dependency.
visibility = ["//:__subpackages__"],
visibility = [
"//:__subpackages__",
"//location/nearby/sharing/lib:__subpackages__",
],
deps = [
] + select({
"@platforms//os:windows": [
@@ -22,7 +22,6 @@ package(default_visibility = [
"//ambient/nearby/testing/connection/mdc/ios:__subpackages__",
"//connections:__subpackages__",
"//connections:partners",
"//googlemac/iPhone/Nearby:__subpackages__",
"//internal/platform:__subpackages__",
"//internal/preferences:__subpackages__",
"//location/nearby:__subpackages__",
@@ -106,7 +105,6 @@ objc_library(
"//internal/platform/implementation/apple/Mediums/Hotspot",
"//internal/account",
"//internal/crypto_cros",
"//internal/platform/implementation:account_manager",
"//internal/platform:comm",
"//internal/platform:logging",
"//internal/platform:types",
@@ -26,7 +26,7 @@ namespace nearby {
namespace apple {
BleL2capServerSocket::~BleL2capServerSocket() {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
DoClose();
}
@@ -36,7 +36,7 @@ void BleL2capServerSocket::SetPSM(int psm) { psm_ = psm; }
// TODO: b/399815436 - Refactor Accept() and AddPendingSocket() for better readability.
std::unique_ptr<api::ble::BleL2capSocket> BleL2capServerSocket::Accept() {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
while (!closed_ && pending_sockets_.empty()) {
cond_.Wait(&mutex_);
}
@@ -48,7 +48,7 @@ std::unique_ptr<api::ble::BleL2capSocket> BleL2capServerSocket::Accept() {
}
bool BleL2capServerSocket::AddPendingSocket(std::unique_ptr<BleL2capSocket> socket) {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
if (closed_) {
return false;
}
@@ -58,12 +58,12 @@ bool BleL2capServerSocket::AddPendingSocket(std::unique_ptr<BleL2capSocket> sock
}
void BleL2capServerSocket::SetCloseNotifier(absl::AnyInvocable<void()> notifier) {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
close_notifier_ = std::move(notifier);
}
Exception BleL2capServerSocket::Close() {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
return DoClose();
}
@@ -172,17 +172,17 @@ BleL2capSocket::BleL2capSocket(GNCBLEL2CAPConnection *connection,
peripheral_id_(peripheral_id) {}
BleL2capSocket::~BleL2capSocket() {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
DoClose();
}
bool BleL2capSocket::IsClosed() const {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
return closed_;
}
Exception BleL2capSocket::Close() {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
DoClose();
return {Exception::kSuccess};
}
@@ -522,11 +522,11 @@ std::unique_ptr<api::ble::BleL2capServerSocket> BleMedium::OpenL2capServerSocket
__block NSError *blockPSMPublishedError = nil;
auto l2cap_server_socket = std::make_unique<BleL2capServerSocket>();
l2cap_server_socket->SetCloseNotifier([this]() {
absl::MutexLock lock(&l2cap_server_socket_mutex_);
absl::MutexLock lock(l2cap_server_socket_mutex_);
l2cap_server_socket_ptr_ = nullptr;
});
{
absl::MutexLock lock(&l2cap_server_socket_mutex_);
absl::MutexLock lock(l2cap_server_socket_mutex_);
l2cap_server_socket_ptr_ = l2cap_server_socket.get();
}
std::string service_id_str = service_id;
@@ -538,7 +538,7 @@ std::unique_ptr<api::ble::BleL2capServerSocket> BleMedium::OpenL2capServerSocket
return;
}
{
absl::MutexLock lock(&l2cap_server_socket_mutex_);
absl::MutexLock lock(l2cap_server_socket_mutex_);
if (l2cap_server_socket_ptr_) {
l2cap_server_socket_ptr_->SetPSM(PSM);
}
@@ -558,7 +558,7 @@ std::unique_ptr<api::ble::BleL2capServerSocket> BleMedium::OpenL2capServerSocket
callbackQueue:connection_callback_queue_];
auto socket = std::make_unique<BleL2capSocket>(connection);
{
absl::MutexLock lock(&l2cap_server_socket_mutex_);
absl::MutexLock lock(l2cap_server_socket_mutex_);
if (l2cap_server_socket_ptr_) {
l2cap_server_socket_ptr_->AddPendingSocket(std::move(socket));
}
@@ -730,20 +730,20 @@ std::optional<api::ble::BlePeripheral::UniqueId> BleMedium::RetrieveBlePeriphera
}
void BleMedium::ClearAdvertisementPacketsMap() {
absl::MutexLock lock(&advertisement_packets_mutex_);
absl::MutexLock lock(advertisement_packets_mutex_);
advertisement_packets_map_.clear();
last_timestamp_to_clean_expired_advertisement_packets_ = [NSDate date];
}
NSDate *BleMedium::GetLastTimestampToCleanExpiredAdvertisementPackets() {
absl::MutexLock lock(&advertisement_packets_mutex_);
absl::MutexLock lock(advertisement_packets_mutex_);
return last_timestamp_to_clean_expired_advertisement_packets_;
}
bool BleMedium::ShouldReportAdvertisement(NSDate *now,
api::ble::BlePeripheral::UniqueId peripheral_id,
NSDictionary<CBUUID *, NSData *> *service_data) {
absl::MutexLock lock(&advertisement_packets_mutex_);
absl::MutexLock lock(advertisement_packets_mutex_);
if (service_data == nil || service_data.count == 0) {
return false;
}
@@ -775,19 +775,19 @@ bool BleMedium::ShouldReportAdvertisement(NSDate *now,
void BleMedium::AddAdvertisementPacketInfo(api::ble::BlePeripheral::UniqueId peripheral_id,
NSDictionary<CBUUID *, NSData *> *service_data) {
absl::MutexLock lock(&advertisement_packets_mutex_);
absl::MutexLock lock(advertisement_packets_mutex_);
advertisement_packets_map_[peripheral_id] = {[NSDate date], service_data};
}
api::ble::BlePeripheral::UniqueId BleMedium::PeripheralsMap::Add(id<GNCPeripheral> peripheral) {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
api::ble::BlePeripheral::UniqueId peripheral_id = peripheral.identifier.hash;
peripherals_.insert({peripheral_id, peripheral});
return peripheral_id;
}
id<GNCPeripheral> BleMedium::PeripheralsMap::Get(api::ble::BlePeripheral::UniqueId peripheral_id) {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
auto peripheral_it = peripherals_.find(peripheral_id);
if (peripheral_it == peripherals_.end()) {
return nil;
@@ -796,7 +796,7 @@ id<GNCPeripheral> BleMedium::PeripheralsMap::Get(api::ble::BlePeripheral::Unique
}
void BleMedium::PeripheralsMap::Clear() {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
peripherals_.clear();
}
@@ -25,12 +25,12 @@ namespace nearby {
namespace apple {
BleServerSocket::~BleServerSocket() {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
DoClose();
}
std::unique_ptr<api::ble::BleSocket> BleServerSocket::Accept() {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
while (!closed_ && pending_sockets_.empty()) {
cond_.Wait(&mutex_);
}
@@ -42,7 +42,7 @@ std::unique_ptr<api::ble::BleSocket> BleServerSocket::Accept() {
}
bool BleServerSocket::Connect(std::unique_ptr<BleSocket> socket) {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
if (closed_) {
return false;
}
@@ -52,12 +52,12 @@ bool BleServerSocket::Connect(std::unique_ptr<BleSocket> socket) {
}
void BleServerSocket::SetCloseNotifier(absl::AnyInvocable<void()> notifier) {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
close_notifier_ = std::move(notifier);
}
Exception BleServerSocket::Close() {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
return DoClose();
}
@@ -185,23 +185,23 @@ BleSocket::BleSocket(id<GNCMConnection> connection, api::ble::BlePeripheral::Uni
peripheral_id_(peripheral_id) {}
BleSocket::~BleSocket() {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
DoClose();
}
bool BleSocket::IsClosed() const {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
return closed_;
}
Exception BleSocket::Close() {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
DoClose();
return {Exception::kSuccess};
}
void BleSocket::SetCloseNotifier(absl::AnyInvocable<void()> notifier) {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
close_notifier_ = std::move(notifier);
}
@@ -21,19 +21,19 @@ namespace nearby {
namespace apple {
Exception CountDownLatch::Await() {
absl::MutexLock lock(&mutex_, absl::Condition(IsZeroOrNegative, &count_));
absl::MutexLock lock(mutex_, absl::Condition(IsZeroOrNegative, &count_));
return {Exception::kSuccess};
}
ExceptionOr<bool> CountDownLatch::Await(absl::Duration timeout) {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
bool condition = mutex_.AwaitWithTimeout(
absl::Condition(IsZeroOrNegative, &count_), timeout);
return ExceptionOr<bool>(condition);
}
void CountDownLatch::CountDown() {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
count_--;
}
@@ -88,8 +88,19 @@ class PreferencesManager : public nearby::api::PreferencesManager {
absl::Time GetTime(absl::string_view key,
absl::Time default_value) const override;
bool SetProtoMessage(absl::string_view key,
const google::protobuf::Message& value) override {
return false;
}
bool GetProtoMessage(absl::string_view key,
google::protobuf::Message* value) const override {
return false;
}
// Removes preferences
void Remove(absl::string_view key) override;
// TODO: b/485304482 - Implement this method if needed..
bool RemoveKeyPrefix(absl::string_view prefix) override { return false; }
};
} // namespace nearby::apple
@@ -38,7 +38,7 @@ bool Timer::Create(int delay, int interval, absl::AnyInvocable<void()> callback)
return false;
}
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
if (timer_ != nullptr) {
GNCLoggerError(@"Timer has already started.");
return false;
@@ -59,7 +59,7 @@ bool Timer::Create(int delay, int interval, absl::AnyInvocable<void()> callback)
absl::AnyInvocable<void()> callback_to_run = nullptr;
bool is_one_shot = (intervalInNanoseconds == DISPATCH_TIME_FOREVER);
{
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
// If Stop() was called concurrently, the callback will be null.
if (!callback_ || callback_running_) {
return;
@@ -76,7 +76,7 @@ bool Timer::Create(int delay, int interval, absl::AnyInvocable<void()> callback)
callback_to_run();
}
{
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
if (!is_one_shot && callback_to_run) {
// For periodic timers, move the callback back for the next run.
callback_ = std::move(callback_to_run);
@@ -93,7 +93,7 @@ bool Timer::Create(int delay, int interval, absl::AnyInvocable<void()> callback)
}
bool Timer::Stop() {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
if (timer_ != nullptr) {
dispatch_source_cancel(timer_);
timer_ = nullptr;
@@ -25,10 +25,8 @@
#include "absl/status/status.h"
#include "absl/strings/string_view.h"
#include "internal/account/account_manager_impl.h"
#include "internal/platform/count_down_latch.h"
#include "internal/platform/crypto.h"
#include "internal/platform/implementation/account_manager.h"
#include "internal/platform/logging.h"
#include "internal/platform/tachyon_express_signaling_messenger.h"
#include "internal/proto/tachyon.pb.h"
@@ -69,6 +69,8 @@ cc_library(
"@com_google_absl//absl/time",
"@com_google_absl//absl/types:span",
"@com_google_nisaba//nisaba/port:thread_pool",
"@com_google_protobuf//:protobuf",
"@com_google_protobuf//json",
"@nlohmann_json//:json",
],
alwayslink = 1,
@@ -30,6 +30,8 @@
#include "internal/base/file_path.h"
#include "internal/platform/implementation/g3/preferences_repository.h"
#include "internal/platform/logging.h"
#include "google/protobuf/json/json.h"
#include "google/protobuf/message.h"
namespace nearby {
namespace g3 {
@@ -105,6 +107,18 @@ bool PreferencesManager::SetTime(absl::string_view key, absl::Time value) {
return Commit();
}
bool PreferencesManager::SetProtoMessage(absl::string_view key,
const google::protobuf::Message& value) {
std::string json_string;
if (!proto2::json::MessageToJsonString(value, &json_string).ok()) {
return false;
}
{
absl::MutexLock lock(mutex_);
return SetValue(key, json::parse(json_string));
}
}
// Get JSON value.
json PreferencesManager::Get(absl::string_view key,
const json& default_value) const {
@@ -171,12 +185,36 @@ absl::Time PreferencesManager::GetTime(absl::string_view key,
return absl::FromUnixNanos(result->get<int64_t>());
}
bool PreferencesManager::GetProtoMessage(absl::string_view key,
google::protobuf::Message* value) const {
absl::MutexLock lock(mutex_);
auto result = value_.find(absl::StrCat(key));
if (result == value_.end()) {
return false;
}
return proto2::json::JsonStringToMessage(result->dump(), value)
.ok();
}
// Removes preferences
void PreferencesManager::Remove(absl::string_view key) {
absl::MutexLock lock(mutex_);
value_.erase(absl::StrCat(key));
}
bool PreferencesManager::RemoveKeyPrefix(absl::string_view prefix) {
absl::MutexLock lock(mutex_);
auto it = value_.begin();
while (it != value_.end()) {
if (it.key().starts_with(prefix)) {
it = value_.erase(it);
} else {
++it;
}
}
return true;
}
// Private methods
// Writes data to storage.
@@ -31,6 +31,7 @@
#include "internal/base/file_path.h"
#include "internal/platform/implementation/g3/preferences_repository.h"
#include "internal/platform/implementation/preferences_manager.h"
#include "google/protobuf/message.h"
namespace nearby {
namespace g3 {
@@ -73,6 +74,10 @@ class PreferencesManager : public api::PreferencesManager {
bool SetTime(absl::string_view key, absl::Time value) override
ABSL_LOCKS_EXCLUDED(mutex_);
bool SetProtoMessage(absl::string_view key,
const google::protobuf::Message& value) override
ABSL_LOCKS_EXCLUDED(mutex_);
// Gets values
nlohmann::json Get(absl::string_view key,
const nlohmann::json& default_value) const override
@@ -106,8 +111,14 @@ class PreferencesManager : public api::PreferencesManager {
absl::Time default_value) const override
ABSL_LOCKS_EXCLUDED(mutex_);
bool GetProtoMessage(absl::string_view key,
google::protobuf::Message* value) const override
ABSL_LOCKS_EXCLUDED(mutex_);
// Removes preferences
void Remove(absl::string_view key) override ABSL_LOCKS_EXCLUDED(mutex_);
bool RemoveKeyPrefix(absl::string_view prefix) override
ABSL_LOCKS_EXCLUDED(mutex_);
private:
// Writes data to storage.
@@ -66,17 +66,17 @@ class WifiHotspotServerSocket : public api::WifiHotspotServerSocket {
static std::string GetName(absl::string_view ip_address, int port);
void SetIPAddress(const std::string& ip_address) ABSL_LOCKS_EXCLUDED(mutex_) {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
ip_address_ = ip_address;
}
int GetPort() const override ABSL_LOCKS_EXCLUDED(mutex_) {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
return port_;
}
void SetPort(int port) ABSL_LOCKS_EXCLUDED(mutex_) {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
port_ = port;
}
@@ -24,6 +24,7 @@
#include "absl/time/time.h"
#include "absl/types/span.h"
#include "nlohmann/json_fwd.hpp"
#include "google/protobuf/message.h"
namespace nearby {
namespace api {
@@ -59,6 +60,9 @@ class PreferencesManager {
virtual bool SetTime(absl::string_view key, absl::Time value) = 0;
virtual bool SetProtoMessage(absl::string_view key,
const google::protobuf::Message& value) = 0;
// Gets values
virtual nlohmann::json Get(absl::string_view key,
const nlohmann::json& default_value) const = 0;
@@ -83,8 +87,15 @@ class PreferencesManager {
virtual absl::Time GetTime(absl::string_view key,
absl::Time default_value) const = 0;
virtual bool GetProtoMessage(absl::string_view key,
google::protobuf::Message* value) const = 0;
// Removes preferences
virtual void Remove(absl::string_view key) = 0;
// Removes all preferences that start with the given prefix.
// Returns false on error.
virtual bool RemoveKeyPrefix(absl::string_view prefix) = 0;
};
} // namespace api
@@ -24,7 +24,7 @@ namespace shared {
CountDownLatch::CountDownLatch(int count) : count_(count) {}
ExceptionOr<bool> CountDownLatch::Await(absl::Duration timeout) {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
absl::Time deadline = absl::Now() + timeout;
while (count_ > 0) {
if (cond_.WaitWithDeadline(&mutex_, deadline)) {
@@ -35,14 +35,14 @@ ExceptionOr<bool> CountDownLatch::Await(absl::Duration timeout) {
}
Exception CountDownLatch::Await() {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
while (count_ > 0) {
cond_.Wait(&mutex_);
}
return {Exception::kSuccess};
}
void CountDownLatch::CountDown() {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
if (count_ > 0 && --count_ == 0) {
cond_.SignalAll();
}
@@ -12,6 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
load("@com_google_protobuf//bazel:cc_proto_library.bzl", "cc_proto_library")
load("@com_google_protobuf//bazel:proto_library.bzl", "proto_library")
load("@rules_cc//cc:cc_library.bzl", "cc_library")
load("@rules_cc//cc:cc_test.bzl", "cc_test")
@@ -374,6 +376,8 @@ cc_library(
"@com_google_absl//absl/time",
"@com_google_absl//absl/types:optional",
"@com_google_absl//absl/types:span",
"@com_google_protobuf//:protobuf",
"@com_google_protobuf//json",
"@nlohmann_json//:json",
],
)
@@ -418,6 +422,20 @@ cc_library(
],
)
proto_library(
name = "preferences_manager_test_proto",
testonly = True,
srcs = ["preferences_manager_test.proto"],
compatible_with = ["//buildenv/target:non_prod"],
)
cc_proto_library(
name = "preferences_manager_test_cc_proto",
testonly = True,
compatible_with = ["//buildenv/target:non_prod"],
deps = [":preferences_manager_test_proto"],
)
cc_test(
name = "impl_test",
size = "small",
@@ -451,6 +469,7 @@ cc_test(
tags = ["nozapfhahn"],
deps = [
":crypto",
":preferences_manager_test_cc_proto",
":test_utils",
":types",
":windows",
@@ -462,6 +481,7 @@ cc_test(
"//internal/platform/implementation:types",
"//internal/platform/implementation/shared:count_down_latch",
"//internal/platform/implementation/windows/generated:types",
"//net/proto2/contrib/parse_proto:parse_text_proto",
"@com_github_protobuf_matchers//protobuf-matchers",
"@com_google_absl//absl/status",
"@com_google_absl//absl/strings",
@@ -27,15 +27,10 @@
#include <vector>
#include "absl/functional/any_invocable.h"
#include "absl/strings/escaping.h"
#include "absl/strings/str_format.h"
#include "absl/strings/str_join.h"
#include "absl/strings/string_view.h"
#include "absl/synchronization/mutex.h"
#include "absl/types/optional.h"
#include "internal/flags/nearby_flags.h"
#include "internal/platform/byte_array.h"
#include "internal/platform/flags/nearby_platform_feature_flags.h"
#include "internal/platform/implementation/ble.h"
#include "internal/platform/implementation/windows/bluetooth_adapter.h"
#include "internal/platform/implementation/windows/utils.h"
@@ -48,8 +43,7 @@
#include "winrt/Windows.Foundation.h"
#include "winrt/Windows.Storage.Streams.h"
namespace nearby {
namespace windows {
namespace nearby::windows {
namespace {
using ::winrt::Windows::Devices::Bluetooth::BluetoothCacheMode;
@@ -66,8 +60,6 @@ using ::winrt::Windows::Devices::Bluetooth::GenericAttributeProfile::
GattCommunicationStatus;
using ::winrt::Windows::Devices::Bluetooth::GenericAttributeProfile::
GattDeviceService;
using ::winrt::Windows::Devices::Bluetooth::GenericAttributeProfile::
GattDeviceServicesResult;
using ::winrt::Windows::Devices::Bluetooth::GenericAttributeProfile::
GattReadResult;
using ::winrt::Windows::Devices::Bluetooth::GenericAttributeProfile::
@@ -665,5 +657,4 @@ void BleGattClient::OnCharacteristicValueChanged(
}
}
} // namespace windows
} // namespace nearby
} // namespace nearby::windows
@@ -25,11 +25,9 @@
#include <utility>
#include <vector>
#include "absl/container/flat_hash_map.h"
#include "absl/functional/any_invocable.h"
#include "absl/status/status.h"
#include "absl/strings/escaping.h"
#include "absl/strings/str_format.h"
#include "absl/synchronization/mutex.h"
#include "absl/time/clock.h"
#include "absl/time/time.h"
@@ -45,8 +43,7 @@
#include "winrt/Windows.Storage.Streams.h"
#include "winrt/base.h"
namespace nearby {
namespace windows {
namespace nearby::windows {
namespace {
using ::winrt::Windows::Devices::Bluetooth::BluetoothError;
@@ -78,8 +75,6 @@ using ::winrt::Windows::Devices::Bluetooth::GenericAttributeProfile::
GattServiceProviderAdvertisingParameters;
using ::winrt::Windows::Devices::Bluetooth::GenericAttributeProfile::
GattServiceProviderResult;
using ::winrt::Windows::Devices::Bluetooth::GenericAttributeProfile::
GattSubscribedClient;
using ::winrt::Windows::Devices::Bluetooth::GenericAttributeProfile::
GattWriteRequestedEventArgs;
using ::winrt::Windows::Foundation::Collections::IVectorView;
@@ -753,5 +748,4 @@ BleGattServer::FindGattCharacteristicData(
return nullptr;
}
} // namespace windows
} // namespace nearby
} // namespace nearby::windows
@@ -19,17 +19,14 @@
#include <memory>
#include "absl/synchronization/mutex.h"
#include "absl/synchronization/notification.h"
#include "internal/platform/exception.h"
#include "internal/platform/implementation/ble.h"
#include "internal/platform/implementation/bluetooth_adapter.h"
#include "internal/platform/implementation/windows/ble_socket.h"
#include "internal/platform/implementation/windows/bluetooth_adapter.h"
#include "internal/platform/implementation/windows/utils.h"
#include "internal/platform/logging.h"
namespace nearby {
namespace windows {
namespace nearby::windows {
BleServerSocket::BleServerSocket(api::BluetoothAdapter* adapter)
: adapter_(dynamic_cast<BluetoothAdapter*>(adapter)) {
@@ -53,7 +50,6 @@ std::unique_ptr<api::ble::BleSocket> BleServerSocket::Accept() {
}
Exception BleServerSocket::Close() {
// TODO(b/271031645): implement BLE socket using weave
absl::MutexLock lock(mutex_);
VLOG(1) << __func__ << ": Close is called.";
@@ -68,10 +64,8 @@ Exception BleServerSocket::Close() {
}
bool BleServerSocket::Bind() {
// TODO(b/271031645): implement BLE socket using weave
LOG(ERROR) << __func__ << ": GATT socket started.";
return true;
}
} // namespace windows
} // namespace nearby
} // namespace nearby::windows
@@ -57,8 +57,7 @@ typedef std::basic_string<TCHAR> tstring;
#define BLUETOOTH_RADIO_REGISTRY_NAME_KEY "Local Name"
namespace nearby {
namespace windows {
namespace nearby::windows {
namespace {
struct LocalSettings {
std::string original_radio_name;
@@ -545,7 +544,7 @@ bool BluetoothAdapter::SetName(absl::string_view name, bool persist) {
// lpWideCharStr.
nullptr, // Pointer to a buffer that receives the converted string.
0, // Size, in bytes, of the buffer indicated by lpMultiByteStr.
NULL, // Pointer to the character to use if a character cannot be
nullptr, // Pointer to the character to use if a character cannot be
// represented in the specified code page.
&defaultCharUsed); // Pointer to a flag that indicates if the function
// has used a default character in the conversion.
@@ -570,8 +569,8 @@ bool BluetoothAdapter::SetName(absl::string_view name, bool persist) {
.data(), // Pointer to a buffer that receives the converted string.
guid_str_size, // Size, in bytes, of the buffer indicated by
// lpMultiByteStr.
NULL, // // Pointer to the character to use if a character cannot be
// represented in the specified code page.
nullptr, // Pointer to the character to use if a character cannot be
// represented in the specified code page.
&defaultCharUsed); // // Pointer to a flag that indicates if the
// function has used a default character in the
// conversion.
@@ -613,11 +612,11 @@ bool BluetoothAdapter::SetName(absl::string_view name, bool persist) {
// opened.
GENERIC_WRITE, // The requested access to the file or device.
0, // The requested sharing mode of the file or device.
NULL, // A pointer to a SECURITY_ATTRIBUTES structure.
nullptr, // A pointer to a SECURITY_ATTRIBUTES structure.
OPEN_EXISTING, // An action to take on a file or device that exists or
// does not exist.
0, // The file or device attributes and flags.
NULL); // A valid handle to a template file with the GENERIC_READ
nullptr); // A valid handle to a template file with the GENERIC_READ
// access right. This parameter can be NULL.
if (hDevice == INVALID_HANDLE_VALUE) {
@@ -656,7 +655,7 @@ bool BluetoothAdapter::SetName(absl::string_view name, bool persist) {
return false;
}
if (name != "") {
if (!name.empty()) {
// Sets the data and type of a specified value under a registry key.
// https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regsetvalueexa
status = RegSetValueExA(
@@ -703,12 +702,12 @@ bool BluetoothAdapter::SetName(absl::string_view name, bool persist) {
&reload, // A pointer to the input buffer that contains the data
// required to perform the operation.
sizeof(reload), // The size of the input buffer, in bytes.
NULL, // A pointer to the output buffer that is to receive the data
// returned by the operation.
0, // The size of the output buffer, in bytes.
&bytes, // A pointer to a variable that receives the size of the
// data stored in the output buffer, in bytes.
NULL)) { // A pointer to an OVERLAPPED structure.
nullptr, // A pointer to the output buffer that is to receive the
// data returned by the operation.
0, // The size of the output buffer, in bytes.
&bytes, // A pointer to a variable that receives the size of the
// data stored in the output buffer, in bytes.
nullptr)) { // A pointer to an OVERLAPPED structure.
LOG(ERROR) << __func__
<< ": Failed to update radio module local name. Error code: "
<< GetLastError();
@@ -777,7 +776,8 @@ BluetoothAdapter::GetGenericBluetoothAdapterInstanceID() const {
// computer.
// https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdigetclassdevsa
hDevInfo =
SetupDiGetClassDevsA(&GUID_DEVCLASS_BLUETOOTH, NULL, NULL, DIGCF_PRESENT);
SetupDiGetClassDevsA(&GUID_DEVCLASS_BLUETOOTH, /*Enumerator=*/nullptr,
/*hwndParent=*/nullptr, DIGCF_PRESENT);
if (hDevInfo == INVALID_HANDLE_VALUE) {
LOG(ERROR) << __func__
@@ -904,5 +904,4 @@ std::string BluetoothAdapter::GetNameFromComputerName() const {
return "";
}
} // namespace windows
} // namespace nearby
} // namespace nearby::windows
@@ -77,12 +77,6 @@ MacAddress BluetoothDevice::GetMacAddress() const { return mac_address_; }
// Checks cache first, will check uncached if no result.
RfcommDeviceService BluetoothDevice::GetRfcommServiceForIdAsync(
RfcommServiceId serviceId) {
if (nearby::NearbyFlags::GetInstance().GetBoolFlag(
platform::config_package_nearby::nearby_platform_feature::
kEnableNewBluetoothRefactor)) {
return GetRfcommServiceForIdWithRetryAsync(serviceId);
}
try {
LOG(INFO) << __func__ << ": Get RF services for service id:"
<< winrt::to_string(serviceId.AsString());
@@ -146,29 +146,19 @@ bool BluetoothSocket::Connect(HostName connection_host_name,
LOG(INFO) << __func__ << ": start to connect to bluetooth service:"
<< winrt::to_string(connection_service_name);
if (nearby::NearbyFlags::GetInstance().GetBoolFlag(
platform::config_package_nearby::nearby_platform_feature::
kEnableNewBluetoothRefactor)) {
int connect_called_count = 0;
while (connect_called_count < kMaxConnectRetryCount) {
connect_called_count += 1;
bool connect_result =
InternalConnect(connection_host_name, connection_service_name);
if (connect_result) {
return connect_result;
}
} else {
int connect_called_count = 0;
while (connect_called_count < kMaxConnectRetryCount) {
connect_called_count += 1;
bool connect_result =
InternalConnect(connection_host_name, connection_service_name);
if (connect_result) {
return connect_result;
}
LOG(WARNING) << __func__ << ": Failed to connect bluetooth at the "
<< connect_called_count << "th call.";
LOG(WARNING) << __func__ << ": Failed to connect bluetooth at the "
<< connect_called_count << "th call.";
absl::SleepFor(kConnectInterval);
}
absl::SleepFor(kConnectInterval);
}
LOG(WARNING) << __func__ << ": Failed to connect bluetooth";
@@ -22,7 +22,6 @@
#include <utility>
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "internal/platform/implementation/bluetooth_classic.h"
#include "internal/platform/implementation/windows/generated/winrt/impl/Windows.Devices.Enumeration.0.h"
#include "internal/platform/logging.h"
@@ -31,8 +30,7 @@
#include "winrt/Windows.Foundation.Collections.h"
#include "winrt/base.h"
namespace nearby {
namespace windows {
namespace nearby::windows {
namespace {
using ::winrt::Windows::Devices::Bluetooth::BluetoothDevice;
@@ -44,7 +42,6 @@ using ::winrt::Windows::Devices::Enumeration::DevicePairingResult;
using ::winrt::Windows::Devices::Enumeration::DevicePairingResultStatus;
using ::winrt::Windows::Devices::Enumeration::DeviceUnpairingResult;
using ::winrt::Windows::Devices::Enumeration::DeviceUnpairingResultStatus;
using ::winrt::Windows::Foundation::IAsyncOperation;
using PairingError = ::nearby::api::BluetoothPairingCallback::PairingError;
using PairingType = ::nearby::api::PairingParams::PairingType;
} // namespace
@@ -322,5 +319,4 @@ void BluetoothPairing::OnPair(DevicePairingResult& pairing_result) {
pairing_callback_.on_pairing_error_cb(PairingError::kFailed);
}
} // namespace windows
} // namespace nearby
} // namespace nearby::windows
@@ -83,38 +83,12 @@
#include "internal/platform/os_name.h"
#include "internal/platform/payload_id.h"
namespace nearby {
namespace api {
namespace nearby::api {
namespace {
constexpr char kNCRelativePath[] = "Google/Nearby/Connections";
std::string GetApplicationName(DWORD pid) {
HANDLE handle =
OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE,
pid); // Modify pid to the pid of your application
if (!handle) {
return "";
}
std::string szProcessName("", MAX_PATH);
DWORD len = MAX_PATH;
if (NULL != handle) {
GetModuleFileNameExA(handle, nullptr, szProcessName.data(), len);
}
szProcessName.resize(szProcessName.find_first_of('\0') + 1);
auto just_the_file_name_and_ext = szProcessName.substr(
szProcessName.find_last_of('\\') + 1,
szProcessName.length() - szProcessName.find_last_of('\\') + 1);
return just_the_file_name_and_ext.substr(
0, just_the_file_name_and_ext.find_last_of('.'));
}
} // namespace
std::string ImplementationPlatform::GetCustomSavePath(
@@ -253,7 +227,6 @@ ImplementationPlatform::CreateBluetoothClassicMedium(
return std::make_unique<windows::BluetoothClassicMedium>(adapter);
}
// TODO(b/184975123): replace with real implementation.
std::unique_ptr<api::ble::BleMedium> ImplementationPlatform::CreateBleMedium(
api::BluetoothAdapter& adapter) {
return std::make_unique<windows::BleMedium>(adapter);
@@ -264,7 +237,6 @@ ImplementationPlatform::CreateCredentialStorage() {
return nullptr;
}
// TODO(b/184975123): replace with real implementation.
std::unique_ptr<WifiMedium> ImplementationPlatform::CreateWifiMedium() {
return std::make_unique<windows::WifiMedium>();
}
@@ -287,7 +259,6 @@ ImplementationPlatform::CreateWifiDirectMedium() {
return std::make_unique<windows::WifiDirectMedium>();
}
// TODO(b/261663238) replace with real implementation.
std::unique_ptr<WebRtcMedium> ImplementationPlatform::CreateWebRtcMedium() {
return nullptr;
}
@@ -318,5 +289,4 @@ ImplementationPlatform::CreatePreferencesManager(absl::string_view path) {
return std::make_unique<windows::PreferencesManager>(FilePath{path});
}
} // namespace api
} // namespace nearby
} // namespace nearby::api
@@ -30,6 +30,8 @@
#include "internal/base/file_path.h"
#include "internal/platform/implementation/windows/preferences_repository.h"
#include "internal/platform/logging.h"
#include "google/protobuf/json/json.h"
#include "google/protobuf/message.h"
namespace nearby::windows {
namespace {
@@ -104,6 +106,18 @@ bool PreferencesManager::SetTime(absl::string_view key, absl::Time value) {
return Commit();
}
bool PreferencesManager::SetProtoMessage(absl::string_view key,
const google::protobuf::Message& value) {
std::string json_string;
if (!proto2::json::MessageToJsonString(value, &json_string).ok()) {
return false;
}
{
absl::MutexLock lock(mutex_);
return SetValue(key, json::parse(json_string));
}
}
// Get JSON value.
json PreferencesManager::Get(absl::string_view key,
const json& default_value) const {
@@ -170,12 +184,36 @@ absl::Time PreferencesManager::GetTime(absl::string_view key,
return absl::FromUnixNanos(result->get<int64_t>());
}
bool PreferencesManager::GetProtoMessage(absl::string_view key,
google::protobuf::Message* value) const {
absl::MutexLock lock(mutex_);
auto result = value_.find(absl::StrCat(key));
if (result == value_.end()) {
return false;
}
return proto2::json::JsonStringToMessage(result->dump(), value)
.ok();
}
// Removes preferences
void PreferencesManager::Remove(absl::string_view key) {
absl::MutexLock lock(mutex_);
value_.erase(absl::StrCat(key));
}
bool PreferencesManager::RemoveKeyPrefix(absl::string_view prefix) {
absl::MutexLock lock(mutex_);
auto it = value_.begin();
while (it != value_.end()) {
if (it.key().starts_with(prefix)) {
it = value_.erase(it);
} else {
++it;
}
}
return true;
}
// Private methods
// Writes data to storage.
@@ -31,6 +31,7 @@
#include "internal/base/file_path.h"
#include "internal/platform/implementation/preferences_manager.h"
#include "internal/platform/implementation/windows/preferences_repository.h"
#include "google/protobuf/message.h"
namespace nearby {
namespace windows {
@@ -73,6 +74,10 @@ class PreferencesManager : public api::PreferencesManager {
bool SetTime(absl::string_view key, absl::Time value) override
ABSL_LOCKS_EXCLUDED(mutex_);
bool SetProtoMessage(absl::string_view key,
const google::protobuf::Message& value) override
ABSL_LOCKS_EXCLUDED(mutex_);
// Gets values
nlohmann::json Get(absl::string_view key,
const nlohmann::json& default_value) const override
@@ -106,8 +111,14 @@ class PreferencesManager : public api::PreferencesManager {
absl::Time default_value) const override
ABSL_LOCKS_EXCLUDED(mutex_);
bool GetProtoMessage(absl::string_view key,
google::protobuf::Message* value) const override
ABSL_LOCKS_EXCLUDED(mutex_);
// Removes preferences
void Remove(absl::string_view key) override ABSL_LOCKS_EXCLUDED(mutex_);
bool RemoveKeyPrefix(absl::string_view prefix) override
ABSL_LOCKS_EXCLUDED(mutex_);
private:
// Writes data to storage.
@@ -21,7 +21,11 @@
#include <string>
#include <vector>
#include "net/proto2/contrib/parse_proto/parse_text_proto.h"
#include "gmock/gmock.h"
#include "protobuf-matchers/protocol-buffer-matchers.h"
#include "gtest/gtest.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "absl/time/clock.h"
#include "absl/time/time.h"
@@ -31,10 +35,15 @@
#include "internal/base/file_path.h"
#include "internal/base/files.h"
#include "internal/platform/logging.h"
#include "internal/platform/implementation/windows/preferences_manager_test.proto.h"
namespace nearby {
namespace windows {
namespace {
using ::proto2::contrib::parse_proto::ParseTextProtoOrDie;
using ::protobuf_matchers::EqualsProto;
using ::testing::IsEmpty;
using json = ::nlohmann::json;
constexpr absl::string_view kPreferencesFilePath = "Google/Nearby/Sharing";
} // namespace
@@ -184,5 +193,47 @@ TEST(PreferencesManager, RemoveKey) {
EXPECT_EQ(result, "default key");
}
TEST(PreferencesManager, RemoveKeyPrefix) {
constexpr absl::string_view kKeyPrefix = "test_key_prefix.";
auto pm = PreferencesManager(FilePath{kPreferencesFilePath});
for (int i = 0; i < 10; ++i) {
pm.SetString(absl::StrCat(kKeyPrefix, i), absl::StrCat("value", i));
}
constexpr absl::string_view string_key = "string_key";
pm.SetString(string_key, "this is a test string");
EXPECT_EQ(pm.GetString(string_key, ""), "this is a test string");
EXPECT_TRUE(pm.RemoveKeyPrefix(kKeyPrefix));
for (int i = 0; i < 10; ++i) {
EXPECT_THAT(pm.GetString(absl::StrCat(kKeyPrefix, i), ""),
IsEmpty());
}
EXPECT_EQ(pm.GetString(string_key, ""), "this is a test string");
}
TEST(PreferencesManager, SetAndGetProtoMessage) {
std::string proto_key = "proto_key";
PreferencesManager pm(FilePath{kPreferencesFilePath});
windows::tests::SyncConfig sync_config = ParseTextProtoOrDie(R"pb(
folders {
id: "folder_id"
label: "test_folder"
index_id: 1
max_sequence: 100
}
folders {
id: "folder_id2"
label: "test_folder2"
index_id: 2
max_sequence: 200
}
)pb");
windows::tests::SyncConfig sync_config_out;
EXPECT_FALSE(pm.GetProtoMessage(proto_key, &sync_config_out));
pm.SetProtoMessage(proto_key, sync_config);
EXPECT_TRUE(pm.GetProtoMessage(proto_key, &sync_config_out));
EXPECT_THAT(sync_config_out, EqualsProto(sync_config));
}
} // namespace windows
} // namespace nearby
@@ -0,0 +1,31 @@
// Copyright 2026 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.
syntax = "proto2";
package nearby.windows.tests;
option java_multiple_files = true;
option java_outer_classname = "PreferencesManagerTest";
message SyncConfig {
repeated SyncFolder folders = 1;
}
message SyncFolder {
optional string id = 1;
optional string label = 2;
optional int32 index_id = 3;
optional int64 max_sequence = 4;
}
@@ -56,7 +56,10 @@ using ::winrt::Windows::Devices::WiFiDirect::
using ::winrt::Windows::Devices::WiFiDirect::WiFiDirectConnectionRequest;
using ::winrt::Windows::Security::Credentials::PasswordCredential;
constexpr absl::Duration kConnectTimeout = absl::Milliseconds(500);
// Wifi connection metrics show P90 latency is just under 600ms.
// Assuming the hotspot connection latency is similar to the wifi
// connection latency.
constexpr absl::Duration kConnectTimeout = absl::Milliseconds(700);
} // namespace
WifiHotspotMedium::~WifiHotspotMedium() {
@@ -36,7 +36,6 @@
namespace nearby::windows {
namespace {
// mDNS information for advertising and discovery
const char kMdnsHostName[] = "%s.local";
const char kMdnsInstanceNameFormat[] = "%s.%slocal";
// Timeout for starting mDNS service
@@ -80,7 +80,9 @@ constexpr absl::string_view kMdnsDeviceSelectorFormat =
constexpr absl::string_view kDisableMdnsAdvertisingRegistryValue =
"disable_mdns_advertising";
constexpr absl::Duration kConnectTimeout = absl::Milliseconds(500);
// From metrics, P90 wifi connection latency is just under 600ms.
// Set to 700ms to be slightly more generous than the P90.
constexpr absl::Duration kConnectTimeout = absl::Milliseconds(700);
bool IsSelfInstance(IMapView<winrt::hstring, IInspectable> properties,
absl::string_view self_instance_name) {
@@ -770,21 +772,10 @@ api::UpgradeAddressInfo WifiLanMedium::GetUpgradeAddressCandidates(
}
}
}
if (NearbyFlags::GetInstance().GetBoolFlag(
platform::config_package_nearby::nearby_platform_feature::
kEnableWifiLanAddressCandidates)) {
// Append v4 addresses to the end of the list.
result.address_candidates.insert(result.address_candidates.end(),
ipv4_addresses.begin(),
ipv4_addresses.end());
} else {
// If kEnableWifiLanAddressCandidates is disabled, only return the last v4
// address.
result.address_candidates.clear();
if (!ipv4_addresses.empty()) {
result.address_candidates.push_back(ipv4_addresses.back());
}
}
// Append v4 addresses to the end of the list.
result.address_candidates.insert(result.address_candidates.end(),
ipv4_addresses.begin(),
ipv4_addresses.end());
return result;
}
+1 -1
View File
@@ -1147,7 +1147,7 @@ void MediumEnvironment::UnregisterWifiHotspotMedium(
}
void MediumEnvironment::SetFeatureFlags(const FeatureFlags::Flags& flags) {
const_cast<FeatureFlags&>(FeatureFlags::GetInstance()).SetFlags(flags);
FeatureFlags::GetMutableInstanceForTesting().SetFlags(flags);
}
std::optional<FakeClock*> MediumEnvironment::GetSimulatedClock() {
+8 -8
View File
@@ -40,7 +40,7 @@ TaskRunnerImpl::TaskRunnerImpl(uint32_t runner_count) {
TaskRunnerImpl::~TaskRunnerImpl() {
{
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
if (closed_) {
return;
}
@@ -51,7 +51,7 @@ TaskRunnerImpl::~TaskRunnerImpl() {
void TaskRunnerImpl::Shutdown() {
absl::flat_hash_map<uint64_t, std::unique_ptr<Timer>> timers;
{
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
closed_ = true;
timers = std::move(timers_map_);
}
@@ -65,7 +65,7 @@ void TaskRunnerImpl::Shutdown() {
bool TaskRunnerImpl::PostTask(absl::AnyInvocable<void()> task) {
{
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
if (closed_) {
return false;
}
@@ -81,7 +81,7 @@ bool TaskRunnerImpl::PostTask(absl::AnyInvocable<void()> task) {
bool TaskRunnerImpl::PostDelayedTask(absl::Duration delay,
absl::AnyInvocable<void()> task) {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
if (closed_) {
return false;
}
@@ -94,10 +94,10 @@ bool TaskRunnerImpl::PostDelayedTask(absl::Duration delay,
[this, id, task = std::move(task)]() mutable {
std::unique_ptr<Timer> timer;
{
absl::MutexLock lock(&mutex_);
if (closed_) {
return;
}
absl::MutexLock lock(mutex_);
if (closed_) {
return;
}
timer = std::move(timers_map_.extract(id).mapped());
}
PostTask(std::move(task));
+3 -3
View File
@@ -31,7 +31,7 @@ bool TimerImpl::Start(int delay, int period,
if (period < 0) {
period = 0;
}
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
if (internal_timer_ != nullptr) {
LOG(INFO) << "The timer is already running.";
return false;
@@ -47,7 +47,7 @@ bool TimerImpl::Start(int delay, int period,
}
void TimerImpl::Stop() {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
if (internal_timer_ == nullptr) {
return;
}
@@ -57,7 +57,7 @@ void TimerImpl::Stop() {
}
bool TimerImpl::IsRunning() {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
return (internal_timer_ != nullptr);
}
+1 -1
View File
@@ -53,8 +53,8 @@ cc_test(
"//internal/platform:logging",
"//internal/platform/implementation/g3", # build_cleaner: keep
"//proto:connections_enums_cc_proto",
"//third_party/protobuf",
"@com_github_protobuf_matchers//protobuf-matchers",
"@com_google_googletest//:gtest_main",
"@com_google_protobuf//:protobuf",
],
)
@@ -352,6 +352,9 @@ message ConnectionsLog {
// the device attestation is initiated, to the moment the device attestation
// is finished.
optional int64 device_attestation_latency_millis = 14;
// The error code returned by Play Integrity API during device attestation.
optional int64 play_integrity_error_code = 15;
}
message DeviceInfo {
@@ -445,6 +448,17 @@ message ConnectionsLog {
// The supported service.
optional location.nearby.proto.connections.SupportedService
supported_service = 14;
// The speed test report.
optional SpeedTestReport speed_test_report = 15;
}
message SpeedTestReport {
// The throughput in kbytes per second.
optional int32 throughput_kbytes_per_sec = 1;
// Whether the throughput is incoming or outgoing.
optional bool is_incoming = 2;
}
// Contains the transfer statistics for a DCT payload.
@@ -482,6 +496,9 @@ message ConnectionsLog {
// True if this payload transfer is an attempt to resume an interrupted
// payload after a reconnection. False if it's a new payload transfer.
optional bool is_resumption = 5;
// The data speed report in kbyte per second using global bytes counter
optional int32 data_speed_report_kbyte_per_sec = 6;
}
// A Payload transferred (or attempted to be transferred) between devices.
+4 -1
View File
@@ -20,7 +20,10 @@ cc_library(
name = "utils",
hdrs = ["utils.h"],
compatible_with = ["//buildenv/target:non_prod"],
visibility = ["//:__subpackages__"],
visibility = [
"//:__subpackages__",
"//location/nearby/sharing/lib:__subpackages__",
],
deps = [
"//third_party/grpc:grpc++",
"@com_google_absl//absl/functional:any_invocable",
+8 -8
View File
@@ -22,30 +22,30 @@
namespace nearby {
FakeClock::~FakeClock() {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
observers_.clear();
}
absl::Time FakeClock::Now() const {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
return now_;
}
void FakeClock::AddObserver(absl::string_view name,
std::function<void()> observer) {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
observers_.emplace(name, std::move(observer));
}
void FakeClock::RemoveObserver(absl::string_view name) {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
observers_.erase(name);
}
void FakeClock::FastForward(absl::Duration duration) {
std::vector<std::string> timer_callback_ids;
{
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
now_ += duration;
for (const auto& observer : observers_) {
timer_callback_ids.push_back(observer.first);
@@ -59,7 +59,7 @@ void FakeClock::FastForward(absl::Duration duration) {
std::function<void()> callback;
{
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
is_alive_timer = observers_.contains(timer_callback_id);
if (!is_alive_timer) {
continue;
@@ -72,12 +72,12 @@ void FakeClock::FastForward(absl::Duration duration) {
}
int FakeClock::GetObserversCount() {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
return observers_.size();
}
void FakeClock::Reset() {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
return observers_.clear();
}
+3 -3
View File
@@ -30,12 +30,12 @@ namespace nearby {
FakeTaskRunner::~FakeTaskRunner() { Shutdown(); }
void FakeTaskRunner::Shutdown() {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
task_executor_->Shutdown();
}
bool FakeTaskRunner::PostTask(absl::AnyInvocable<void()> task) {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
task_executor_->Execute([task = std::move(task)]() mutable {
task();
});
@@ -44,7 +44,7 @@ bool FakeTaskRunner::PostTask(absl::AnyInvocable<void()> task) {
bool FakeTaskRunner::PostDelayedTask(absl::Duration delay,
absl::AnyInvocable<void()> task) {
absl::MutexLock lock(&mutex_);
absl::MutexLock lock(mutex_);
std::unique_ptr<Timer> timer = std::make_unique<FakeTimer>(clock_);
Timer* timer_ptr = timer.get();
timers_.push_back(std::move(timer));
+59 -1
View File
@@ -97,7 +97,10 @@ enum Medium {
// //depot/google3/java/com/google/android/gms/nearby/internal/connection/api.proto,
// //depot/google3/third_party/nearby/connections/implementation/proto/offline_wire_formats.proto,
// //depot/google3/wireless/android/stats/platform/westworld/public/protos/enums/android/nearby/connections/enums.proto,
// //depot/google3/third_party/nearby/connections/c/nc_types.h
// //depot/google3/third_party/nearby/connections/c/nc_types.h,
// //depot/google3/logs/proto/wireless/android/backup/os_migration_log.proto:BandwidthChangedEvent.Medium,
// //depot/google3/java/com/google/android/gmscore/integ/modules/smartdevice/src/com/google/android/gms/smartdevice/logging/gil/SemanticLogger.kt,
// //depot/google3/javatests/com/google/android/gmscore/integ/modules/smartdevice/tests/robolectric/src/com/google/android/gms/smartdevice/logging/gil/SemanticLoggerTest.kt
// )
// LINT.IfChange
@@ -1389,6 +1392,61 @@ enum OperationResultCode {
DCT_ERROR_LOCAL_ATTESTATION_TIMEOUT = 5032;
// Parallel attestation timeout
DCT_ERROR_PARALLEL_ATTESTATION_TIMEOUT = 5033;
// Failed to start MDNS discovery on the remote device
DCT_ERROR_REMOTE_MDNS_DISCOVERY_TIMEOUT = 5034;
// Failed to register MDNS service on the remote device
DCT_ERROR_REMOTE_MDNS_REGISTER_SERVICE = 5035;
// Failed to send request on the remote device
DCT_ERROR_REMOTE_REQUEST_FAILED = 5036;
// Failed to receive response on the remote device
DCT_ERROR_REMOTE_RESPONSE_FAILED = 5037;
// Failed to exchange control messages on the remote device
DCT_ERROR_REMOTE_CONTROL_MESSAGE_EXCHANGE = 5038;
// DCT device capability mismatch on the remote device
DCT_ERROR_REMOTE_CAPABILITY_MISMATCH = 5039;
// High speed medium is unavailable on the remote device
DCT_ERROR_REMOTE_HIGH_SPEED_MEDIUM_UNAVAILABLE = 5040;
// Wifi is disabled on the remote device
DCT_ERROR_REMOTE_WIFI_DISABLED = 5041;
// Wifi is disconnected on the remote device
DCT_ERROR_REMOTE_WIFI_DISCONNECTED = 5042;
// Failed to transfer wifi credential on the remote device
DCT_ERROR_REMOTE_WIFI_CREDENTIAL_TRANSFER = 5043;
// Failed to connect to wifi internet on the remote device
DCT_ERROR_REMOTE_WIFI_INTERNET_CONNECTION = 5044;
// Failed to upgrade to high speed medium on the remote device
DCT_ERROR_REMOTE_UPGRADE_HIGH_SPEED_MEDIUM_FAILED = 5045;
// User cancellation on the remote device
DCT_ERROR_REMOTE_USER_CANCELLED = 5046;
// Service cancellation on the remote device
DCT_ERROR_REMOTE_SERVICE_CANCELLED = 5047;
// Failed to verify integrity on the remote device
DCT_ERROR_REMOTE_UNVERIFIED_INTEGRITY = 5048;
// Failed to upgrade to high speed medium due to low speed
DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED_LOW_SPEED = 5049;
// Failed to upgrade to high speed medium due to connection error
DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED_CONNECTION = 5050;
// Failed to upgrade to high speed medium because USB is not plugged in
DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED_USB_NOT_PLUGGED = 5051;
// Failed to upgrade to high speed medium because USB is not host
DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED_USB_NOT_HOST = 5052;
// Failed to upgrade to high speed medium because MDNS discovery is not
// started
DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED_MDNS_DISCOVERY_NOT_STARTED = 5053;
// Failed to upgrade to high speed medium because MDNS discovery is not
// started
DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED_NO_MEDIUM = 5054;
// Failed to upgrade to high speed medium because USB network is not started
DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED_USB_NETWORK_NOT_STARTED = 5055;
// Failed to upgrade to high speed medium because medium negotiation fails
DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED_MEDIUM_NEGOTIATION = 5056;
// Failed to upgrade to high speed medium because host fails to start
DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED_HOST_NOT_STARTED = 5057;
// Failed to upgrade to high speed medium because host network is not
// available
DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED_HOST_NETWORK_NOT_AVAILABLE = 5058;
// Failed to upgrade to high speed medium because no incoming HTTP connection
DCT_ERROR_UPGRADE_HIGH_SPEED_MEDIUM_FAILED_NO_INCOMING_HTTP_CONNECTION = 5059;
}
enum StopAdvertisingReason {
+22 -3
View File
@@ -74,10 +74,12 @@ cc_library(
name = "types",
srcs = [
"advertisement.cc",
"advertisement_capabilities.cc",
"share_target.cc",
],
hdrs = [
"advertisement.h",
"advertisement_capabilities.h",
"constants.h",
"nearby_connection.h",
"nearby_connections_manager.h",
@@ -230,6 +232,8 @@ cc_library(
"//internal/base:file_path",
"//internal/base:files",
"//internal/platform:types",
"//location/nearby/sharing/lib/sync:sync_config_prefs_cc_proto",
"//location/nearby/sharing/lib/sync:sync_manager",
"//proto:sharing_enums_cc_proto",
"//sharing/analytics",
"//sharing/certificates",
@@ -380,6 +384,9 @@ cc_library(
"//internal/platform:types",
"//internal/platform/implementation:account_manager",
"//internal/platform/implementation:types",
"//location/nearby/sharing/lib/rpc:grpc_async_client_factory",
"//location/nearby/sharing/lib/rpc:sharing_rpc_client",
"//location/nearby/sharing/lib/sync:sync_manager",
"//proto:sharing_enums_cc_proto",
"//sharing/analytics",
"//sharing/certificates",
@@ -401,6 +408,7 @@ cc_library(
"//sharing/proto:wire_format_cc_proto",
"//sharing/scheduling",
"@com_google_absl//absl/base:core_headers",
"@com_google_absl//absl/base:nullability",
"@com_google_absl//absl/container:flat_hash_map",
"@com_google_absl//absl/container:flat_hash_set",
"@com_google_absl//absl/functional:any_invocable",
@@ -618,7 +626,6 @@ cc_test(
":transfer_metadata",
":transfer_metadata_matchers",
":types",
"//base:casts",
"//internal/analytics:mock_event_logger",
"//internal/base:file_path",
"//internal/base:files",
@@ -627,6 +634,7 @@ cc_test(
"//internal/platform/implementation:signin_attempt",
"//internal/test",
"//internal/test:mocks",
"//location/nearby/sharing/lib/rpc:fake_nearby_share_client",
"//sharing/analytics",
"//sharing/certificates",
"//sharing/certificates:test_support",
@@ -638,6 +646,7 @@ cc_test(
"//sharing/flags/generated:generated_flags",
"//sharing/internal/api:mock_sharing_platform",
"//sharing/internal/api:platform",
"//sharing/internal/public:pref_names",
"//sharing/internal/test:nearby_test",
"//sharing/local_device_data",
"//sharing/local_device_data:test_support",
@@ -725,6 +734,7 @@ cc_test(
"//internal/test",
"//sharing/common",
"//sharing/common:enum",
"//sharing/internal/public:pref_names",
"//sharing/internal/test:nearby_test",
"//sharing/local_device_data:test_support",
"//sharing/proto:enums_cc_proto",
@@ -733,7 +743,6 @@ cc_test(
"@com_google_absl//absl/strings:string_view",
"@com_google_absl//absl/synchronization",
"@com_google_absl//absl/time",
"@com_google_absl//absl/types:span",
"@com_google_googletest//:gtest_main",
],
)
@@ -929,11 +938,11 @@ cc_test(
"//sharing/internal/public:logging",
"//sharing/proto:wire_format_cc_proto",
"//sharing/proto/analytics:sharing_log_cc_proto",
"//third_party/protobuf",
"@com_github_protobuf_matchers//protobuf-matchers",
"@com_google_absl//absl/strings:string_view",
"@com_google_absl//absl/time",
"@com_google_googletest//:gtest_main",
"@com_google_protobuf//:protobuf",
],
)
@@ -1000,3 +1009,13 @@ cc_test(
"@com_google_googletest//:gtest_main",
],
)
cc_test(
name = "advertisement_capabilities_test",
srcs = ["advertisement_capabilities_test.cc"],
deps = [
":types",
"@com_github_protobuf_matchers//protobuf-matchers",
"@com_google_googletest//:gtest_main",
],
)
+33 -12
View File
@@ -23,11 +23,11 @@
#include <vector>
#include "absl/types/span.h"
#include "sharing/advertisement_capabilities.h"
#include "sharing/common/nearby_share_enums.h"
#include "sharing/internal/public/logging.h"
namespace nearby {
namespace sharing {
namespace nearby::sharing {
namespace {
// v1 advertisements:
@@ -57,6 +57,7 @@ enum class TlvTypes : uint8_t {
kUnknown = 0,
kQrCode = 1,
kVendorId = 2,
kCapabilities = 3,
};
// The length in bytes of the vendor ID in the TLV advertisement.
constexpr uint8_t kVendorIdLength = 1;
@@ -126,7 +127,7 @@ bool ParseHasDeviceName(uint8_t b) {
std::unique_ptr<Advertisement> Advertisement::NewInstance(
std::vector<uint8_t> salt, std::vector<uint8_t> encrypted_metadata_key,
ShareTargetType device_type, std::optional<std::string> device_name,
uint8_t vendor_id) {
uint8_t vendor_id, AdvertisementCapabilities capabilities) {
if (salt.size() != Advertisement::kSaltSize) {
LOG(ERROR) << "Failed to create advertisement because the salt did "
"not match the expected length "
@@ -153,17 +154,21 @@ std::unique_ptr<Advertisement> Advertisement::NewInstance(
// Using `new` to access a non-public constructor.
return std::make_unique<Advertisement>(
/* version= */ 0, std::move(salt), std::move(encrypted_metadata_key),
device_type, std::move(device_name), vendor_id);
device_type, std::move(device_name), vendor_id, std::move(capabilities));
}
std::vector<uint8_t> Advertisement::ToEndpointInfo() const {
std::vector<uint8_t> capabilities_data = capabilities_.ToBytes();
// We add 3 bytes for vendor ID because of type (1 byte), len (1 byte), and
// the ID itself (1 byte).
int size = kMinimumSize + (device_name_.has_value() ? 1 : 0) +
(device_name_.has_value() ? device_name_->size() : 0) +
(vendor_id_ != static_cast<uint8_t>(BlockedVendorId::kNone)
? (kTlvMinimumLength + kVendorIdLength)
: 0);
: 0) +
(capabilities_.IsEmpty() || capabilities_data.empty()
? 0
: (kTlvMinimumLength + capabilities_data.size()));
std::vector<uint8_t> endpoint_info;
endpoint_info.reserve(size);
@@ -190,6 +195,14 @@ std::vector<uint8_t> Advertisement::ToEndpointInfo() const {
// The vendor ID itself.
endpoint_info.push_back(vendor_id_);
}
// Add capabilities TLV
if (!capabilities_.IsEmpty() && !capabilities_data.empty()) {
VLOG(1) << "Adding capabilities to advertisement";
endpoint_info.push_back(static_cast<uint8_t>(TlvTypes::kCapabilities));
endpoint_info.push_back(static_cast<uint8_t>(capabilities_data.size()));
endpoint_info.insert(endpoint_info.end(), capabilities_data.begin(),
capabilities_data.end());
}
return endpoint_info;
}
@@ -204,7 +217,7 @@ std::unique_ptr<Advertisement> Advertisement::FromEndpointInfo(
return nullptr;
}
auto iter = endpoint_info.begin();
auto iter = endpoint_info.cbegin();
uint8_t first_byte = *iter++;
int version = ParseVersion(first_byte);
@@ -242,6 +255,7 @@ std::unique_ptr<Advertisement> Advertisement::FromEndpointInfo(
}
uint8_t vendor_id = static_cast<uint8_t>(BlockedVendorId::kNone);
AdvertisementCapabilities capabilities{};
while (endpoint_info.end() - iter >= kTlvMinimumLength) {
// We will parse a TLV element now.
TlvTypes type = static_cast<TlvTypes>(*iter++);
@@ -263,6 +277,11 @@ std::unique_ptr<Advertisement> Advertisement::FromEndpointInfo(
// TODO: b/341984671 - Implement handling for this TLV type.
iter += value_len;
break;
case TlvTypes::kCapabilities:
capabilities = AdvertisementCapabilities::Parse(
absl::MakeConstSpan(iter, value_len));
iter += value_len;
break;
default:
LOG(ERROR) << "Unknown TLV type: " << static_cast<uint8_t>(type);
iter += value_len;
@@ -272,7 +291,7 @@ std::unique_ptr<Advertisement> Advertisement::FromEndpointInfo(
return Advertisement::NewInstance(
std::move(salt), std::move(encrypted_metadata_key), device_type,
std::move(optional_device_name), vendor_id);
std::move(optional_device_name), vendor_id, std::move(capabilities));
// LINT.ThenChange(//depot/google3/third_party/nearby/connections/implementation/mediums/advertisements/advertisement_util.cc)
}
@@ -280,7 +299,8 @@ bool Advertisement::operator==(const Advertisement& other) const {
return version_ == other.version_ && salt_ == other.salt_ &&
encrypted_metadata_key_ == other.encrypted_metadata_key_ &&
device_type_ == other.device_type_ &&
device_name_ == other.device_name_ && vendor_id_ == other.vendor_id_;
device_name_ == other.device_name_ && vendor_id_ == other.vendor_id_ &&
capabilities_.ToBytes() == other.capabilities_.ToBytes();
}
// private
@@ -288,13 +308,14 @@ Advertisement::Advertisement(int version, std::vector<uint8_t> salt,
std::vector<uint8_t> encrypted_metadata_key,
ShareTargetType device_type,
std::optional<std::string> device_name,
uint8_t vendor_id)
uint8_t vendor_id,
AdvertisementCapabilities capabilities)
: version_(version),
salt_(std::move(salt)),
encrypted_metadata_key_(std::move(encrypted_metadata_key)),
device_type_(device_type),
device_name_(std::move(device_name)),
vendor_id_(vendor_id) {}
vendor_id_(vendor_id),
capabilities_(std::move(capabilities)) {}
} // namespace sharing
} // namespace nearby
} // namespace nearby::sharing
+10 -9
View File
@@ -23,10 +23,10 @@
#include <vector>
#include "absl/types/span.h"
#include "sharing/advertisement_capabilities.h"
#include "sharing/common/nearby_share_enums.h"
namespace nearby {
namespace sharing {
namespace nearby::sharing {
// An advertisement in the form of
// [VERSION|VISIBILITY][SALT][ACCOUNT_IDENTIFIER][LEN][DEVICE_NAME].
@@ -44,17 +44,17 @@ class Advertisement {
};
// LINT.ThenChange(//depot/google3/java/com/google/android/gmscore/integ/client/nearby/src/com/google/android/gms/nearby/sharing/SharingOptions.java:VendorId)
static std::unique_ptr<Advertisement> NewInstance(
std::vector<uint8_t> salt, std::vector<uint8_t> encrypted_metadata_key,
ShareTargetType device_type, std::optional<std::string> device_name,
uint8_t vendor_id);
uint8_t vendor_id, AdvertisementCapabilities capabilities);
// TODO: b/341967036 - Remove uses of std::optional for device name. Empty
// string should be enough.
Advertisement(int version, std::vector<uint8_t> salt,
std::vector<uint8_t> encrypted_metadata_key,
ShareTargetType device_type,
std::optional<std::string> device_name, uint8_t vendor_id);
std::optional<std::string> device_name, uint8_t vendor_id,
AdvertisementCapabilities capabilities);
~Advertisement() = default;
Advertisement(const Advertisement&) = default;
Advertisement& operator=(const Advertisement&) = default;
@@ -96,14 +96,15 @@ class Advertisement {
ShareTargetType device_type_ = ShareTargetType::kUnknown;
// The human-readable name of the remote device.
std::optional<std::string> device_name_ = std::nullopt;
const std::optional<std::string> device_name_;
// The vendor identifier of the remote device. Reference for vendor ID:
// google3/java/com/google/android/gmscore/integ/client/nearby/src/com/google/android/gms/nearby/sharing/SharingOptions.java
const uint8_t vendor_id_;
const AdvertisementCapabilities capabilities_;
};
} // namespace sharing
} // namespace nearby
} // namespace nearby::sharing
#endif // THIRD_PARTY_NEARBY_SHARING_ADVERTISEMENT_H_
+61
View File
@@ -0,0 +1,61 @@
// Copyright 2025 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 "sharing/advertisement_capabilities.h"
#include <cstdint>
#include <vector>
#include "absl/types/span.h"
#include "sharing/internal/public/logging.h"
namespace nearby::sharing {
constexpr uint8_t kFileSyncMask = 0b00000001;
AdvertisementCapabilities AdvertisementCapabilities::Parse(
absl::Span<const uint8_t> data) {
AdvertisementCapabilities capabilities{};
for (const uint8_t byte : data) {
switch (byte) {
case static_cast<uint8_t>(Capability::kFileSync):
capabilities.Add(Capability::kFileSync);
break;
default:
continue;
}
}
return capabilities;
}
std::vector<uint8_t> AdvertisementCapabilities::ToBytes() const {
std::vector<uint8_t> bytes;
for (const Capability capability : capabilities_) {
switch (capability) {
case Capability::kFileSync:
if (bytes.empty()) {
bytes.resize(1);
}
bytes[0] |= kFileSyncMask;
break;
default:
LOG(DFATAL) << "Unhandled capability: "
<< static_cast<uint8_t>(capability);
break;
}
}
return bytes;
}
} // namespace nearby::sharing
+55
View File
@@ -0,0 +1,55 @@
// Copyright 2025 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_SHARING_ADVERTISEMENT_CAPABILITIES_H_
#define THIRD_PARTY_NEARBY_SHARING_ADVERTISEMENT_CAPABILITIES_H_
#include <cstdint>
#include <initializer_list>
#include <vector>
#include "absl/types/span.h"
namespace nearby::sharing {
// A container class for storing capabilities to be added to QuickShare
// advertisements.
class AdvertisementCapabilities {
public:
enum class Capability {
kInvalid = 0,
kFileSync = 1, // File sync extension support.
};
// Parses serialized capabilities from an advertisement.
static AdvertisementCapabilities Parse(absl::Span<const uint8_t> data);
AdvertisementCapabilities(std::initializer_list<Capability> capabilities)
: capabilities_(capabilities) {}
void Add(Capability capability) { capabilities_.push_back(capability); }
// Returns true if there are no capabilities in this object.
bool IsEmpty() const { return capabilities_.empty(); }
// Serializes the capabilities into a byte array for inclusion in an
// advertisement.
std::vector<uint8_t> ToBytes() const;
private:
std::vector<Capability> capabilities_;
};
} // namespace nearby::sharing
#endif // THIRD_PARTY_NEARBY_SHARING_ADVERTISEMENT_CAPABILITIES_H_
@@ -0,0 +1,67 @@
// Copyright 2025 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 "sharing/advertisement_capabilities.h"
#include <cstdint>
#include "gmock/gmock.h"
#include "protobuf-matchers/protocol-buffer-matchers.h"
#include "gtest/gtest.h"
namespace nearby::sharing {
namespace {
TEST(AdvertisementCapabilitiesTest, ParseEmpty) {
EXPECT_TRUE(AdvertisementCapabilities::Parse({}).IsEmpty());
}
TEST(AdvertisementCapabilitiesTest, ParseFileSync) {
uint8_t data[] = {
static_cast<uint8_t>(AdvertisementCapabilities::Capability::kFileSync)};
AdvertisementCapabilities capabilities =
AdvertisementCapabilities::Parse(data);
EXPECT_FALSE(capabilities.IsEmpty());
EXPECT_THAT(capabilities.ToBytes(), testing::ElementsAre(0x01));
}
TEST(AdvertisementCapabilitiesTest, ToBytesEmpty) {
AdvertisementCapabilities capabilities({});
EXPECT_TRUE(capabilities.ToBytes().empty());
}
TEST(AdvertisementCapabilitiesTest, ToBytesFileSync) {
AdvertisementCapabilities capabilities(
{AdvertisementCapabilities::Capability::kFileSync});
EXPECT_THAT(capabilities.ToBytes(), testing::ElementsAre(0x01));
}
TEST(AdvertisementCapabilitiesTest, AddCapability) {
AdvertisementCapabilities capabilities({});
EXPECT_TRUE(capabilities.IsEmpty());
capabilities.Add(AdvertisementCapabilities::Capability::kFileSync);
EXPECT_FALSE(capabilities.IsEmpty());
EXPECT_THAT(capabilities.ToBytes(), testing::ElementsAre(0x01));
}
TEST(AdvertisementCapabilitiesTest, MultipleAdds) {
// Currently only kFileSync is supported.
AdvertisementCapabilities capabilities({});
capabilities.Add(AdvertisementCapabilities::Capability::kFileSync);
capabilities.Add(AdvertisementCapabilities::Capability::kFileSync);
// Duplicate adds should still result in bit 0 being set.
EXPECT_THAT(capabilities.ToBytes(), testing::ElementsAre(0x01));
}
} // namespace
} // namespace nearby::sharing
+23 -2
View File
@@ -21,6 +21,7 @@
#include "gtest/gtest.h"
#include "absl/types/span.h"
#include "sharing/advertisement_capabilities.h"
#include "sharing/common/nearby_share_enums.h"
namespace nearby {
@@ -43,6 +44,7 @@ struct TestParameters {
ShareTargetType target_type;
std::optional<std::string> target_name;
int vendor_id;
AdvertisementCapabilities capabilities;
};
class AdvertisementTest : public testing::TestWithParam<TestParameters> {};
@@ -51,17 +53,18 @@ TEST_P(AdvertisementTest, TestAdvertisementRoundTrip) {
auto params = GetParam();
auto advertisement = Advertisement::NewInstance(
params.salt, params.encrypted_metadata_key, params.target_type,
params.target_name, params.vendor_id);
params.target_name, params.vendor_id, params.capabilities);
auto bytes = advertisement->ToEndpointInfo();
auto advertisement_from_bytes = Advertisement::FromEndpointInfo(bytes);
EXPECT_EQ(*advertisement_from_bytes, *advertisement);
}
TEST(BadAdvertisementTest, TestTlvParsingOnAdvertisement) {
AdvertisementCapabilities capabilities{};
auto advertisement = Advertisement::NewInstance(
std::vector<uint8_t>(Advertisement::kSaltSize),
std::vector<uint8_t>(Advertisement::kMetadataEncryptionKeyHashByteSize),
ShareTargetType::kLaptop, std::nullopt, /*vendor_id=*/1);
ShareTargetType::kLaptop, std::nullopt, /*vendor_id=*/1, capabilities);
auto bytes = advertisement->ToEndpointInfo();
// Add a TLV field for QR code.
bytes.insert(bytes.end(), kQrCodeTlvBytes.begin(), kQrCodeTlvBytes.end());
@@ -149,6 +152,24 @@ INSTANTIATE_TEST_SUITE_P(
.target_type = ShareTargetType::kLaptop,
.target_name = std::nullopt,
.vendor_id = 0}));
INSTANTIATE_TEST_SUITE_P(
Capabilities, AdvertisementTest,
testing::Values(
TestParameters{.salt = std::vector<uint8_t>(Advertisement::kSaltSize),
.encrypted_metadata_key = std::vector<uint8_t>(
Advertisement::kMetadataEncryptionKeyHashByteSize),
.target_type = ShareTargetType::kPhone,
.target_name = std::nullopt,
.vendor_id = 0,
.capabilities = AdvertisementCapabilities{}},
TestParameters{.salt = std::vector<uint8_t>(Advertisement::kSaltSize),
.encrypted_metadata_key = std::vector<uint8_t>(
Advertisement::kMetadataEncryptionKeyHashByteSize),
.target_type = ShareTargetType::kPhone,
.target_name = std::nullopt,
.vendor_id = 0,
.capabilities = AdvertisementCapabilities{
AdvertisementCapabilities::Capability::kFileSync}}));
} // namespace
} // namespace sharing
+8 -7
View File
@@ -42,15 +42,16 @@ cc_library(
],
visibility = ["//visibility:public"],
deps = [
"//google/nearby/identity/v1:resources_cc_proto",
"//google/nearby/identity/v1:rpcs_cc_proto",
"//google/protobuf:timestamp_cc_proto",
"//internal/base",
"//internal/base:file_path",
"//internal/crypto_cros",
"//internal/platform:mac_address",
"//internal/platform:types",
"//internal/platform/implementation:account_manager",
"//proto/identity/v1:resources_cc_proto",
"//proto/identity/v1:rpcs_cc_proto",
"//sharing/common",
"//location/nearby/sharing/lib/rpc:sharing_rpc_client",
"//sharing/internal/api:platform",
"//sharing/internal/base",
"//sharing/internal/public:logging",
@@ -96,6 +97,7 @@ cc_library(
"//internal/base:bluetooth_address",
"//internal/base:file_path",
"//internal/crypto_cros",
"//location/nearby/sharing/lib/rpc:sharing_rpc_client",
"//sharing/common:enum",
"//sharing/internal/api:platform",
"//sharing/internal/public:types",
@@ -122,13 +124,13 @@ cc_test(
deps = [
":certificates",
":test_support",
"//google/nearby/identity/v1:resources_cc_proto",
"//google/nearby/identity/v1:rpcs_cc_proto",
"//internal/platform:mac_address",
"//internal/platform/implementation:account_manager",
"//internal/platform/implementation:platform_impl",
"//internal/test",
"//proto/identity/v1:resources_cc_proto",
"//proto/identity/v1:rpcs_cc_proto",
"//sharing/common",
"//location/nearby/sharing/lib/rpc:fake_nearby_share_client",
"//sharing/common:enum",
"//sharing/internal/api:mock_sharing_platform",
"//sharing/internal/api:platform",
@@ -140,7 +142,6 @@ cc_test(
"//sharing/scheduling",
"//sharing/scheduling:test_support",
"@com_github_protobuf_matchers//protobuf-matchers",
"@com_google_absl//absl/container:flat_hash_map",
"@com_google_absl//absl/functional:any_invocable",
"@com_google_absl//absl/status",
"@com_google_absl//absl/status:statusor",
@@ -23,12 +23,12 @@
#include <utility>
#include <vector>
#include "location/nearby/sharing/lib/rpc/sharing_rpc_client.h"
#include "internal/base/file_path.h"
#include "sharing/certificates/nearby_share_certificate_manager.h"
#include "sharing/certificates/nearby_share_encrypted_metadata_key.h"
#include "sharing/certificates/nearby_share_private_certificate.h"
#include "sharing/certificates/test_util.h"
#include "sharing/internal/api/sharing_rpc_client.h"
#include "sharing/internal/public/context.h"
#include "sharing/local_device_data/nearby_share_local_device_data_manager.h"
#include "sharing/proto/enums.pb.h"
@@ -50,7 +50,7 @@ FakeNearbyShareCertificateManager::Factory::CreateInstance(
nearby::Context* context,
NearbyShareLocalDeviceDataManager* local_device_data_manager,
const FilePath& profile_path,
nearby::sharing::api::SharingRpcClientFactory* client_factory) {
nearby::sharing::api::IdentityRpcClient* identity_client) {
auto instance = std::make_unique<FakeNearbyShareCertificateManager>();
instances_.push_back(instance.get());
@@ -24,12 +24,12 @@
#include <string>
#include <vector>
#include "location/nearby/sharing/lib/rpc/sharing_rpc_client.h"
#include "internal/base/file_path.h"
#include "sharing/certificates/nearby_share_certificate_manager.h"
#include "sharing/certificates/nearby_share_certificate_manager_impl.h"
#include "sharing/certificates/nearby_share_encrypted_metadata_key.h"
#include "sharing/certificates/nearby_share_private_certificate.h"
#include "sharing/internal/api/sharing_rpc_client.h"
#include "sharing/internal/public/context.h"
#include "sharing/local_device_data/nearby_share_local_device_data_manager.h"
#include "sharing/proto/rpc_resources.pb.h"
@@ -61,7 +61,7 @@ class FakeNearbyShareCertificateManager : public NearbyShareCertificateManager {
Context* context,
NearbyShareLocalDeviceDataManager* local_device_data_manager,
const FilePath& profile_path,
nearby::sharing::api::SharingRpcClientFactory* client_factory) override;
nearby::sharing::api::IdentityRpcClient* identity_client) override;
std::vector<FakeNearbyShareCertificateManager*> instances_;
};
@@ -28,7 +28,12 @@
#include <utility>
#include <vector>
#include "google/nearby/identity/v1/resources.pb.h"
#include "google/nearby/identity/v1/rpcs.pb.h"
#include "google/protobuf/timestamp.pb.h"
#include "location/nearby/sharing/lib/rpc/sharing_rpc_client.h"
#include "absl/algorithm/algorithm.h"
#include "absl/base/nullability.h"
#include "absl/container/flat_hash_map.h"
#include "absl/memory/memory.h"
#include "absl/status/statusor.h"
@@ -41,8 +46,6 @@
#include "internal/base/file_path.h"
#include "internal/platform/implementation/account_manager.h"
#include "internal/platform/mac_address.h"
#include "proto/identity/v1/resources.pb.h"
#include "proto/identity/v1/rpcs.pb.h"
#include "sharing/certificates/common.h"
#include "sharing/certificates/constants.h"
#include "sharing/certificates/nearby_share_certificate_manager.h"
@@ -55,7 +58,6 @@
#include "sharing/internal/api/preference_manager.h"
#include "sharing/internal/api/public_certificate_database.h"
#include "sharing/internal/api/sharing_platform.h"
#include "sharing/internal/api/sharing_rpc_client.h"
#include "sharing/internal/base/encode.h"
#include "sharing/internal/public/context.h"
#include "sharing/internal/public/logging.h"
@@ -199,12 +201,12 @@ NearbyShareCertificateManagerImpl::Factory::Create(
Context* context, SharingPlatform& sharing_platform,
NearbyShareLocalDeviceDataManager* local_device_data_manager,
const FilePath& profile_path,
nearby::sharing::api::SharingRpcClientFactory* client_factory) {
nearby::sharing::api::IdentityRpcClient* absl_nonnull identity_client) {
DCHECK(context);
if (test_factory_) {
return test_factory_->CreateInstance(context, local_device_data_manager,
profile_path, client_factory);
profile_path, identity_client);
}
FilePath database_path = profile_path;
@@ -213,7 +215,7 @@ NearbyShareCertificateManagerImpl::Factory::Create(
context, sharing_platform.GetPreferenceManager(),
sharing_platform.GetAccountManager(),
sharing_platform.CreatePublicCertificateDatabase(database_path),
local_device_data_manager, client_factory));
local_device_data_manager, identity_client));
}
// static
@@ -229,12 +231,12 @@ NearbyShareCertificateManagerImpl::NearbyShareCertificateManagerImpl(
AccountManager& account_manager,
std::unique_ptr<PublicCertificateDatabase> public_certificate_database,
NearbyShareLocalDeviceDataManager* local_device_data_manager,
nearby::sharing::api::SharingRpcClientFactory* client_factory)
nearby::sharing::api::IdentityRpcClient* absl_nonnull identity_client)
: context_(context),
account_manager_(account_manager),
local_device_data_manager_(local_device_data_manager),
preference_manager_(preference_manager),
nearby_identity_client_(client_factory->CreateIdentityInstance()),
nearby_identity_client_(identity_client),
certificate_storage_(NearbyShareCertificateStorageImpl::Factory::Create(
preference_manager, std::move(public_certificate_database))),
private_certificate_expiration_scheduler_(
@@ -418,7 +420,7 @@ bool NearbyShareCertificateManagerImpl::DownloadPublicCertificatesInExecutor() {
bool download_succeeded = false;
absl::Notification notification;
auto context = std::make_unique<CertificateDownloadContext>(
nearby_identity_client_.get(), std::move(device_id),
nearby_identity_client_, std::move(device_id),
[this, &download_succeeded, &notification](
absl::StatusOr<std::vector<PublicCertificate>> certificates_status) {
if (!certificates_status.ok()) {
@@ -494,7 +496,10 @@ void NearbyShareCertificateManagerImpl::AddCertifactesToPublishDeviceRequest(
shared_credential->set_data(public_cert->SerializeAsString());
shared_credential->set_data_type(
SharedCredential::DATA_TYPE_PUBLIC_CERTIFICATE);
*shared_credential->mutable_expiration_time() = public_cert->end_time();
shared_credential->mutable_expiration_time()->set_seconds(
public_cert->end_time().seconds());
shared_credential->mutable_expiration_time()->set_nanos(
public_cert->end_time().nanos());
}
LOG(INFO) << __func__ << ": PublishDevice: uploaded "
<< self_share_credential_count << " self share credentials and "
@@ -23,6 +23,7 @@
#include <utility>
#include <vector>
#include "location/nearby/sharing/lib/rpc/sharing_rpc_client.h"
#include "absl/base/nullability.h"
#include "absl/functional/any_invocable.h"
#include "absl/status/statusor.h"
@@ -37,7 +38,6 @@
#include "sharing/internal/api/preference_manager.h"
#include "sharing/internal/api/public_certificate_database.h"
#include "sharing/internal/api/sharing_platform.h"
#include "sharing/internal/api/sharing_rpc_client.h"
#include "sharing/internal/public/context.h"
#include "sharing/local_device_data/nearby_share_local_device_data_manager.h"
#include "sharing/proto/enums.pb.h"
@@ -68,7 +68,7 @@ class NearbyShareCertificateManagerImpl
nearby::sharing::api::SharingPlatform& sharing_platform,
NearbyShareLocalDeviceDataManager* local_device_data_manager,
const FilePath& profile_path,
nearby::sharing::api::SharingRpcClientFactory* client_factory);
nearby::sharing::api::IdentityRpcClient* absl_nonnull identity_client);
static void SetFactoryForTesting(Factory* test_factory);
protected:
@@ -77,7 +77,8 @@ class NearbyShareCertificateManagerImpl
Context* context,
NearbyShareLocalDeviceDataManager* local_device_data_manager,
const FilePath& profile_path,
nearby::sharing::api::SharingRpcClientFactory* client_factory) = 0;
nearby::sharing::api::IdentityRpcClient* absl_nonnull
identity_client) = 0;
private:
static Factory* test_factory_;
@@ -101,7 +102,8 @@ class NearbyShareCertificateManagerImpl
class CertificateDownloadContext {
public:
CertificateDownloadContext(
nearby::sharing::api::IdentityRpcClient* nearby_identity_client,
nearby::sharing::api::IdentityRpcClient* absl_nonnull
nearby_identity_client,
std::string device_id,
absl::AnyInvocable<void(absl::StatusOr<std::vector<
nearby::sharing::proto::PublicCertificate>>
@@ -119,7 +121,8 @@ class NearbyShareCertificateManagerImpl
void QuerySharedCredentialsFetchNextPage();
private:
nearby::sharing::api::IdentityRpcClient* const nearby_identity_client_;
nearby::sharing::api::IdentityRpcClient* absl_nonnull const
nearby_identity_client_;
std::string device_id_;
std::optional<std::string> next_page_token_;
int page_number_ = 1;
@@ -137,7 +140,7 @@ class NearbyShareCertificateManagerImpl
std::unique_ptr<nearby::sharing::api::PublicCertificateDatabase>
public_certificate_database,
NearbyShareLocalDeviceDataManager* local_device_data_manager,
nearby::sharing::api::SharingRpcClientFactory* client_factory);
nearby::sharing::api::IdentityRpcClient* absl_nonnull identity_client);
// NearbyShareCertificateManager:
void OnStartScheduledTasks() override;
@@ -197,8 +200,7 @@ class NearbyShareCertificateManagerImpl
NearbyShareLocalDeviceDataManager* const local_device_data_manager_;
nearby::sharing::api::PreferenceManager& preference_manager_;
int32_t vendor_id_ = 0; // Defaults to GOOGLE.
std::unique_ptr<nearby::sharing::api::SharingRpcClient> nearby_client_;
std::unique_ptr<nearby::sharing::api::IdentityRpcClient>
nearby::sharing::api::IdentityRpcClient* absl_nonnull const
nearby_identity_client_;
std::shared_ptr<NearbyShareCertificateStorage> certificate_storage_;
@@ -25,10 +25,12 @@
#include <utility>
#include <vector>
#include "google/nearby/identity/v1/resources.pb.h"
#include "google/nearby/identity/v1/rpcs.pb.h"
#include "location/nearby/sharing/lib/rpc/fake_nearby_share_client.h"
#include "gmock/gmock.h"
#include "protobuf-matchers/protocol-buffer-matchers.h"
#include "gtest/gtest.h"
#include "absl/container/flat_hash_map.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
@@ -38,8 +40,6 @@
#include "internal/platform/implementation/account_manager.h"
#include "internal/platform/mac_address.h"
#include "internal/test/fake_account_manager.h"
#include "proto/identity/v1/resources.pb.h"
#include "proto/identity/v1/rpcs.pb.h"
#include "sharing/certificates/constants.h"
#include "sharing/certificates/fake_nearby_share_certificate_storage.h"
#include "sharing/certificates/nearby_share_certificate_manager.h"
@@ -48,7 +48,6 @@
#include "sharing/certificates/nearby_share_encrypted_metadata_key.h"
#include "sharing/certificates/nearby_share_private_certificate.h"
#include "sharing/certificates/test_util.h"
#include "sharing/internal/api/fake_nearby_share_client.h"
#include "sharing/internal/api/mock_sharing_platform.h"
#include "sharing/internal/public/pref_names.h"
#include "sharing/internal/test/fake_bluetooth_adapter.h"
@@ -148,7 +147,7 @@ class NearbyShareCertificateManagerImplTest
cert_manager_ = NearbyShareCertificateManagerImpl::Factory::Create(
&fake_context_, mock_sharing_platform_,
local_device_data_manager_.get(),
/*profile_path=*/{}, &client_factory_);
/*profile_path=*/{}, &identity_client_);
cert_manager_->AddObserver(this);
cert_store_ = cert_store_factory_.instances().back();
@@ -193,10 +192,6 @@ class NearbyShareCertificateManagerImplTest
++num_private_certs_changed_notifications_;
}
FakeNearbyIdentityClient* GetIdentityClient() {
return client_factory_.identity_instances().back();
}
protected:
enum class DownloadPublicCertificatesResult {
kSuccess,
@@ -242,10 +237,11 @@ class NearbyShareCertificateManagerImplTest
}
void VerifyCertificatesUpload(bool expected_force_update_contacts) {
FakeNearbyIdentityClient* identity_client = GetIdentityClient();
ASSERT_FALSE(identity_client->publish_device_requests().empty());
std::vector<PublishDeviceRequest> publish_device_requests =
identity_client_.publish_device_requests();
ASSERT_FALSE(publish_device_requests.empty());
const PublishDeviceRequest& publish_device_request =
identity_client->publish_device_requests().back();
publish_device_requests.back();
EXPECT_EQ(publish_device_request.device().name(),
absl::StrCat("devices/", kDeviceId));
EXPECT_EQ(publish_device_request.device()
@@ -330,7 +326,6 @@ class NearbyShareCertificateManagerImplTest
void InvokeCertUploadPublishDevice(bool contacts_removed,
bool publish_device_success) {
FakeNearbyIdentityClient* identity_client = GetIdentityClient();
std::vector<absl::StatusOr<PublishDeviceResponse>> responses;
if (contacts_removed) {
// When contacts are removed, a second publish device call is scheduled.
@@ -342,7 +337,7 @@ class NearbyShareCertificateManagerImplTest
PublishDeviceResponse response;
response.add_contact_updates(PublishDeviceResponse::CONTACT_UPDATE_ADDED);
responses.push_back(response);
identity_client->SetPublishDeviceResponses(std::move(responses));
identity_client_.SetPublishDeviceResponses(std::move(responses));
upload_scheduler_->InvokeRequestCallback();
Sync();
@@ -351,7 +346,7 @@ class NearbyShareCertificateManagerImplTest
Sync();
Sync();
}
EXPECT_EQ(identity_client->publish_device_requests().size(),
EXPECT_EQ(identity_client_.publish_device_requests().size(),
contacts_removed ? 2 : 1);
VerifyCertificatesUpload(
@@ -385,15 +380,14 @@ class NearbyShareCertificateManagerImplTest
BuildQuerySharedCredentialsResponse(page_number, page_token));
}
FakeNearbyIdentityClient* identity_client = GetIdentityClient();
identity_client->SetQuerySharedCredentialsResponses(responses);
identity_client_.SetQuerySharedCredentialsResponses(responses);
cert_store_->SetAddPublicCertificatesResult(
result != DownloadPublicCertificatesResult::kStorageError);
download_scheduler_->InvokeRequestCallback();
Sync();
std::vector<QuerySharedCredentialsRequest> requests =
identity_client->query_shared_credentials_requests();
identity_client_.query_shared_credentials_requests();
EXPECT_EQ(requests.size(), num_pages);
EXPECT_EQ(requests.back().name(), absl::StrCat("devices/", kDeviceId));
ASSERT_EQ(download_scheduler_->handled_results().size(),
@@ -494,7 +488,7 @@ class NearbyShareCertificateManagerImplTest
std::vector<PublicCertificate> public_certificates_;
std::vector<NearbyShareEncryptedMetadataKey> metadata_encryption_keys_;
FakeNearbyShareClientFactory client_factory_;
FakeNearbyIdentityClient identity_client_;
FakeNearbyShareSchedulerFactory scheduler_factory_;
FakeNearbyShareCertificateStorage::Factory cert_store_factory_;
std::unique_ptr<FakeNearbyShareLocalDeviceDataManager>
@@ -762,7 +756,7 @@ TEST_F(NearbyShareCertificateManagerImplTest,
EXPECT_EQ(0, upload_scheduler_->num_immediate_requests());
EXPECT_TRUE(cert_store_->GetPrivateCertificates().empty());
EXPECT_TRUE(GetIdentityClient()->publish_device_requests().empty());
EXPECT_TRUE(identity_client_.publish_device_requests().empty());
}
TEST_F(NearbyShareCertificateManagerImplTest,
@@ -935,7 +929,7 @@ TEST_F(NearbyShareCertificateManagerImplTest,
upload_scheduler_->InvokeRequestCallback();
Sync();
EXPECT_TRUE(GetIdentityClient()->publish_device_requests().empty());
EXPECT_TRUE(identity_client_.publish_device_requests().empty());
EXPECT_EQ(upload_scheduler_->handled_results().size(), 1);
EXPECT_EQ(upload_scheduler_->handled_results().back(), false);
}
@@ -962,16 +956,15 @@ TEST_F(NearbyShareCertificateManagerImplTest, StopScheduledTasks) {
TEST_F(NearbyShareCertificateManagerImplTest,
UpdateAccountInfo_TitanumEnabled) {
Initialize();
FakeNearbyIdentityClient* identity_client = GetIdentityClient();
GetAccountInfoResponse response;
response.mutable_account_info()->mutable_capabilities()->Add(
AccountInfo::CAPABILITY_TITANIUM);
identity_client->SetGetAccountInfoResponse(response);
identity_client_.SetGetAccountInfoResponse(response);
account_info_update_scheduler_->InvokeRequestCallback();
Sync();
EXPECT_FALSE(GetIdentityClient()->get_account_info_requests().empty());
EXPECT_FALSE(identity_client_.get_account_info_requests().empty());
EXPECT_TRUE(preference_manager_.GetBoolean(
PrefNames::kAdvancedProtectionEnabled, /*default_value=*/false));
}
@@ -980,14 +973,13 @@ TEST_F(NearbyShareCertificateManagerImplTest,
UpdateAccountInfo_TitanumDisabled) {
Initialize();
preference_manager_.SetBoolean(PrefNames::kAdvancedProtectionEnabled, true);
FakeNearbyIdentityClient* identity_client = GetIdentityClient();
GetAccountInfoResponse response;
identity_client->SetGetAccountInfoResponse(response);
identity_client_.SetGetAccountInfoResponse(response);
account_info_update_scheduler_->InvokeRequestCallback();
Sync();
EXPECT_FALSE(GetIdentityClient()->get_account_info_requests().empty());
EXPECT_FALSE(identity_client_.get_account_info_requests().empty());
EXPECT_FALSE(preference_manager_.GetBoolean(
PrefNames::kAdvancedProtectionEnabled, /*default_value=*/false));
}
@@ -996,16 +988,15 @@ TEST_F(NearbyShareCertificateManagerImplTest,
UpdateAccountInfo_TitanumUnspecified) {
Initialize();
preference_manager_.SetBoolean(PrefNames::kAdvancedProtectionEnabled, true);
FakeNearbyIdentityClient* identity_client = GetIdentityClient();
GetAccountInfoResponse response;
response.mutable_account_info()->mutable_capabilities()->Add(
AccountInfo::CAPABILITY_UNSPECIFIED);
identity_client->SetGetAccountInfoResponse(response);
identity_client_.SetGetAccountInfoResponse(response);
account_info_update_scheduler_->InvokeRequestCallback();
Sync();
EXPECT_FALSE(GetIdentityClient()->get_account_info_requests().empty());
EXPECT_FALSE(identity_client_.get_account_info_requests().empty());
EXPECT_FALSE(preference_manager_.GetBoolean(
PrefNames::kAdvancedProtectionEnabled, /*default_value=*/false));
}
@@ -1019,7 +1010,7 @@ TEST_F(NearbyShareCertificateManagerImplTest,
Sync();
// Identity client by default return Status::NotFound.
EXPECT_FALSE(GetIdentityClient()->get_account_info_requests().empty());
EXPECT_FALSE(identity_client_.get_account_info_requests().empty());
EXPECT_TRUE(preference_manager_.GetBoolean(
PrefNames::kAdvancedProtectionEnabled, /*default_value=*/false));
}
@@ -36,11 +36,11 @@
#include "sharing/certificates/constants.h"
#include "sharing/certificates/nearby_share_certificate_storage.h"
#include "sharing/certificates/nearby_share_private_certificate.h"
#include "sharing/common/nearby_share_prefs.h"
#include "sharing/internal/api/preference_manager.h"
#include "sharing/internal/api/private_certificate_data.h"
#include "sharing/internal/api/public_certificate_database.h"
#include "sharing/internal/public/logging.h"
#include "sharing/internal/public/pref_names.h"
#include "sharing/proto/rpc_resources.pb.h"
#include "sharing/proto/timestamp.pb.h"
@@ -63,12 +63,6 @@ enum InitStatusMetric {
kMaxValue = kInvalidOperation
};
std::string EncodeString(absl::string_view unencoded_string) {
std::string result;
absl::WebSafeBase64Escape(unencoded_string, &result);
return result;
}
std::optional<std::string> DecodeString(const std::string* encoded_string) {
std::string result;
if (!encoded_string) return std::nullopt;
@@ -356,7 +350,7 @@ std::vector<NearbySharePrivateCertificate>
NearbyShareCertificateStorageImpl::GetPrivateCertificates() {
std::vector<PrivateCertificateData> list =
preference_manager_.GetPrivateCertificateArray(
prefs::kNearbySharingPrivateCertificateListName);
PrefNames::kPrivateCertificateList);
std::vector<NearbySharePrivateCertificate> certs;
certs.reserve(list.size());
for (const PrivateCertificateData& cert_data : list) {
@@ -397,7 +391,7 @@ void NearbyShareCertificateStorageImpl::ReplacePrivateCertificates(
list.push_back(cert.ToCertificateData());
}
preference_manager_.SetPrivateCertificateArray(
prefs::kNearbySharingPrivateCertificateListName, list);
PrefNames::kPrivateCertificateList, list);
}
void NearbyShareCertificateStorageImpl::AddPublicCertificates(
@@ -510,7 +504,7 @@ void NearbyShareCertificateStorageImpl::ClearPublicCertificates(
bool NearbyShareCertificateStorageImpl::FetchPublicCertificateExpirations() {
std::vector<std::pair<std::string, int64_t>> expirations =
preference_manager_.GetCertificateExpirationArray(
prefs::kNearbySharingPublicCertificateExpirationDictName);
PrefNames::kPublicCertificateExpirationDict);
public_certificate_expirations_.clear();
if (expirations.empty()) {
return false;
@@ -536,12 +530,12 @@ void NearbyShareCertificateStorageImpl::SavePublicCertificateExpirations() {
expirations.reserve(public_certificate_expirations_.size());
for (const std::pair<std::string, absl::Time>& pair :
public_certificate_expirations_) {
expirations.emplace_back(EncodeString(pair.first),
expirations.emplace_back(absl::WebSafeBase64Escape(pair.first),
absl::ToUnixNanos(pair.second));
}
preference_manager_.SetCertificateExpirationArray(
prefs::kNearbySharingPublicCertificateExpirationDictName, expirations);
PrefNames::kPublicCertificateExpirationDict, expirations);
}
} // namespace nearby::sharing
@@ -38,9 +38,9 @@
#include "sharing/certificates/nearby_share_certificate_storage.h"
#include "sharing/certificates/nearby_share_private_certificate.h"
#include "sharing/certificates/test_util.h"
#include "sharing/common/nearby_share_prefs.h"
#include "sharing/internal/api/mock_public_certificate_db.h"
#include "sharing/internal/api/private_certificate_data.h"
#include "sharing/internal/public/pref_names.h"
#include "sharing/internal/test/fake_preference_manager.h"
#include "sharing/internal/test/fake_public_certificate_db.h"
#include "sharing/proto/enums.pb.h"
@@ -104,12 +104,6 @@ constexpr char kMetadataEncryptionKey4[] = "metadataencryptionkey4";
constexpr char kEncryptedMetadataBytes4[] = "encryptedmetadatabytes4";
constexpr char kMetadataEncryptionKeyTag4[] = "metadataencryptionkeytag4";
std::string EncodeString(absl::string_view unencoded_string) {
std::string result;
absl::WebSafeBase64Escape(unencoded_string, &result);
return result;
}
PublicCertificate CreatePublicCertificate(
absl::string_view secret_id, absl::string_view secret_key,
absl::string_view public_key, int64_t start_seconds, int32_t start_nanos,
@@ -159,10 +153,8 @@ class NearbyShareCertificateStorageImplTest : public ::testing::Test {
NearbyShareCertificateStorageImplTest&) = delete;
void SetUp() override {
preference_manager_.Remove(
prefs::kNearbySharingPublicCertificateExpirationDictName);
preference_manager_.Remove(
prefs::kNearbySharingPrivateCertificateListName);
preference_manager_.Remove(PrefNames::kPublicCertificateExpirationDict);
preference_manager_.Remove(PrefNames::kPrivateCertificateList);
}
std::map<std::string, PublicCertificate> PrepopulatePublicCertificates() {
@@ -186,13 +178,12 @@ class NearbyShareCertificateStorageImplTest : public ::testing::Test {
std::vector<std::pair<std::string, int64_t>> expirations;
for (const auto& cert : pub_certs) {
expirations.emplace_back(
EncodeString(cert.secret_id()),
absl::WebSafeBase64Escape(cert.secret_id()),
absl::ToUnixNanos(TimestampToTime(cert.end_time())));
entries.emplace(cert.secret_id(), std::move(cert));
}
preference_manager_.SetCertificateExpirationArray(
prefs::kNearbySharingPublicCertificateExpirationDictName,
expirations);
PrefNames::kPublicCertificateExpirationDict, expirations);
return entries;
}
@@ -841,21 +832,20 @@ TEST_F(NearbyShareCertificateStorageImplTest,
std::vector<api::PrivateCertificateData> private_cert_data =
preference_manager_.GetPrivateCertificateArray(
prefs::kNearbySharingPrivateCertificateListName);
PrefNames::kPrivateCertificateList);
ASSERT_EQ(private_cert_data.size(), 3u);
// Set to invalid base64 encoded string.
private_cert_data[0].key_pair = "::..\\|@#";
preference_manager_.SetPrivateCertificateArray(
prefs::kNearbySharingPrivateCertificateListName, private_cert_data);
PrefNames::kPrivateCertificateList, private_cert_data);
std::vector<NearbySharePrivateCertificate> certs =
cert_store->GetPrivateCertificates();
// Verify corrupted cert has been removed.
EXPECT_TRUE(certs.empty());
private_cert_data =
preference_manager_.GetPrivateCertificateArray(
prefs::kNearbySharingPrivateCertificateListName);
private_cert_data = preference_manager_.GetPrivateCertificateArray(
PrefNames::kPrivateCertificateList);
EXPECT_TRUE(private_cert_data.empty());
}
@@ -188,7 +188,7 @@ NearbyShareDecryptedPublicCertificate::DecryptPublicCertificate(
return NearbyShareDecryptedPublicCertificate(
not_before, not_after, std::move(secret_key), std::move(public_key),
std::move(id), std::move(unencrypted_metadata),
public_certificate.for_self_share());
public_certificate.for_self_share(), public_certificate.binding_id());
}
NearbyShareDecryptedPublicCertificate::NearbyShareDecryptedPublicCertificate(
@@ -196,14 +196,15 @@ NearbyShareDecryptedPublicCertificate::NearbyShareDecryptedPublicCertificate(
std::unique_ptr<crypto::SymmetricKey> secret_key,
std::vector<uint8_t> public_key, std::vector<uint8_t> id,
nearby::sharing::proto::EncryptedMetadata unencrypted_metadata,
bool for_self_share)
bool for_self_share, std::string binding_id)
: not_before_(not_before),
not_after_(not_after),
secret_key_(std::move(secret_key)),
public_key_(std::move(public_key)),
id_(std::move(id)),
unencrypted_metadata_(std::move(unencrypted_metadata)),
for_self_share_(for_self_share) {}
for_self_share_(for_self_share),
binding_id_(std::move(binding_id)) {}
NearbyShareDecryptedPublicCertificate::NearbyShareDecryptedPublicCertificate(
const NearbyShareDecryptedPublicCertificate& other) {
@@ -223,6 +224,7 @@ NearbyShareDecryptedPublicCertificate::operator=(
id_ = other.id_;
unencrypted_metadata_ = other.unencrypted_metadata_;
for_self_share_ = other.for_self_share_;
binding_id_ = other.binding_id_;
return *this;
}
@@ -19,6 +19,7 @@
#include <memory>
#include <optional>
#include <string>
#include <vector>
#include "absl/time/time.h"
@@ -68,6 +69,8 @@ class NearbyShareDecryptedPublicCertificate {
bool for_self_share() const { return for_self_share_; }
const std::string& binding_id() const { return binding_id_; }
// Verifies the |signature| of the signed |payload| using |public_key_|.
// Returns true if verification was successful.
bool VerifySignature(absl::Span<const uint8_t> payload,
@@ -85,7 +88,7 @@ class NearbyShareDecryptedPublicCertificate {
std::unique_ptr<crypto::SymmetricKey> secret_key,
std::vector<uint8_t> public_key, std::vector<uint8_t> id,
nearby::sharing::proto::EncryptedMetadata unencrypted_metadata,
bool for_self_share);
bool for_self_share, std::string binding_id);
// The start and end times of the certificate's validity period. To avoid
// issues with clock skew, these times may be offset compared to the
@@ -111,6 +114,10 @@ class NearbyShareDecryptedPublicCertificate {
// Indicates if this public certificate is from another device owned by the
// same user.
bool for_self_share_ = false;
// The binding id of device pair binding. If multiple bindings exist
// between two devices, it will return the newest binding_id.
std::string binding_id_;
};
} // namespace sharing
@@ -50,6 +50,7 @@ TEST(NearbyShareDecryptedPublicCertificateTest, Decrypt) {
PublicCertificate proto_cert =
GetNearbyShareTestPublicCertificate(kTestPublicCertificateVisibility);
proto_cert.set_for_self_share(true);
proto_cert.set_binding_id("binding_id");
std::optional<NearbyShareDecryptedPublicCertificate> cert =
NearbyShareDecryptedPublicCertificate::DecryptPublicCertificate(
@@ -65,6 +66,7 @@ TEST(NearbyShareDecryptedPublicCertificateTest, Decrypt) {
EXPECT_EQ(GetNearbyShareTestMetadata().SerializeAsString(),
cert->unencrypted_metadata().SerializeAsString());
EXPECT_EQ(proto_cert.for_self_share(), cert->for_self_share());
EXPECT_EQ(proto_cert.binding_id(), cert->binding_id());
}
TEST(NearbyShareDecryptedPublicCertificateTest, Decrypt_IncorrectKeyFailure) {
@@ -92,12 +92,6 @@ std::optional<std::vector<uint8_t>> CreateMetadataEncryptionKeyTag(
return result;
}
std::string EncodeString(absl::string_view unencoded_string) {
std::string result;
absl::WebSafeBase64Escape(unencoded_string, &result);
return result;
}
std::optional<std::string> DecodeString(const std::string* encoded_string) {
std::string result;
if (!encoded_string) return std::nullopt;
@@ -109,7 +103,8 @@ std::optional<std::string> DecodeString(const std::string* encoded_string) {
}
std::string BytesToEncodedString(const std::vector<uint8_t>& bytes) {
return EncodeString(std::string(bytes.begin(), bytes.end()));
return absl::WebSafeBase64Escape(std::string_view(
reinterpret_cast<const char*>(bytes.data()), bytes.size()));
}
std::optional<std::vector<uint8_t>> EncodedStringToBytes(
@@ -319,11 +314,11 @@ PrivateCertificateData NearbySharePrivateCertificate::ToCertificateData()
.not_before = absl::ToUnixNanos(not_before_),
.not_after = absl::ToUnixNanos(not_after_),
.key_pair = BytesToEncodedString(key_pair),
.secret_key = EncodeString(secret_key_->key()),
.secret_key = absl::WebSafeBase64Escape(secret_key_->key()),
.metadata_encryption_key = BytesToEncodedString(metadata_encryption_key_),
.id = BytesToEncodedString(id_),
.unencrypted_metadata_proto =
EncodeString(unencrypted_metadata_.SerializeAsString()),
absl::WebSafeBase64Escape(unencrypted_metadata_.SerializeAsString()),
.consumed_salts = SaltsToString(consumed_salts_),
};
}
+5 -42
View File
@@ -16,7 +16,6 @@
#include <string>
#include "absl/base/attributes.h"
#include "sharing/internal/api/preference_manager.h"
#include "sharing/internal/public/pref_names.h"
#include "sharing/proto/enums.pb.h"
@@ -27,49 +26,10 @@ namespace prefs {
namespace {
using ::nearby::sharing::PrefNames;
using ::nearby::sharing::api::PreferenceManager;
using DataUsage = ::nearby::sharing::proto::DataUsage;
using FastInitiationNotificationState =
::nearby::sharing::proto::FastInitiationNotificationState;
using ::nearby::sharing::proto::DataUsage;
using ::nearby::sharing::proto::FastInitiationNotificationState;
} // namespace
ABSL_CONST_INIT const char* kNearbySharingBackgroundVisibilityName =
PrefNames::kVisibility.data();
ABSL_CONST_INIT const char* kNearbySharingBackgroundFallbackVisibilityName =
PrefNames::kFallbackVisibility.data();
ABSL_CONST_INIT const char*
kNearbySharingBackgroundVisibilityExpirationSeconds =
PrefNames::kVisibilityExpirationSeconds.data();
ABSL_CONST_INIT const char* kNearbySharingCustomSavePath =
PrefNames::kCustomSavePath.data();
ABSL_CONST_INIT const char* kNearbySharingDataUsageName =
PrefNames::kDataUsage.data();
ABSL_CONST_INIT const char* kNearbySharingDeviceIdName =
PrefNames::kDeviceId.data();
ABSL_CONST_INIT const char* kNearbySharingDeviceNameName =
PrefNames::kDeviceName.data();
ABSL_CONST_INIT const char* kNearbySharingFastInitiationNotificationStateName =
PrefNames::kFastInitiationNotificationState.data();
ABSL_CONST_INIT const char* kNearbySharingPrivateCertificateListName =
PrefNames::kPrivateCertificateList.data();
ABSL_CONST_INIT const char* kNearbySharingPublicCertificateExpirationDictName =
PrefNames::kPublicCertificateExpirationDict.data();
ABSL_CONST_INIT const char*
kNearbySharingSchedulerDownloadPublicCertificatesName =
PrefNames::kSchedulerDownloadPublicCertificates.data();
ABSL_CONST_INIT const char*
kNearbySharingSchedulerPrivateCertificateExpirationName =
PrefNames::kSchedulerPrivateCertificateExpiration.data();
ABSL_CONST_INIT const char*
kNearbySharingSchedulerPublicCertificateExpirationName =
PrefNames::kSchedulerPublicCertificateExpiration.data();
ABSL_CONST_INIT const char*
kNearbySharingSchedulerUploadLocalDeviceCertificatesName =
PrefNames::kSchedulerUploadLocalDeviceCertificates.data();
ABSL_CONST_INIT const char* kNearbySharingUsersName = PrefNames::kUsers.data();
ABSL_CONST_INIT const char* kNearbySharingIsAnalyticsEnabledName =
PrefNames::kIsAnalyticsEnabled.data();
void RegisterNearbySharingPrefs(PreferenceManager& preference_manager,
bool skip_persistent_ones) {
// These prefs are not synced across devices on purpose.
@@ -106,6 +66,9 @@ void RegisterNearbySharingPrefs(PreferenceManager& preference_manager,
preference_manager.Remove(PrefNames::kSchedulerUploadLocalDeviceCertificates);
preference_manager.Remove(PrefNames::kUsers);
preference_manager.SetBoolean(PrefNames::kAdvancedProtectionEnabled, false);
preference_manager.RemoveAllSyncConfigs();
preference_manager.RemoveAllBindingConfigs();
}
void ResetSchedulers(PreferenceManager& preference_manager) {

Some files were not shown because too many files have changed in this diff Show More