diff options
Diffstat (limited to 'chromium/third_party/nearby/src/connections/implementation/client_proxy.cc')
-rw-r--r-- | chromium/third_party/nearby/src/connections/implementation/client_proxy.cc | 773 |
1 files changed, 773 insertions, 0 deletions
diff --git a/chromium/third_party/nearby/src/connections/implementation/client_proxy.cc b/chromium/third_party/nearby/src/connections/implementation/client_proxy.cc new file mode 100644 index 00000000000..702504ca396 --- /dev/null +++ b/chromium/third_party/nearby/src/connections/implementation/client_proxy.cc @@ -0,0 +1,773 @@ +// Copyright 2021 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 "connections/implementation/client_proxy.h" + +#include <cstdlib> +#include <functional> +#include <limits> +#include <string> +#include <utility> + +#include "absl/container/flat_hash_map.h" +#include "absl/container/flat_hash_set.h" +#include "absl/strings/escaping.h" +#include "absl/strings/str_cat.h" +#include "internal/platform/error_code_recorder.h" +#include "internal/platform/feature_flags.h" +#include "internal/platform/prng.h" +#include "internal/platform/logging.h" +#include "internal/platform/mutex_lock.h" +#include "proto/connections_enums.pb.h" + +namespace location { +namespace nearby { +namespace connections { + +// 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'}; + +ClientProxy::ClientProxy(analytics::EventLogger* event_logger) + : client_id_(Prng().NextInt64()) { + NEARBY_LOGS(INFO) << "ClientProxy ctor event_logger=" << event_logger; + analytics_recorder_ = + std::make_unique<analytics::AnalyticsRecorder>(event_logger); + error_code_recorder_ = std::make_unique<ErrorCodeRecorder>( + [this](const ErrorCodeParams& params) { + analytics_recorder_->OnErrorCode(params); + }); +} + +ClientProxy::~ClientProxy() { Reset(); } + +std::int64_t ClientProxy::GetClientId() const { return client_id_; } + +std::string ClientProxy::GetLocalEndpointId() { + MutexLock lock(&mutex_); + if (local_endpoint_id_.empty()) { + local_endpoint_id_ = GenerateLocalEndpointId(); + NEARBY_LOGS(INFO) << "ClientProxy [Local Endpoint Generated]: client=" + << GetClientId() + << "; endpoint_id=" << local_endpoint_id_; + } + return local_endpoint_id_; +} + +std::string ClientProxy::GetConnectionToken(const std::string& endpoint_id) { + Connection* item = LookupConnection(endpoint_id); + if (item != nullptr) { + return item->connection_token; + } + return {}; +} + +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_; + } + } + std::string id; + for (int i = 0; i < kEndpointIdLength; i++) { + id += kEndpointIdChars[prng_.NextUint32() % sizeof(kEndpointIdChars)]; + } + return id; +} + +void ClientProxy::Reset() { + MutexLock lock(&mutex_); + + StoppedAdvertising(); + StoppedDiscovery(); + RemoveAllEndpoints(); + ExitHighVisibilityMode(); + analytics_recorder_->LogSession(); +} + +void ClientProxy::StartedAdvertising( + const std::string& service_id, Strategy strategy, + const ConnectionListener& listener, + absl::Span<proto::connections::Medium> mediums, + const AdvertisingOptions& advertising_options) { + MutexLock lock(&mutex_); + 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(); + } + + advertising_info_ = {service_id, listener}; + advertising_options_ = advertising_options; + + const std::vector<proto::connections::Medium> medium_vector(mediums.begin(), + mediums.end()); + analytics_recorder_->OnStartAdvertising(strategy, medium_vector, false, 0); +} + +void ClientProxy::StoppedAdvertising() { + MutexLock lock(&mutex_); + NEARBY_LOGS(INFO) << "ClientProxy [StoppedAdvertising]: client=" + << GetClientId(); + + if (IsAdvertising()) { + advertising_info_.Clear(); + analytics_recorder_->OnStopAdvertising(); + } + // advertising_options_ is purposefully not cleared here. + ResetLocalEndpointIdIfNeeded(); + + ExitHighVisibilityMode(); +} + +bool ClientProxy::IsAdvertising() const { + MutexLock lock(&mutex_); + + return !advertising_info_.IsEmpty(); +} + +std::string ClientProxy::GetAdvertisingServiceId() const { + MutexLock lock(&mutex_); + return advertising_info_.service_id; +} + +std::string ClientProxy::GetServiceId() const { + MutexLock lock(&mutex_); + if (IsAdvertising()) return advertising_info_.service_id; + if (IsDiscovering()) return discovery_info_.service_id; + return "idle_service_id"; +} + +void ClientProxy::StartedDiscovery( + const std::string& service_id, Strategy strategy, + const DiscoveryListener& listener, + absl::Span<proto::connections::Medium> mediums, + const DiscoveryOptions& discovery_options) { + MutexLock lock(&mutex_); + discovery_info_ = DiscoveryInfo{service_id, listener}; + discovery_options_ = discovery_options; + + const std::vector<proto::connections::Medium> medium_vector(mediums.begin(), + mediums.end()); + analytics_recorder_->OnStartDiscovery(strategy, medium_vector, false, 0); +} + +void ClientProxy::StoppedDiscovery() { + MutexLock lock(&mutex_); + + if (IsDiscovering()) { + discovered_endpoint_ids_.clear(); + discovery_info_.Clear(); + analytics_recorder_->OnStopDiscovery(); + } + // discovery_options_ is purposefully not cleared here. + ResetLocalEndpointIdIfNeeded(); +} + +bool ClientProxy::IsDiscoveringServiceId(const std::string& service_id) const { + MutexLock lock(&mutex_); + + return IsDiscovering() && service_id == discovery_info_.service_id; +} + +bool ClientProxy::IsDiscovering() const { + MutexLock lock(&mutex_); + + return !discovery_info_.IsEmpty(); +} + +std::string ClientProxy::GetDiscoveryServiceId() const { + MutexLock lock(&mutex_); + + return discovery_info_.service_id; +} + +void ClientProxy::OnEndpointFound(const std::string& service_id, + const std::string& endpoint_id, + const ByteArray& endpoint_info, + proto::connections::Medium medium) { + MutexLock lock(&mutex_); + + NEARBY_LOGS(INFO) << "ClientProxy [Endpoint Found]: [enter] id=" + << endpoint_id << "; service=" << service_id << "; info=" + << absl::BytesToHexString(endpoint_info.data()); + if (!IsDiscoveringServiceId(service_id)) { + NEARBY_LOGS(INFO) << "ClientProxy [Endpoint Found]: Ignoring event for id=" + << endpoint_id + << " because this client is not discovering."; + return; + } + + if (discovered_endpoint_ids_.count(endpoint_id)) { + NEARBY_LOGS(WARNING) + << "ClientProxy [Endpoint Found]: Ignoring event for id=" << endpoint_id + << " because this client has already reported this endpoint as found."; + return; + } + + discovered_endpoint_ids_.insert(endpoint_id); + discovery_info_.listener.endpoint_found_cb(endpoint_id, endpoint_info, + service_id); + analytics_recorder_->OnEndpointFound(medium); +} + +void ClientProxy::OnEndpointLost(const std::string& service_id, + const std::string& endpoint_id) { + MutexLock lock(&mutex_); + + NEARBY_LOGS(INFO) << "ClientProxy [Endpoint Lost]: [enter] id=" << endpoint_id + << "; service=" << service_id; + if (!IsDiscoveringServiceId(service_id)) { + NEARBY_LOG(INFO, + "ClientProxy [Endpoint Lost]: Ignoring event for id=%s because " + "this client is not discovering", + endpoint_id.c_str()); + return; + } + + const auto it = discovered_endpoint_ids_.find(endpoint_id); + if (it == discovered_endpoint_ids_.end()) { + NEARBY_LOGS(WARNING) + << "ClientProxy [Endpoint Lost]: Ignoring event for id=" << endpoint_id + << " because this client has not yet reported this endpoint as found"; + return; + } + + discovered_endpoint_ids_.erase(it); + discovery_info_.listener.endpoint_lost_cb(endpoint_id); +} + +void ClientProxy::OnConnectionInitiated( + const std::string& endpoint_id, const ConnectionResponseInfo& info, + const ConnectionOptions& connection_options, + const ConnectionListener& listener, const std::string& connection_token) { + MutexLock lock(&mutex_); + + // Whether this is incoming or outgoing, the local and remote endpoints both + // still need to accept this connection, so set its establishment status to + // PENDING. + auto result = connections_.emplace( + endpoint_id, Connection{ + .is_incoming = info.is_incoming_connection, + .connection_listener = listener, + .connection_options = connection_options, + .connection_token = connection_token, + }); + // Instead of using structured binding which is nice, but banned + // (can not use c++17 features, until chromium does) we unpack manually. + auto& pair_iter = result.first; + bool inserted = result.second; + NEARBY_LOGS(INFO) + << "ClientProxy [Connection Initiated]: add Connection: client=" + << GetClientId() << "; endpoint_id=" << endpoint_id + << "; inserted=" << inserted; + DCHECK(inserted); + const Connection& item = pair_iter->second; + // Notify the client. + // + // Note: we allow devices to connect to an advertiser even after it stops + // advertising, so no need to check IsAdvertising() here. + item.connection_listener.initiated_cb(endpoint_id, info); + + if (info.is_incoming_connection) { + // Add CancellationFlag for advertisers once encryption succeeds. + AddCancellationFlag(endpoint_id); + analytics_recorder_->OnConnectionRequestReceived(endpoint_id); + } else { + analytics_recorder_->OnConnectionRequestSent(endpoint_id); + } +} + +void ClientProxy::OnConnectionAccepted(const std::string& endpoint_id) { + MutexLock lock(&mutex_); + + if (!HasPendingConnectionToEndpoint(endpoint_id)) { + NEARBY_LOGS(INFO) << "ClientProxy [Connection Accepted]: no pending " + "connection; endpoint_id=" + << endpoint_id; + return; + } + + // Notify the client. + Connection* item = LookupConnection(endpoint_id); + if (item != nullptr) { + item->connection_listener.accepted_cb(endpoint_id); + item->status = Connection::kConnected; + } +} + +void ClientProxy::OnConnectionRejected(const std::string& endpoint_id, + const Status& status) { + MutexLock lock(&mutex_); + + if (!HasPendingConnectionToEndpoint(endpoint_id)) { + NEARBY_LOGS(INFO) << "ClientProxy [Connection Rejected]: no pending " + "connection; endpoint_id=" + << endpoint_id; + return; + } + + // Notify the client. + const Connection* item = LookupConnection(endpoint_id); + if (item != nullptr) { + item->connection_listener.rejected_cb(endpoint_id, status); + OnDisconnected(endpoint_id, false /* notify */); + } +} + +void ClientProxy::OnBandwidthChanged(const std::string& endpoint_id, + Medium new_medium) { + MutexLock lock(&mutex_); + + const Connection* item = LookupConnection(endpoint_id); + if (item != nullptr) { + item->connection_listener.bandwidth_changed_cb(endpoint_id, new_medium); + NEARBY_LOGS(INFO) << "ClientProxy [reporting onBandwidthChanged]: client=" + << GetClientId() << "; endpoint_id=" << endpoint_id; + } +} + +void ClientProxy::OnDisconnected(const std::string& endpoint_id, bool notify) { + MutexLock lock(&mutex_); + + const Connection* item = LookupConnection(endpoint_id); + if (item != nullptr) { + if (notify) { + item->connection_listener.disconnected_cb({endpoint_id}); + } + connections_.erase(endpoint_id); + ResetLocalEndpointIdIfNeeded(); + } + + CancelEndpoint(endpoint_id); +} + +bool ClientProxy::ConnectionStatusMatches(const std::string& endpoint_id, + Connection::Status status) const { + MutexLock lock(&mutex_); + + const Connection* item = LookupConnection(endpoint_id); + if (item != nullptr) { + return item->status == status; + } + return false; +} + +BooleanMediumSelector ClientProxy::GetUpgradeMediums( + const std::string& endpoint_id) const { + MutexLock lock(&mutex_); + + const Connection* item = LookupConnection(endpoint_id); + if (item != nullptr) { + return item->connection_options.allowed; + } + return {}; +} + +bool ClientProxy::IsConnectedToEndpoint(const std::string& endpoint_id) const { + return ConnectionStatusMatches(endpoint_id, Connection::kConnected); +} + +std::vector<std::string> ClientProxy::GetMatchingEndpoints( + std::function<bool(const Connection&)> pred) const { + MutexLock lock(&mutex_); + + std::vector<std::string> connected_endpoints; + + for (const auto& pair : connections_) { + const auto& endpoint_id = pair.first; + const auto& connection = pair.second; + if (pred(connection)) { + connected_endpoints.push_back(endpoint_id); + } + } + return connected_endpoints; +} + +std::vector<std::string> ClientProxy::GetPendingConnectedEndpoints() const { + return GetMatchingEndpoints([](const Connection& connection) { + return connection.status != Connection::kConnected; + }); +} + +std::vector<std::string> ClientProxy::GetConnectedEndpoints() const { + return GetMatchingEndpoints([](const Connection& connection) { + return connection.status == Connection::kConnected; + }); +} + +std::int32_t ClientProxy::GetNumOutgoingConnections() const { + return GetMatchingEndpoints([](const Connection& connection) { + return connection.status == Connection::kConnected && + !connection.is_incoming; + }) + .size(); +} + +std::int32_t ClientProxy::GetNumIncomingConnections() const { + return GetMatchingEndpoints([](const Connection& connection) { + return connection.status == Connection::kConnected && + connection.is_incoming; + }) + .size(); +} + +bool ClientProxy::HasPendingConnectionToEndpoint( + const std::string& endpoint_id) const { + MutexLock lock(&mutex_); + + const Connection* item = LookupConnection(endpoint_id); + if (item != nullptr) { + return item->status != Connection::kConnected; + } + return false; +} + +bool ClientProxy::HasLocalEndpointResponded( + const std::string& endpoint_id) const { + MutexLock lock(&mutex_); + + return ConnectionStatusesContains( + endpoint_id, + static_cast<Connection::Status>(Connection::kLocalEndpointAccepted | + Connection::kLocalEndpointRejected)); +} + +bool ClientProxy::HasRemoteEndpointResponded( + const std::string& endpoint_id) const { + MutexLock lock(&mutex_); + + return ConnectionStatusesContains( + endpoint_id, + static_cast<Connection::Status>(Connection::kRemoteEndpointAccepted | + Connection::kRemoteEndpointRejected)); +} + +void ClientProxy::LocalEndpointAcceptedConnection( + const std::string& endpoint_id, const PayloadListener& listener) { + MutexLock lock(&mutex_); + + if (HasLocalEndpointResponded(endpoint_id)) { + NEARBY_LOGS(INFO) + << "ClientProxy [Local Accepted]: local endpoint has responded; id=" + << endpoint_id; + return; + } + + AppendConnectionStatus(endpoint_id, Connection::kLocalEndpointAccepted); + Connection* item = LookupConnection(endpoint_id); + if (item != nullptr) { + item->payload_listener = listener; + } + analytics_recorder_->OnLocalEndpointAccepted(endpoint_id); +} + +void ClientProxy::LocalEndpointRejectedConnection( + const std::string& endpoint_id) { + MutexLock lock(&mutex_); + + if (HasLocalEndpointResponded(endpoint_id)) { + NEARBY_LOGS(INFO) + << "ClientProxy [Local Rejected]: local endpoint has responded; id=" + << endpoint_id; + return; + } + + AppendConnectionStatus(endpoint_id, Connection::kLocalEndpointRejected); + analytics_recorder_->OnLocalEndpointRejected(endpoint_id); +} + +void ClientProxy::RemoteEndpointAcceptedConnection( + const std::string& endpoint_id) { + MutexLock lock(&mutex_); + + if (HasRemoteEndpointResponded(endpoint_id)) { + NEARBY_LOGS(INFO) + << "ClientProxy [Remote Accepted]: remote endpoint has responded; id=" + << endpoint_id; + return; + } + + AppendConnectionStatus(endpoint_id, Connection::kRemoteEndpointAccepted); + analytics_recorder_->OnRemoteEndpointAccepted(endpoint_id); +} + +void ClientProxy::RemoteEndpointRejectedConnection( + const std::string& endpoint_id) { + MutexLock lock(&mutex_); + + if (HasRemoteEndpointResponded(endpoint_id)) { + NEARBY_LOGS(INFO) + << "ClientProxy [Remote Rejected]: remote endpoint has responded; id=" + << endpoint_id; + return; + } + + AppendConnectionStatus(endpoint_id, Connection::kRemoteEndpointRejected); + analytics_recorder_->OnRemoteEndpointRejected(endpoint_id); +} + +bool ClientProxy::IsConnectionAccepted(const std::string& endpoint_id) const { + MutexLock lock(&mutex_); + + return ConnectionStatusesContains(endpoint_id, + Connection::kLocalEndpointAccepted) && + ConnectionStatusesContains(endpoint_id, + Connection::kRemoteEndpointAccepted); +} + +bool ClientProxy::IsConnectionRejected(const std::string& endpoint_id) const { + MutexLock lock(&mutex_); + + return ConnectionStatusesContains( + endpoint_id, + static_cast<Connection::Status>(Connection::kLocalEndpointRejected | + Connection::kRemoteEndpointRejected)); +} + +bool ClientProxy::LocalConnectionIsAccepted(std::string endpoint_id) const { + return ConnectionStatusesContains( + endpoint_id, ClientProxy::Connection::kLocalEndpointAccepted); +} + +bool ClientProxy::RemoteConnectionIsAccepted(std::string endpoint_id) const { + return ConnectionStatusesContains( + endpoint_id, ClientProxy::Connection::kRemoteEndpointAccepted); +} + +void ClientProxy::AddCancellationFlag(const std::string& endpoint_id) { + // Don't insert the CancellationFlag to the map if feature flag is disabled. + if (!FeatureFlags::GetInstance().GetFlags().enable_cancellation_flag) { + return; + } + + auto item = cancellation_flags_.find(endpoint_id); + if (item != cancellation_flags_.end()) { + return; + } + cancellation_flags_.emplace(endpoint_id, + std::make_unique<CancellationFlag>()); +} + +CancellationFlag* ClientProxy::GetCancellationFlag( + const std::string& endpoint_id) { + const auto item = cancellation_flags_.find(endpoint_id); + if (item == cancellation_flags_.end()) { + return default_cancellation_flag_.get(); + } + return item->second.get(); +} + +void ClientProxy::CancelEndpoint(const std::string& endpoint_id) { + const auto item = cancellation_flags_.find(endpoint_id); + if (item == cancellation_flags_.end()) return; + item->second->Cancel(); + cancellation_flags_.erase(item); +} + +void ClientProxy::CancelAllEndpoints() { + for (const auto& item : cancellation_flags_) { + CancellationFlag* cancellation_flag = item.second.get(); + if (cancellation_flag->Cancelled()) { + continue; + } + cancellation_flag->Cancel(); + } + cancellation_flags_.clear(); +} + +void ClientProxy::OnPayload(const std::string& endpoint_id, Payload payload) { + MutexLock lock(&mutex_); + + if (IsConnectedToEndpoint(endpoint_id)) { + const Connection* item = LookupConnection(endpoint_id); + if (item != nullptr) { + NEARBY_LOGS(INFO) << "ClientProxy [reporting onPayloadReceived]: client=" + << GetClientId() << "; endpoint_id=" << endpoint_id + << " ; payload_id=" << payload.GetId(); + item->payload_listener.payload_cb(endpoint_id, std::move(payload)); + } + } +} + +const ClientProxy::Connection* ClientProxy::LookupConnection( + const std::string& endpoint_id) const { + auto item = connections_.find(endpoint_id); + return item != connections_.end() ? &item->second : nullptr; +} + +ClientProxy::Connection* ClientProxy::LookupConnection( + const std::string& endpoint_id) { + auto item = connections_.find(endpoint_id); + return item != connections_.end() ? &item->second : nullptr; +} + +void ClientProxy::OnPayloadProgress(const std::string& endpoint_id, + const PayloadProgressInfo& info) { + MutexLock lock(&mutex_); + + if (IsConnectedToEndpoint(endpoint_id)) { + Connection* item = LookupConnection(endpoint_id); + if (item != nullptr) { + item->payload_listener.payload_progress_cb(endpoint_id, info); + + if (info.status == PayloadProgressInfo::Status::kInProgress) { + NEARBY_LOGS(VERBOSE) + << "ClientProxy [reporting onPayloadProgress]: client=" + << GetClientId() << "; endpoint_id=" << endpoint_id + << "; payload_id=" << info.payload_id + << ", payload_status=" << ToString(info.status); + } else { + NEARBY_LOGS(INFO) + << "ClientProxy [reporting onPayloadProgress]: client=" + << GetClientId() << "; endpoint_id=" << endpoint_id + << "; payload_id=" << info.payload_id + << ", payload_status=" << ToString(info.status); + } + } + } +} + +void ClientProxy::RemoveAllEndpoints() { + MutexLock lock(&mutex_); + + // Note: we may want to notify the client of onDisconnected() for each + // endpoint, in the case when this is called from stopAllEndpoints(). For now, + // just remove without notifying. + connections_.clear(); + cancellation_flags_.clear(); + local_endpoint_id_.clear(); +} + +void ClientProxy::ResetLocalEndpointIdIfNeeded() { + MutexLock lock(&mutex_); + if (connections_.empty() && !IsAdvertising() && !IsDiscovering()) { + local_endpoint_id_.clear(); + } +} + +bool ClientProxy::ConnectionStatusesContains( + const std::string& endpoint_id, Connection::Status status_to_match) const { + const Connection* item = LookupConnection(endpoint_id); + if (item != nullptr) { + return (item->status & status_to_match) != 0; + } + return false; +} + +void ClientProxy::AppendConnectionStatus(const std::string& endpoint_id, + Connection::Status status_to_append) { + Connection* item = LookupConnection(endpoint_id); + if (item != nullptr) { + item->status = + static_cast<Connection::Status>(item->status | status_to_append); + } +} + +AdvertisingOptions ClientProxy::GetAdvertisingOptions() const { + return advertising_options_; +} + +DiscoveryOptions ClientProxy::GetDiscoveryOptions() const { + return discovery_options_; +} + +void ClientProxy::EnterHighVisibilityMode() { + MutexLock lock(&mutex_); + NEARBY_LOGS(INFO) << "ClientProxy [EnterHighVisibilityMode]: client=" + << GetClientId(); + + high_vis_mode_ = true; +} + +void ClientProxy::ExitHighVisibilityMode() { + MutexLock lock(&mutex_); + NEARBY_LOGS(INFO) << "ClientProxy [ExitHighVisibilityMode]: client=" + << GetClientId(); + + high_vis_mode_ = false; + ScheduleClearLocalHighVisModeCacheEndpointIdAlarm(); +} + +void ClientProxy::ScheduleClearLocalHighVisModeCacheEndpointIdAlarm() { + CancelClearLocalHighVisModeCacheEndpointIdAlarm(); + + if (local_high_vis_mode_cache_endpoint_id_.empty()) { + NEARBY_LOGS(VERBOSE) << "ClientProxy [There is no cached local high power " + "advertising endpoint Id]: 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_ = + CancelableAlarm( + "clear_high_power_endpoint_id_cache", + [this]() { + MutexLock lock(&mutex_); + 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(); + }, + kHighPowerAdvertisementEndpointIdCacheTimeout, + &single_thread_executor_); +} + +void ClientProxy::CancelClearLocalHighVisModeCacheEndpointIdAlarm() { + if (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_ = CancelableAlarm(); + } +} + +std::string ClientProxy::ToString(PayloadProgressInfo::Status status) const { + switch (status) { + case PayloadProgressInfo::Status::kSuccess: + return std::string("Success"); + case PayloadProgressInfo::Status::kFailure: + return std::string("Failure"); + case PayloadProgressInfo::Status::kInProgress: + return std::string("In Progress"); + case PayloadProgressInfo::Status::kCanceled: + return std::string("Cancelled"); + } +} + +} // namespace connections +} // namespace nearby +} // namespace location |