mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-14 22:56:12 -04:00
Added logic to stabilize endpoint IDs
PiperOrigin-RevId: 644407047
This commit is contained in:
committed by
Copybara-Service
parent
23031698dd
commit
4f386b95db
@@ -237,6 +237,7 @@ cc_test(
|
||||
deps = [
|
||||
":internal",
|
||||
":internal_test",
|
||||
"//base:casts",
|
||||
"//connections:core_types",
|
||||
"//connections/implementation/analytics",
|
||||
"//connections/implementation/flags:connections_flags",
|
||||
@@ -249,6 +250,7 @@ cc_test(
|
||||
"//internal/interop:authentication_transport_interface",
|
||||
"//internal/interop:device",
|
||||
"//internal/platform:base",
|
||||
"//internal/platform:cancellation_flag",
|
||||
"//internal/platform:comm",
|
||||
"//internal/platform:test_util",
|
||||
"//internal/platform:types",
|
||||
@@ -260,6 +262,7 @@ cc_test(
|
||||
"@com_google_absl//absl/base:core_headers",
|
||||
"@com_google_absl//absl/status",
|
||||
"@com_google_absl//absl/strings",
|
||||
"@com_google_absl//absl/strings:str_format",
|
||||
"@com_google_absl//absl/synchronization",
|
||||
"@com_google_absl//absl/time",
|
||||
"@com_google_absl//absl/types:span",
|
||||
|
||||
@@ -227,20 +227,34 @@ Status BasePcpHandler::StartAdvertising(
|
||||
"start-advertising",
|
||||
[this, client, &service_id, &info, &compatible_advertising_options,
|
||||
&response]() RUN_ON_PCP_HANDLER_THREAD() {
|
||||
// The endpoint id inside of the advertisement is different to high
|
||||
// visibility and low visibility mode. In order to decide if client
|
||||
// should grab the high visibility or low visibility id, it needs to
|
||||
// tell client which one right now, before
|
||||
// client#StartedAdvertising.
|
||||
if (ShouldEnterHighVisibilityMode(compatible_advertising_options)) {
|
||||
client->EnterHighVisibilityMode();
|
||||
if (NearbyFlags::GetInstance().GetBoolFlag(
|
||||
connections::config_package_nearby::nearby_connections_feature::
|
||||
kUseStableEndpointId)) {
|
||||
if (ShouldEnterStableEndpointIdMode(compatible_advertising_options)) {
|
||||
client->EnterStableEndpointIdMode();
|
||||
}
|
||||
} else {
|
||||
// The endpoint id inside of the advertisement is different to high
|
||||
// visibility and low visibility mode. In order to decide if client
|
||||
// should grab the high visibility or low visibility id, it needs to
|
||||
// tell client which one right now, before
|
||||
// client#StartedAdvertising.
|
||||
if (ShouldEnterHighVisibilityMode(compatible_advertising_options)) {
|
||||
client->EnterHighVisibilityMode();
|
||||
}
|
||||
}
|
||||
|
||||
auto result = StartAdvertisingImpl(
|
||||
client, service_id, client->GetLocalEndpointId(),
|
||||
info.endpoint_info, compatible_advertising_options);
|
||||
if (!result.status.Ok()) {
|
||||
client->ExitHighVisibilityMode();
|
||||
if (NearbyFlags::GetInstance().GetBoolFlag(
|
||||
connections::config_package_nearby::
|
||||
nearby_connections_feature::kUseStableEndpointId)) {
|
||||
client->ExitStableEndpointIdMode();
|
||||
} else {
|
||||
client->ExitHighVisibilityMode();
|
||||
}
|
||||
response.Set(result.status);
|
||||
return;
|
||||
}
|
||||
@@ -333,6 +347,17 @@ bool BasePcpHandler::ShouldEnterHighVisibilityMode(
|
||||
advertising_options.allowed.bluetooth;
|
||||
}
|
||||
|
||||
bool BasePcpHandler::ShouldEnterStableEndpointIdMode(
|
||||
const AdvertisingOptions& advertising_options) {
|
||||
if (advertising_options.use_stable_endpoint_id) {
|
||||
return true;
|
||||
} else if (advertising_options.low_power) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
BooleanMediumSelector BasePcpHandler::ComputeIntersectionOfSupportedMediums(
|
||||
const PendingConnectionInfo& connection_info) {
|
||||
absl::flat_hash_set<Medium> intersection;
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
@@ -25,28 +26,45 @@
|
||||
#include "absl/base/thread_annotations.h"
|
||||
#include "absl/container/btree_map.h"
|
||||
#include "absl/container/flat_hash_map.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 "connections/implementation/analytics/packet_meta_data.h"
|
||||
#include "connections/implementation/bwu_manager.h"
|
||||
#include "connections/implementation/client_proxy.h"
|
||||
#include "connections/implementation/encryption_runner.h"
|
||||
#include "connections/implementation/endpoint_channel.h"
|
||||
#include "connections/implementation/endpoint_channel_manager.h"
|
||||
#include "connections/implementation/endpoint_manager.h"
|
||||
#include "connections/implementation/mediums/mediums.h"
|
||||
#include "connections/implementation/mediums/webrtc_peer_id.h"
|
||||
#include "connections/implementation/pcp.h"
|
||||
#include "connections/implementation/pcp_handler.h"
|
||||
#include "connections/listeners.h"
|
||||
#include "connections/medium_selector.h"
|
||||
#include "connections/out_of_band_connection_metadata.h"
|
||||
#include "connections/params.h"
|
||||
#include "connections/status.h"
|
||||
#include "connections/strategy.h"
|
||||
#include "connections/v3/connection_listening_options.h"
|
||||
#include "connections/v3/listeners.h"
|
||||
#include "internal/interop/authentication_status.h"
|
||||
#include "internal/interop/device.h"
|
||||
#include "internal/interop/device_provider.h"
|
||||
#include "internal/platform/atomic_boolean.h"
|
||||
#include "internal/platform/ble_v2.h"
|
||||
#include "internal/platform/bluetooth_adapter.h"
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/platform/cancelable_alarm.h"
|
||||
#include "internal/platform/connection_info.h"
|
||||
#include "internal/platform/count_down_latch.h"
|
||||
#include "internal/platform/exception.h"
|
||||
#include "internal/platform/future.h"
|
||||
#include "internal/platform/prng.h"
|
||||
#include "internal/platform/mutex.h"
|
||||
#include "internal/platform/nsd_service_info.h"
|
||||
#include "internal/platform/runnable.h"
|
||||
#include "internal/platform/scheduled_executor.h"
|
||||
#include "internal/platform/single_thread_executor.h"
|
||||
|
||||
@@ -608,6 +626,13 @@ class BasePcpHandler : public PcpHandler,
|
||||
bool ShouldEnterHighVisibilityMode(
|
||||
const AdvertisingOptions& advertising_options);
|
||||
|
||||
// Below cases should enter stable endpoint id mode:
|
||||
// 1. When use stable endpoint id returns true.
|
||||
// 2. When low power returns false.
|
||||
// 3. Other cases return true.
|
||||
bool ShouldEnterStableEndpointIdMode(
|
||||
const AdvertisingOptions& advertising_options);
|
||||
|
||||
// Returns the intersection of supported mediums based on the mediums reported
|
||||
// by the remote client and the local client's advertising options.
|
||||
BooleanMediumSelector ComputeIntersectionOfSupportedMediums(
|
||||
|
||||
@@ -15,32 +15,46 @@
|
||||
#include "connections/implementation/client_proxy.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <functional>
|
||||
#include <ios>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/container/flat_hash_map.h"
|
||||
#include "absl/container/flat_hash_set.h"
|
||||
#include "absl/functional/any_invocable.h"
|
||||
#include "absl/strings/escaping.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/time/time.h"
|
||||
#include "absl/types/span.h"
|
||||
#include "connections/advertising_options.h"
|
||||
#include "connections/connection_options.h"
|
||||
#include "connections/discovery_options.h"
|
||||
#include "connections/implementation/analytics/analytics_recorder.h"
|
||||
#include "connections/implementation/flags/nearby_connections_feature_flags.h"
|
||||
#include "connections/listeners.h"
|
||||
#include "connections/medium_selector.h"
|
||||
#include "connections/payload.h"
|
||||
#include "connections/status.h"
|
||||
#include "connections/strategy.h"
|
||||
#include "connections/v3/bandwidth_info.h"
|
||||
#include "connections/v3/connection_listening_options.h"
|
||||
#include "connections/v3/connection_result.h"
|
||||
#include "connections/v3/connections_device.h"
|
||||
#include "connections/v3/connections_device_provider.h"
|
||||
#include "connections/v3/listeners.h"
|
||||
#include "internal/analytics/event_logger.h"
|
||||
#include "internal/flags/nearby_flags.h"
|
||||
#include "internal/interop/device.h"
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/platform/cancelable_alarm.h"
|
||||
#include "internal/platform/cancellation_flag.h"
|
||||
#include "internal/platform/error_code_params.h"
|
||||
#include "internal/platform/error_code_recorder.h"
|
||||
#include "internal/platform/feature_flags.h"
|
||||
#include "internal/platform/implementation/platform.h"
|
||||
@@ -52,18 +66,26 @@
|
||||
|
||||
namespace nearby {
|
||||
namespace connections {
|
||||
|
||||
namespace {
|
||||
using ::location::nearby::connections::OsInfo;
|
||||
|
||||
// The definition is necessary before C++17.
|
||||
constexpr absl::Duration
|
||||
ClientProxy::kHighPowerAdvertisementEndpointIdCacheTimeout;
|
||||
|
||||
constexpr char kEndpointIdChars[] = {
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
|
||||
'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
|
||||
'Y', 'Z', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0'};
|
||||
|
||||
bool IsFeatureUseStableEndpointIdEnabled() {
|
||||
return NearbyFlags::GetInstance().GetBoolFlag(
|
||||
connections::config_package_nearby::nearby_connections_feature::
|
||||
kUseStableEndpointId);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// The definition is necessary before C++17.
|
||||
constexpr absl::Duration
|
||||
ClientProxy::kHighPowerAdvertisementEndpointIdCacheTimeout;
|
||||
|
||||
ClientProxy::ClientProxy(::nearby::analytics::EventLogger* event_logger)
|
||||
: client_id_(Prng().NextInt64()) {
|
||||
NEARBY_LOGS(INFO) << "ClientProxy ctor event_logger=" << event_logger;
|
||||
@@ -96,18 +118,19 @@ std::string ClientProxy::GetLocalEndpointId() {
|
||||
MutexLock lock(&mutex_);
|
||||
if (!local_endpoint_id_.empty()) {
|
||||
NEARBY_LOGS(INFO) << __func__
|
||||
<< "Reusing cached endpoint id: " << local_endpoint_id_;
|
||||
<< ": Reusing cached endpoint id: " << local_endpoint_id_;
|
||||
return local_endpoint_id_;
|
||||
}
|
||||
if (external_device_provider_ == nullptr) {
|
||||
local_endpoint_id_ = GenerateLocalEndpointId();
|
||||
NEARBY_LOGS(INFO) << __func__ << "Locally generating endpoint id: "
|
||||
NEARBY_LOGS(INFO) << __func__ << ": Locally generating endpoint id: "
|
||||
<< local_endpoint_id_;
|
||||
} else {
|
||||
local_endpoint_id_ =
|
||||
external_device_provider_->GetLocalDevice()->GetEndpointId();
|
||||
NEARBY_LOGS(INFO)
|
||||
<< __func__ << "From external device provider, populating endpoint id: "
|
||||
<< __func__
|
||||
<< ": From external device provider, populating endpoint id: "
|
||||
<< local_endpoint_id_;
|
||||
}
|
||||
return local_endpoint_id_;
|
||||
@@ -146,13 +169,26 @@ void ClientProxy::SetBluetoothMacAddress(
|
||||
}
|
||||
|
||||
std::string ClientProxy::GenerateLocalEndpointId() {
|
||||
if (high_vis_mode_) {
|
||||
if (!local_high_vis_mode_cache_endpoint_id_.empty()) {
|
||||
NEARBY_LOGS(INFO)
|
||||
<< "ClientProxy [Local Endpoint Re-using cached endpoint id]: client="
|
||||
<< GetClientId() << "; local_high_vis_mode_cache_endpoint_id_="
|
||||
<< local_high_vis_mode_cache_endpoint_id_;
|
||||
return local_high_vis_mode_cache_endpoint_id_;
|
||||
if (IsFeatureUseStableEndpointIdEnabled()) {
|
||||
if (!cached_endpoint_id_.empty()) {
|
||||
if (stable_endpoint_id_mode_) {
|
||||
NEARBY_LOGS(INFO) << "ClientProxy [Local Endpoint Re-using cached "
|
||||
"endpoint id due to in stable endpoint id mode]: "
|
||||
"client="
|
||||
<< GetClientId()
|
||||
<< "; cached_endpoint_id_=" << cached_endpoint_id_;
|
||||
return cached_endpoint_id_;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (high_vis_mode_) {
|
||||
if (!cached_endpoint_id_.empty()) {
|
||||
NEARBY_LOGS(INFO) << "ClientProxy [Local Endpoint Re-using cached "
|
||||
"endpoint id]: client="
|
||||
<< GetClientId()
|
||||
<< "; cached_endpoint_id_=" << cached_endpoint_id_;
|
||||
return cached_endpoint_id_;
|
||||
}
|
||||
}
|
||||
}
|
||||
std::string id;
|
||||
@@ -169,7 +205,11 @@ void ClientProxy::Reset() {
|
||||
StoppedAdvertising();
|
||||
StoppedDiscovery();
|
||||
RemoveAllEndpoints();
|
||||
ExitHighVisibilityMode();
|
||||
if (IsFeatureUseStableEndpointIdEnabled()) {
|
||||
ExitStableEndpointIdMode();
|
||||
} else {
|
||||
ExitHighVisibilityMode();
|
||||
}
|
||||
}
|
||||
|
||||
void ClientProxy::StartedAdvertising(
|
||||
@@ -181,13 +221,22 @@ void ClientProxy::StartedAdvertising(
|
||||
NEARBY_LOGS(INFO) << "ClientProxy [StartedAdvertising]: client="
|
||||
<< GetClientId();
|
||||
|
||||
if (high_vis_mode_) {
|
||||
local_high_vis_mode_cache_endpoint_id_ = local_endpoint_id_;
|
||||
NEARBY_LOGS(INFO)
|
||||
<< "ClientProxy [High Visibility Mode Adv, Cache EndpointId]: client="
|
||||
<< GetClientId() << "; local_high_vis_mode_cache_endpoint_id_="
|
||||
<< local_high_vis_mode_cache_endpoint_id_;
|
||||
CancelClearLocalHighVisModeCacheEndpointIdAlarm();
|
||||
if (IsFeatureUseStableEndpointIdEnabled()) {
|
||||
if (stable_endpoint_id_mode_) {
|
||||
cached_endpoint_id_ = local_endpoint_id_;
|
||||
} else {
|
||||
cached_endpoint_id_.clear();
|
||||
}
|
||||
|
||||
CancelClearCachedEndpointIdAlarm();
|
||||
} else {
|
||||
if (high_vis_mode_) {
|
||||
cached_endpoint_id_ = local_endpoint_id_;
|
||||
NEARBY_LOGS(INFO)
|
||||
<< "ClientProxy [High Visibility Mode Adv, Cache EndpointId]: client="
|
||||
<< GetClientId() << "; cached_endpoint_id_=" << cached_endpoint_id_;
|
||||
CancelClearCachedEndpointIdAlarm();
|
||||
}
|
||||
}
|
||||
|
||||
advertising_info_ = {service_id, listener};
|
||||
@@ -211,7 +260,11 @@ void ClientProxy::StoppedAdvertising() {
|
||||
// advertising_options_ is purposefully not cleared here.
|
||||
OnSessionComplete();
|
||||
|
||||
ExitHighVisibilityMode();
|
||||
if (IsFeatureUseStableEndpointIdEnabled()) {
|
||||
ExitStableEndpointIdMode();
|
||||
} else {
|
||||
ExitHighVisibilityMode();
|
||||
}
|
||||
}
|
||||
|
||||
bool ClientProxy::IsAdvertising() const {
|
||||
@@ -529,6 +582,12 @@ void ClientProxy::OnDisconnected(const std::string& endpoint_id, bool notify) {
|
||||
}
|
||||
|
||||
CancelEndpoint(endpoint_id);
|
||||
|
||||
if (IsFeatureUseStableEndpointIdEnabled()) {
|
||||
if (!stable_endpoint_id_mode_ && !HasOngoingConnection()) {
|
||||
ScheduleClearCachedEndpointIdAlarm();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ClientProxy::ConnectionStatusMatches(const std::string& endpoint_id,
|
||||
@@ -625,6 +684,11 @@ std::vector<std::string> ClientProxy::GetConnectedEndpoints() const {
|
||||
});
|
||||
}
|
||||
|
||||
bool ClientProxy::HasOngoingConnection() const {
|
||||
return !GetPendingConnectedEndpoints().empty() ||
|
||||
!GetConnectedEndpoints().empty();
|
||||
}
|
||||
|
||||
std::int32_t ClientProxy::GetNumOutgoingConnections() const {
|
||||
return GetMatchingEndpoints([](const Connection& connection) {
|
||||
return connection.status == Connection::kConnected &&
|
||||
@@ -1047,27 +1111,50 @@ void ClientProxy::ExitHighVisibilityMode() {
|
||||
<< GetClientId();
|
||||
|
||||
high_vis_mode_ = false;
|
||||
ScheduleClearLocalHighVisModeCacheEndpointIdAlarm();
|
||||
ScheduleClearCachedEndpointIdAlarm();
|
||||
}
|
||||
|
||||
void ClientProxy::ScheduleClearLocalHighVisModeCacheEndpointIdAlarm() {
|
||||
CancelClearLocalHighVisModeCacheEndpointIdAlarm();
|
||||
void ClientProxy::EnterStableEndpointIdMode() {
|
||||
MutexLock lock(&mutex_);
|
||||
NEARBY_LOGS(INFO) << "ClientProxy [EnterStableEndpointIdMode]: client="
|
||||
<< GetClientId();
|
||||
|
||||
if (local_high_vis_mode_cache_endpoint_id_.empty()) {
|
||||
stable_endpoint_id_mode_ = true;
|
||||
}
|
||||
|
||||
void ClientProxy::ExitStableEndpointIdMode() {
|
||||
MutexLock lock(&mutex_);
|
||||
NEARBY_LOGS(INFO) << "ClientProxy [ExitStableEndpointIdMode]: client="
|
||||
<< GetClientId();
|
||||
|
||||
stable_endpoint_id_mode_ = false;
|
||||
ScheduleClearCachedEndpointIdAlarm();
|
||||
}
|
||||
|
||||
void ClientProxy::ScheduleClearCachedEndpointIdAlarm() {
|
||||
CancelClearCachedEndpointIdAlarm();
|
||||
|
||||
if (cached_endpoint_id_.empty()) {
|
||||
NEARBY_LOGS(VERBOSE) << "ClientProxy [There is no cached local high power "
|
||||
"advertising endpoint Id]: client="
|
||||
<< GetClientId();
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsFeatureUseStableEndpointIdEnabled() && HasOngoingConnection()) {
|
||||
NEARBY_LOGS(VERBOSE) << "ClientProxy [Handle clearing cached endpoint ID "
|
||||
"during disconnection]: client="
|
||||
<< GetClientId();
|
||||
return;
|
||||
}
|
||||
|
||||
// Schedule to clear cache high visibility mode advertisement endpoint id in
|
||||
// 30s.
|
||||
NEARBY_LOGS(INFO) << "ClientProxy [High Visibility Mode Adv, Schedule to "
|
||||
"Clear Cache EndpointId]: client="
|
||||
<< GetClientId()
|
||||
<< "; local_high_vis_mode_cache_endpoint_id_="
|
||||
<< local_high_vis_mode_cache_endpoint_id_;
|
||||
clear_local_high_vis_mode_cache_endpoint_id_alarm_ =
|
||||
<< "; cached_endpoint_id_=" << cached_endpoint_id_;
|
||||
cached_endpoint_id_alarm_ =
|
||||
std::make_unique<CancelableAlarm>(
|
||||
"clear_high_power_endpoint_id_cache",
|
||||
[this]() {
|
||||
@@ -1075,19 +1162,18 @@ void ClientProxy::ScheduleClearLocalHighVisModeCacheEndpointIdAlarm() {
|
||||
NEARBY_LOGS(INFO)
|
||||
<< "ClientProxy [Cleared cached local high power advertising "
|
||||
"endpoint Id.]: client="
|
||||
<< GetClientId() << "; local_high_vis_mode_cache_endpoint_id_="
|
||||
<< local_high_vis_mode_cache_endpoint_id_;
|
||||
local_high_vis_mode_cache_endpoint_id_.clear();
|
||||
<< GetClientId()
|
||||
<< "; cached_endpoint_id_=" << cached_endpoint_id_;
|
||||
cached_endpoint_id_.clear();
|
||||
},
|
||||
kHighPowerAdvertisementEndpointIdCacheTimeout,
|
||||
&single_thread_executor_);
|
||||
}
|
||||
|
||||
void ClientProxy::CancelClearLocalHighVisModeCacheEndpointIdAlarm() {
|
||||
if (clear_local_high_vis_mode_cache_endpoint_id_alarm_ &&
|
||||
clear_local_high_vis_mode_cache_endpoint_id_alarm_->IsValid()) {
|
||||
clear_local_high_vis_mode_cache_endpoint_id_alarm_->Cancel();
|
||||
clear_local_high_vis_mode_cache_endpoint_id_alarm_.reset();
|
||||
void ClientProxy::CancelClearCachedEndpointIdAlarm() {
|
||||
if (cached_endpoint_id_alarm_ && cached_endpoint_id_alarm_->IsValid()) {
|
||||
cached_endpoint_id_alarm_->Cancel();
|
||||
cached_endpoint_id_alarm_.reset();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1143,7 +1229,7 @@ bool ClientProxy::IsMultiplexSocketSupported(absl::string_view endpoint_id,
|
||||
}
|
||||
|
||||
int combined_result = GetLocalMultiplexSocketBitmask() &
|
||||
item->first.remote_multiplex_socket_bitmask;
|
||||
item->first.remote_multiplex_socket_bitmask;
|
||||
switch (medium) {
|
||||
case Medium::BLUETOOTH:
|
||||
return (combined_result & kBtMultiplexEnabled) != 0;
|
||||
@@ -1154,7 +1240,6 @@ bool ClientProxy::IsMultiplexSocketSupported(absl::string_view endpoint_id,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::string ClientProxy::ToString(PayloadProgressInfo::Status status) const {
|
||||
switch (status) {
|
||||
case PayloadProgressInfo::Status::kSuccess:
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#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"
|
||||
@@ -31,6 +32,7 @@
|
||||
#include "connections/implementation/proto/offline_wire_formats.pb.h"
|
||||
#include "connections/listeners.h"
|
||||
#include "connections/medium_selector.h"
|
||||
#include "connections/payload.h"
|
||||
#include "connections/status.h"
|
||||
#include "connections/strategy.h"
|
||||
#include "connections/v3/connection_listening_options.h"
|
||||
@@ -49,6 +51,8 @@
|
||||
#include "absl/container/flat_hash_map.h"
|
||||
#include "absl/container/flat_hash_set.h"
|
||||
#include "absl/types/span.h"
|
||||
#include "internal/platform/os_name.h"
|
||||
#include "internal/platform/scheduled_executor.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace connections {
|
||||
@@ -191,6 +195,9 @@ class ClientProxy final {
|
||||
std::vector<std::string> GetConnectedEndpoints() const;
|
||||
// Returns all endpoints that are still awaiting acceptance.
|
||||
std::vector<std::string> GetPendingConnectedEndpoints() const;
|
||||
// Returns true if there is at least one connected connection or one pending
|
||||
// connection.
|
||||
bool HasOngoingConnection() const;
|
||||
// Returns the number of endpoints that are connected and outgoing.
|
||||
std::int32_t GetNumOutgoingConnections() const;
|
||||
// Returns the number of endpoints that are connected and incoming.
|
||||
@@ -260,6 +267,12 @@ class ClientProxy final {
|
||||
// rotates.
|
||||
void ExitHighVisibilityMode();
|
||||
|
||||
// Enters stable endpoint ID mode.
|
||||
void EnterStableEndpointIdMode();
|
||||
// Cleans up any modifications in stable endpoint ID mode. The endpoint id
|
||||
// always rotates.
|
||||
void ExitStableEndpointIdMode();
|
||||
|
||||
std::string Dump();
|
||||
|
||||
const location::nearby::connections::OsInfo& GetLocalOsInfo() const;
|
||||
@@ -282,9 +295,7 @@ class ClientProxy final {
|
||||
return supports_safe_to_disconnect_;
|
||||
}
|
||||
|
||||
bool IsSupportAutoReconnect() const {
|
||||
return support_auto_reconnect_;
|
||||
}
|
||||
bool IsSupportAutoReconnect() const { return support_auto_reconnect_; }
|
||||
|
||||
const std::int32_t& GetLocalSafeToDisconnectVersion() const {
|
||||
return local_safe_to_disconnect_version_;
|
||||
@@ -385,8 +396,8 @@ class ClientProxy final {
|
||||
absl::AnyInvocable<bool(const Connection&)> pred) const;
|
||||
std::string GenerateLocalEndpointId();
|
||||
|
||||
void ScheduleClearLocalHighVisModeCacheEndpointIdAlarm();
|
||||
void CancelClearLocalHighVisModeCacheEndpointIdAlarm();
|
||||
void ScheduleClearCachedEndpointIdAlarm();
|
||||
void CancelClearCachedEndpointIdAlarm();
|
||||
|
||||
location::nearby::connections::OsInfo::OsType OSNameToOsInfoType(
|
||||
api::OSName osName);
|
||||
@@ -402,18 +413,17 @@ class ClientProxy final {
|
||||
// id is stable for 30s. When high_visibility_mode_ is false, the endpoint id
|
||||
// always rotates.
|
||||
bool high_vis_mode_ = false;
|
||||
// Caches the endpoint id when it is in high visibility mode advertisement for
|
||||
// 30s. Currently, Nearby Connections keeps rotating endpoint id. The client
|
||||
// (Nearby Share) treats different endpoints as different receivers, duplicate
|
||||
// share targets for same devices occur on share sheet in this case.
|
||||
// Therefore, we remember the high visibility mode advertisement endpoint id
|
||||
// here. empty if 1) There is no high power advertisement before 2) The
|
||||
// endpoint id cached here in previous high visibility mode advertisement
|
||||
// expires.
|
||||
std::string local_high_vis_mode_cache_endpoint_id_;
|
||||
|
||||
// If advertising is in stable endpoint ID mode, the endpoint ID is stable
|
||||
// for 30s after advertising or disconnection. When stable_endpoint_id_mode_
|
||||
// is false, the endpoint id always rotates.
|
||||
bool stable_endpoint_id_mode_ = false;
|
||||
|
||||
// Caches the endpoint id for stable endpoint ID mode.
|
||||
std::string cached_endpoint_id_;
|
||||
|
||||
ScheduledExecutor single_thread_executor_;
|
||||
std::unique_ptr<CancelableAlarm>
|
||||
clear_local_high_vis_mode_cache_endpoint_id_alarm_;
|
||||
std::unique_ptr<CancelableAlarm> cached_endpoint_id_alarm_;
|
||||
|
||||
// If not empty, we are currently advertising and accepting connection
|
||||
// requests for the given service_id.
|
||||
|
||||
@@ -15,28 +15,45 @@
|
||||
#include "connections/implementation/client_proxy.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "base/casts.h"
|
||||
#include "gmock/gmock.h"
|
||||
#include "protobuf-matchers/protocol-buffer-matchers.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/strings/str_format.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/time/clock.h"
|
||||
#include "absl/time/time.h"
|
||||
#include "absl/types/span.h"
|
||||
#include "connections/advertising_options.h"
|
||||
#include "connections/connection_options.h"
|
||||
#include "connections/discovery_options.h"
|
||||
#include "connections/implementation/flags/nearby_connections_feature_flags.h"
|
||||
#include "connections/listeners.h"
|
||||
#include "connections/medium_selector.h"
|
||||
#include "connections/payload.h"
|
||||
#include "connections/status.h"
|
||||
#include "connections/strategy.h"
|
||||
#include "connections/v3/connection_listening_options.h"
|
||||
#include "connections/v3/connection_result.h"
|
||||
#include "connections/v3/connections_device_provider.h"
|
||||
#include "connections/v3/listeners.h"
|
||||
#include "internal/analytics/mock_event_logger.h"
|
||||
#include "internal/flags/nearby_flags.h"
|
||||
#include "internal/interop/device.h"
|
||||
#include "internal/interop/device_provider.h"
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/platform/cancellation_flag.h"
|
||||
#include "internal/platform/count_down_latch.h"
|
||||
#include "internal/platform/feature_flags.h"
|
||||
#include "internal/platform/medium_environment.h"
|
||||
#include "internal/platform/mutex.h"
|
||||
#include "internal/platform/mutex_lock.h"
|
||||
#include "proto/connections_enums.pb.h"
|
||||
|
||||
namespace nearby {
|
||||
@@ -149,11 +166,30 @@ class ClientProxyTest : public ::testing::TestWithParam<FeatureFlags::Flags> {
|
||||
advertising_options.allowed.bluetooth;
|
||||
}
|
||||
|
||||
bool ShouldEnterStableEndpointIdMode(
|
||||
const AdvertisingOptions& advertising_options) {
|
||||
if (advertising_options.use_stable_endpoint_id) {
|
||||
return true;
|
||||
} else if (advertising_options.low_power) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Endpoint StartAdvertising(
|
||||
ClientProxy* client, ConnectionListener listener,
|
||||
AdvertisingOptions advertising_options = AdvertisingOptions{}) {
|
||||
if (ShouldEnterHighVisibilityMode(advertising_options)) {
|
||||
client->EnterHighVisibilityMode();
|
||||
if (NearbyFlags::GetInstance().GetBoolFlag(
|
||||
connections::config_package_nearby::nearby_connections_feature::
|
||||
kUseStableEndpointId)) {
|
||||
if (ShouldEnterStableEndpointIdMode(advertising_options)) {
|
||||
client->EnterStableEndpointIdMode();
|
||||
}
|
||||
} else {
|
||||
if (ShouldEnterHighVisibilityMode(advertising_options)) {
|
||||
client->EnterHighVisibilityMode();
|
||||
}
|
||||
}
|
||||
Endpoint endpoint{
|
||||
.info = ByteArray{"advertising endpoint name"},
|
||||
@@ -315,6 +351,13 @@ class ClientProxyTest : public ::testing::TestWithParam<FeatureFlags::Flags> {
|
||||
client->OnPayloadProgress(endpoint.id, {});
|
||||
}
|
||||
|
||||
void EnableUseStableEndpointIdFeature() {
|
||||
NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
connections::config_package_nearby::nearby_connections_feature::
|
||||
kUseStableEndpointId,
|
||||
true);
|
||||
}
|
||||
|
||||
MockConnectionListener mock_advertising_connection_;
|
||||
|
||||
MockDiscoveryListener mock_discovery_;
|
||||
@@ -747,6 +790,270 @@ TEST_F(ClientProxyTest,
|
||||
EXPECT_NE(advertising_endpoint_1.id, advertising_endpoint_2.id);
|
||||
}
|
||||
|
||||
TEST_F(ClientProxyTest,
|
||||
RotateWhenLowVizAdvertisementAfterHighVizAndStableAdvertisement) {
|
||||
EnableUseStableEndpointIdFeature();
|
||||
BooleanMediumSelector booleanMediumSelector;
|
||||
booleanMediumSelector.bluetooth = true;
|
||||
|
||||
AdvertisingOptions high_viz_advertising_options{
|
||||
{
|
||||
strategy_,
|
||||
booleanMediumSelector,
|
||||
},
|
||||
false, // auto_upgrade_bandwidth
|
||||
false, // enforce_topology_constraints
|
||||
false, // low_power
|
||||
true, // enable_bluetooth_listening
|
||||
false, // enable_webrtc_listening
|
||||
true, // use_stable_endpoint_id
|
||||
};
|
||||
Endpoint advertising_endpoint_1 =
|
||||
StartAdvertising(&client1_, advertising_connection_listener_,
|
||||
high_viz_advertising_options);
|
||||
|
||||
StopAdvertising(&client1_);
|
||||
|
||||
AdvertisingOptions low_viz_advertising_options{
|
||||
{
|
||||
strategy_,
|
||||
booleanMediumSelector,
|
||||
},
|
||||
false, // auto_upgrade_bandwidth
|
||||
false, // enforce_topology_constraints
|
||||
true, // low_power
|
||||
};
|
||||
|
||||
Endpoint advertising_endpoint_2 = StartAdvertising(
|
||||
&client1_, advertising_connection_listener_, low_viz_advertising_options);
|
||||
|
||||
EXPECT_NE(advertising_endpoint_1.id, advertising_endpoint_2.id);
|
||||
}
|
||||
|
||||
TEST_F(
|
||||
ClientProxyTest,
|
||||
NoRotateWhenLowVizStableAdvertisementAfterHighVizAndStableAdvertisement) {
|
||||
EnableUseStableEndpointIdFeature();
|
||||
BooleanMediumSelector booleanMediumSelector;
|
||||
booleanMediumSelector.bluetooth = true;
|
||||
|
||||
AdvertisingOptions high_viz_advertising_options{
|
||||
{
|
||||
strategy_,
|
||||
booleanMediumSelector,
|
||||
},
|
||||
false, // auto_upgrade_bandwidth
|
||||
false, // enforce_topology_constraints
|
||||
false, // low_power
|
||||
true, // enable_bluetooth_listening
|
||||
false, // enable_webrtc_listening
|
||||
true, // use_stable_endpoint_id
|
||||
};
|
||||
Endpoint advertising_endpoint_1 =
|
||||
StartAdvertising(&client1_, advertising_connection_listener_,
|
||||
high_viz_advertising_options);
|
||||
|
||||
StopAdvertising(&client1_);
|
||||
|
||||
AdvertisingOptions low_viz_advertising_options{
|
||||
{
|
||||
strategy_,
|
||||
booleanMediumSelector,
|
||||
},
|
||||
false, // auto_upgrade_bandwidth
|
||||
false, // enforce_topology_constraints
|
||||
true, // low_power
|
||||
true, // enable_bluetooth_listening
|
||||
false, // enable_webrtc_listening
|
||||
true, // use_stable_endpoint_id
|
||||
};
|
||||
|
||||
Endpoint advertising_endpoint_2 = StartAdvertising(
|
||||
&client1_, advertising_connection_listener_, low_viz_advertising_options);
|
||||
|
||||
EXPECT_EQ(advertising_endpoint_1.id, advertising_endpoint_2.id);
|
||||
}
|
||||
|
||||
TEST_F(
|
||||
ClientProxyTest,
|
||||
NoRotateWhenAdvertisementHasConnectionAfterStableAdvertisementForAWhile) {
|
||||
EnableUseStableEndpointIdFeature();
|
||||
BooleanMediumSelector booleanMediumSelector;
|
||||
booleanMediumSelector.bluetooth = true;
|
||||
|
||||
AdvertisingOptions high_viz_advertising_options{
|
||||
{
|
||||
strategy_,
|
||||
booleanMediumSelector,
|
||||
},
|
||||
false, // auto_upgrade_bandwidth
|
||||
false, // enforce_topology_constraints
|
||||
true, // low_power
|
||||
true, // enable_bluetooth_listening
|
||||
false, // enable_webrtc_listening
|
||||
true, // use_stable_endpoint_id
|
||||
};
|
||||
Endpoint advertising_endpoint_1 =
|
||||
StartAdvertising(&client1_, advertising_connection_listener_,
|
||||
high_viz_advertising_options);
|
||||
|
||||
OnAdvertisingConnectionInitiated(&client1_, advertising_endpoint_1);
|
||||
StopAdvertising(&client1_);
|
||||
|
||||
// Client should use cached endpoint id when having connection.
|
||||
EXPECT_EQ(client1_.GetLocalEndpointId(), advertising_endpoint_1.id);
|
||||
|
||||
// Wait to expire and then advertise.
|
||||
absl::SleepFor(ClientProxy::kHighPowerAdvertisementEndpointIdCacheTimeout +
|
||||
absl::Milliseconds(100));
|
||||
AdvertisingOptions low_viz_advertising_options{
|
||||
{
|
||||
strategy_,
|
||||
booleanMediumSelector,
|
||||
},
|
||||
false, // auto_upgrade_bandwidth
|
||||
false, // enforce_topology_constraints
|
||||
true, // low_power
|
||||
};
|
||||
|
||||
Endpoint advertising_endpoint_2 = StartAdvertising(
|
||||
&client1_, advertising_connection_listener_, low_viz_advertising_options);
|
||||
|
||||
EXPECT_EQ(advertising_endpoint_1.id, advertising_endpoint_2.id);
|
||||
}
|
||||
|
||||
TEST_F(ClientProxyTest, RotateWhenLowVizAdvertisementAfterDisconnection) {
|
||||
EnableUseStableEndpointIdFeature();
|
||||
BooleanMediumSelector booleanMediumSelector;
|
||||
booleanMediumSelector.bluetooth = true;
|
||||
|
||||
AdvertisingOptions high_viz_advertising_options{
|
||||
{
|
||||
strategy_,
|
||||
booleanMediumSelector,
|
||||
},
|
||||
false, // auto_upgrade_bandwidth
|
||||
false, // enforce_topology_constraints
|
||||
false, // low_power
|
||||
true, // enable_bluetooth_listening
|
||||
false, // enable_webrtc_listening
|
||||
true, // use_stable_endpoint_id
|
||||
};
|
||||
Endpoint advertising_endpoint_1 =
|
||||
StartAdvertising(&client1_, advertising_connection_listener_,
|
||||
high_viz_advertising_options);
|
||||
|
||||
OnAdvertisingConnectionInitiated(&client1_, advertising_endpoint_1);
|
||||
StopAdvertising(&client1_);
|
||||
absl::SleepFor(absl::Seconds(2));
|
||||
client1_.OnDisconnected(advertising_endpoint_1.id, true);
|
||||
|
||||
AdvertisingOptions low_viz_advertising_options{
|
||||
{
|
||||
strategy_,
|
||||
booleanMediumSelector,
|
||||
},
|
||||
false, // auto_upgrade_bandwidth
|
||||
false, // enforce_topology_constraints
|
||||
true, // low_power
|
||||
};
|
||||
|
||||
Endpoint advertising_endpoint_2 = StartAdvertising(
|
||||
&client1_, advertising_connection_listener_, low_viz_advertising_options);
|
||||
|
||||
EXPECT_NE(advertising_endpoint_1.id, advertising_endpoint_2.id);
|
||||
}
|
||||
|
||||
TEST_F(ClientProxyTest,
|
||||
NoRotateWhenLowVizAndStableAdvertisementAfterDisconnection) {
|
||||
EnableUseStableEndpointIdFeature();
|
||||
BooleanMediumSelector booleanMediumSelector;
|
||||
booleanMediumSelector.bluetooth = true;
|
||||
|
||||
AdvertisingOptions high_viz_advertising_options{
|
||||
{
|
||||
strategy_,
|
||||
booleanMediumSelector,
|
||||
},
|
||||
false, // auto_upgrade_bandwidth
|
||||
false, // enforce_topology_constraints
|
||||
false, // low_power
|
||||
true, // enable_bluetooth_listening
|
||||
false, // enable_webrtc_listening
|
||||
true, // use_stable_endpoint_id
|
||||
};
|
||||
Endpoint advertising_endpoint_1 =
|
||||
StartAdvertising(&client1_, advertising_connection_listener_,
|
||||
high_viz_advertising_options);
|
||||
|
||||
OnAdvertisingConnectionInitiated(&client1_, advertising_endpoint_1);
|
||||
StopAdvertising(&client1_);
|
||||
absl::SleepFor(absl::Seconds(2));
|
||||
client1_.OnDisconnected(advertising_endpoint_1.id, true);
|
||||
|
||||
AdvertisingOptions low_viz_advertising_options{
|
||||
{
|
||||
strategy_,
|
||||
booleanMediumSelector,
|
||||
},
|
||||
false, // auto_upgrade_bandwidth
|
||||
false, // enforce_topology_constraints
|
||||
true, // low_power
|
||||
true, // enable_bluetooth_listening
|
||||
false, // enable_webrtc_listening
|
||||
true, // use_stable_endpoint_id
|
||||
};
|
||||
|
||||
Endpoint advertising_endpoint_2 = StartAdvertising(
|
||||
&client1_, advertising_connection_listener_, low_viz_advertising_options);
|
||||
|
||||
EXPECT_EQ(advertising_endpoint_1.id, advertising_endpoint_2.id);
|
||||
}
|
||||
|
||||
TEST_F(ClientProxyTest, RotateWhenAdvertisementAfterDisconnectionForAWhile) {
|
||||
EnableUseStableEndpointIdFeature();
|
||||
BooleanMediumSelector booleanMediumSelector;
|
||||
booleanMediumSelector.bluetooth = true;
|
||||
|
||||
AdvertisingOptions high_viz_advertising_options{
|
||||
{
|
||||
strategy_,
|
||||
booleanMediumSelector,
|
||||
},
|
||||
false, // auto_upgrade_bandwidth
|
||||
false, // enforce_topology_constraints
|
||||
false, // low_power
|
||||
true, // enable_bluetooth_listening
|
||||
false, // enable_webrtc_listening
|
||||
true, // use_stable_endpoint_id
|
||||
};
|
||||
Endpoint advertising_endpoint_1 =
|
||||
StartAdvertising(&client1_, advertising_connection_listener_,
|
||||
high_viz_advertising_options);
|
||||
|
||||
OnAdvertisingConnectionInitiated(&client1_, advertising_endpoint_1);
|
||||
StopAdvertising(&client1_);
|
||||
client1_.OnDisconnected(advertising_endpoint_1.id, true);
|
||||
|
||||
// Wait to expire and then advertise.
|
||||
absl::SleepFor(ClientProxy::kHighPowerAdvertisementEndpointIdCacheTimeout +
|
||||
absl::Milliseconds(100));
|
||||
AdvertisingOptions low_viz_advertising_options{
|
||||
{
|
||||
strategy_,
|
||||
booleanMediumSelector,
|
||||
},
|
||||
false, // auto_upgrade_bandwidth
|
||||
false, // enforce_topology_constraints
|
||||
true, // low_power
|
||||
};
|
||||
|
||||
Endpoint advertising_endpoint_2 = StartAdvertising(
|
||||
&client1_, advertising_connection_listener_, low_viz_advertising_options);
|
||||
|
||||
EXPECT_NE(advertising_endpoint_1.id, advertising_endpoint_2.id);
|
||||
}
|
||||
|
||||
// Tests endpoint_id rotates when discover.
|
||||
TEST_F(ClientProxyTest, EndpointIdRotateWhenStartDiscovery) {
|
||||
BooleanMediumSelector booleanMediumSelector;
|
||||
@@ -774,6 +1081,36 @@ TEST_F(ClientProxyTest, EndpointIdRotateWhenStartDiscovery) {
|
||||
EXPECT_NE(advertising_endpoint_1.id, advertising_endpoint_2.id);
|
||||
}
|
||||
|
||||
TEST_F(ClientProxyTest,
|
||||
EndpointIdRotateWhenStartDiscoveryAfterStableAdvertising) {
|
||||
BooleanMediumSelector booleanMediumSelector;
|
||||
booleanMediumSelector.bluetooth = true;
|
||||
|
||||
AdvertisingOptions advertising_options{
|
||||
{
|
||||
strategy_,
|
||||
booleanMediumSelector,
|
||||
},
|
||||
false, // auto_upgrade_bandwidth
|
||||
false, // enforce_topology_constraints
|
||||
false, // low_power
|
||||
true, // enable_bluetooth_listening
|
||||
false, // enable_webrtc_listening
|
||||
true, // use_stable_endpoint_id
|
||||
};
|
||||
|
||||
Endpoint advertising_endpoint_1 = StartAdvertising(
|
||||
&client1_, advertising_connection_listener_, advertising_options);
|
||||
|
||||
StopAdvertising(&client1_);
|
||||
StartDiscovery(&client1_, GetDiscoveryListener());
|
||||
|
||||
Endpoint advertising_endpoint_2 = StartAdvertising(
|
||||
&client1_, advertising_connection_listener_, advertising_options);
|
||||
|
||||
EXPECT_NE(advertising_endpoint_1.id, advertising_endpoint_2.id);
|
||||
}
|
||||
|
||||
// Tests the low visibility mode with bluetooth disabled advertisment.
|
||||
TEST_F(ClientProxyTest,
|
||||
EndpointIdRotateWhenLowVizAdvertisementWithBluetoothDisabled) {
|
||||
@@ -788,6 +1125,9 @@ TEST_F(ClientProxyTest,
|
||||
false, // auto_upgrade_bandwidth
|
||||
false, // enforce_topology_constraints
|
||||
false, // low_power
|
||||
true, // enable_bluetooth_listening
|
||||
false, // enable_webrtc_listening
|
||||
true, // use_stable_endpoint_id
|
||||
};
|
||||
|
||||
Endpoint advertising_endpoint_1 = StartAdvertising(
|
||||
|
||||
Reference in New Issue
Block a user